Discord.NET を利用した Voice Channel に対する音声データ再生
友人に「Bot で Voice Channel に音楽流せない?」と相談を受けました。Discord Bot で音声を扱う実装はしたことがなく、気になったのでパパッと調べてみました。覚書ということで丁寧な解説などはありません。
事前準備
Discord.Audio を利用するためには ibsodium.dll と opus.dll を実行時フォルダ (= パスが通ったところ) に置いておく必要があります。これは Discord.NET のドキュメントにも明記されています。
Audio requires two native libraries, libsodium and opus. Both of these libraries must be placed in the runtime directory of your bot. (When developing on .NET Framework, this would be bin/debug, when developing on .NET Core, this is where you execute dotnet run from; typically the same directory as your csproj).
特にドキュメントも読まずに実装して、いざ実行しようとしたら「opus.dll がない」と怒られ続けてしばらく悩みました。ドキュメントはちゃんと読みましょう。
実装
Step.1 : Voice Channel への接続
Discord API への接続処理などは割愛し、Voice Channel に参加して音声データを流す部分だけをピックアップします。
// 接続済みのクライアントがあるとする
DiscordSocketClient socketClient;
// 指定した Voice Channel に接続
var guild = socketClient.GetGuild(id: ..); // サーバー ID
var channel = guild.GetVoiceChannel(id: ..); // チャンネル ID
var audioClient = await channel.ConnectAsync();
// 音声データを再生
using (var audioStream = audioClient.CreatePCMStream(AudioApplication.Mixed))
{
// audioStream に対して PCM 形式のバイト列を流し込めば音声が流れる
}
AudioApplication の意味
どうやら音声の品質を指定するためにあるようです。用途に合わせて調整しましょう。
AudioApplication の値 |
音質 | 帯域幅 | 遅延 | 主な用途 |
|---|---|---|---|---|
Voice |
声に最適 | 狭い | 少ない | 通話 / 読み上げ |
Mixed |
標準 | 標準 | 標準 | 効果音 / 通知音 |
Music |
高音質 | 広い | 多い | BGM 再生 |
Step.2 : .mp3 を再生
音声データを扱うライブラリは何でもよいと思いますが、今回は NAudio を利用してみます。手元にある .mp3 形式のファイルを流し込むだけであれば以下のような感じでたった数行で実装が終わります。お手軽。
using (var audioStream = audioClient.CreatePCMStream(AudioApplication.Mixed))
{
// NAudio を利用して .mp3 ファイルを PCM 形式の Stream に変換
const string path = @"<Path to Audio>.mp3";
using (var reader = new Mp3FileReader(path))
{
// Discord.NET 内部で OpusEncoder が 48,000 Hz を要求しているので合わせること
var format = new WaveFormat(sampleRate: 48000, channels: 2);
using (var pcmStream = new WaveFormatConversionStream(format, reader))
{
// 音声データを Discord に流し込む
await pcmStream.CopyToAsync(audioStream);
}
}
}
注意事項
ただし、正直なところ NAudio は以下を理由に積極的な利用はしない方がよいのではないかという気はしています。
- Windows でしか動作しない
- .NET 6 (= サポート期限切れ) までしかサポートしていない
上記は本記事執筆時点での話で、今後のアップデートで改善されるかもしれません。今回はとりあえず技術検証をしたいだけなので許容しています。
Discussion