音声
ボイスチャンネルに接続して音声を再生したり、録音したりする。
音楽 bot や読み上げ bot の核。@discordjs/voice パッケージを使う。
導入
npm install @discordjs/voice
npm install ffmpeg-static # 音声変換
npm install libsodium-wrappers # 暗号化(Discord 必須)
# 音楽再生に必要なライブラリ(どちらか)
npm install @discordjs/opus # ネイティブ実装(速い、コンパイル必要)
# または
npm install opusscript # ピュア JS(遅いがビルド不要)
暗号化ライブラリ
Discord の音声は暗号化必須。libsodium-wrappers または tweetnacl または sodium-native のどれかが必要。
VC に接続
import { joinVoiceChannel, VoiceConnectionStatus } from "@discordjs/voice"
if (interaction.isChatInputCommand() && interaction.commandName === "join") {
const member = interaction.member as GuildMember
const channel = member.voice.channel
if (!channel) {
return interaction.reply({ content: "VC に入ってからやって", ephemeral: true })
}
const connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false,
})
connection.on(VoiceConnectionStatus.Ready, () => {
console.log("接続完了")
})
await interaction.reply("接続しました")
}
Intents
GatewayIntentBits.GuildVoiceStates が必須。
音声を再生する
import {
createAudioPlayer, createAudioResource, AudioPlayerStatus,
} from "@discordjs/voice"
const player = createAudioPlayer()
connection.subscribe(player)
const resource = createAudioResource("./music.mp3") // ファイルパス or URL or Stream
player.play(resource)
player.on(AudioPlayerStatus.Idle, () => {
console.log("再生終了")
})
player.on("error", (err) => console.error(err))
AudioResource の入力
- ローカルファイル(mp3, wav, ogg, m4a 等。FFmpeg 経由)
- HTTP URL(直接 mp3 など)
- Node.js Stream
- YouTube は別ライブラリ(後述)
音量調整
const resource = createAudioResource("./music.mp3", {
inlineVolume: true, // 必須
})
resource.volume?.setVolume(0.5) // 0.0 - 1.0+
YouTube から再生(音楽 bot)
play-dl または distube/ytdl-core を使う。Discord の規約と YouTube の規約両方に注意。
npm install play-dl
import play from "play-dl"
const stream = await play.stream("https://www.youtube.com/watch?v=...")
const resource = createAudioResource(stream.stream, { inputType: stream.type })
player.play(resource)
- YouTube の規約上グレー。商用や大規模配布は避ける
- YouTube が API を頻繁に変えるので、ライブラリの更新が早い方を選ぶ
- 著作権を守る運用にする
キュー(音楽 bot の心臓部)
interface Track { title: string; url: string }
const queues = new Map<string, Track[]>()
function getQueue(guildId: string) {
if (!queues.has(guildId)) queues.set(guildId, [])
return queues.get(guildId)!
}
async function playNext(guildId: string, player: AudioPlayer) {
const q = getQueue(guildId)
const track = q.shift()
if (!track) return
const stream = await play.stream(track.url)
player.play(createAudioResource(stream.stream, { inputType: stream.type }))
}
player.on(AudioPlayerStatus.Idle, () => {
playNext(guildId, player)
})
切断
connection.destroy()
メンバーが全員 VC から抜けたら自動切断するパターン:
client.on(Events.VoiceStateUpdate, (oldState, newState) => {
const channel = oldState.channel
if (!channel) return
// bot 以外がいなくなったら
const human = channel.members.filter((m) => !m.user.bot)
if (human.size === 0) {
const conn = getVoiceConnection(channel.guild.id)
conn?.destroy()
}
})
録音(受信)
VC のユーザー音声を受信することもできる。文字起こし bot 等に。
import { EndBehaviorType } from "@discordjs/voice"
import * as fs from "node:fs"
import { pipeline } from "node:stream"
const receiver = connection.receiver
receiver.speaking.on("start", (userId) => {
const audio = receiver.subscribe(userId, {
end: { behavior: EndBehaviorType.AfterSilence, duration: 1000 },
})
// Opus → PCM → WAV など、外部ツールで変換
const out = fs.createWriteStream(`./rec-${userId}-${Date.now()}.opus`)
pipeline(audio, out, (err) => {
if (err) console.error(err)
})
})
Opus フォーマットで届くので、PCM や WAV にしたい場合は ffmpeg や prism-media で変換。
テキスト読み上げ(TTS)
google-tts-api や OpenAI TTS、say.js 等で生成した音声を createAudioResource で流す。
import googleTTS from "google-tts-api"
const url = googleTTS.getAudioUrl("こんにちは", { lang: "ja", slow: false })
const resource = createAudioResource(url)
player.play(resource)
レイテンシと品質
- Discord はOpus 48kHzを要求
- 音楽はFFmpeg で 48kHz にリサンプルされる(自動)
- サーバーの音声リージョンを bot/ユーザーから近くにすると品質改善
- Discord の VC はUDP 通信。ホスティング先のファイアウォール注意
注意点
- 本番デプロイはFFmpeg と暗号化ライブラリがインストールされている環境が必要
- Heroku free tier や一部サーバレス(Vercel/CF Workers)ではWebSocket/UDP が動かないのでフルタイム VPS が必要
- 大量の bot 同時接続には音声リソース上限がある
- 音声録音はプライバシーへの配慮必須。ユーザーに通知する
音楽 bot を作るなら discord-player や distube が高機能ラッパとして使える。 キュー管理・フィルタ・複数ソース対応が組み込み。