mp4やmp3をインターネット上から取得して、その音声をDiscord.jsでBotに流し込むためにちょっと躓いたことがあったのでメモ書き
両方とも、Streamであることは変わりないのだけど、簡単に言えば古いのと新しいのという関係性らしい
internal.Readable
新しい形式のStream。Discord.jsではこちらが使われている。大体新しいライブラリはこっちのStreamを吐くことが多いみたい。
NodeJS.ReadableStream
古い形式のStream。node-fetchのbodyとかは(なぜか)こっちの形式でデータを返してくる。
互換性
互換性はない。ただし、古い形式であるNodeJS.ReadableStream
を新しいinternal.Readable
に変換(ラップ)することは可能(この記述を公式ドキュメント内で見つけるのにかなり時間がかかった...)
変換(ラップ)の例
Discord.jsで作るBotに搭載する実例をもとにサンプルコードを載せておく
example.ts
import { Client, Message, VoiceChannel } from 'discord.js';
import fetch from 'node-fetch';
import { Readable } from 'stream';
const client = new Client();
client.on('message', async (message: Message) => {
if (message.author.bot) return;
const voiceChannel = message.member?.voice.channel;
if (message.content === 'play' && voiceChannel) {
musicPlayAndStreamConvert(voiceChannel)
}
});
async function musicPlayAndStreamConvert(voiceChannel: VoiceChannnel) {
const res = await fetch('<mp3 file url>');
const readableStream = new Readable().wrap(res.body);
const connection = await voiceChannnel.join();
const dispatcher = connection.play(readableStream);
this.dispatcher.on('finish', () => {
connection.disconnect();
})
}
void client.login('<bot token>');
おわりに
私自身も理解が浅いので、間違ってる部分があれば突っ込んでもらえると。
あとは、私と同じ問題に躓いて諦めない人が増えますように(少し遅い七夕)。