【Node.js】discord.jsでplay-dlを使って音楽を流したい!(有識者さん助けて…)
はじめに
もともとytdl-coreを使って音楽Botなるものを作成してみたりしてあそんでいました。しかしytdl-coreでうまく動かなくなり(Youtubeの仕様変更等?)play-dlのほうがいいよ?というchatGPTさまの甘言にそそのかされ、ライブラリを変更してやってみました。しかし、どう頑張ってもエラーは出ないのに、音楽が再生されない。
player.state.statusを確認してみるとずっとbufferingの状態で再生できていないことが分かった。bufferingになっている要因として色々調べた結果createAudioResourceで取得したresourceの中身が_readableState.buffer.length が 0 で、flowing も false。Encoder の _buffer に<Buffer >という空のバッファがある。などいろいろ原因があるっぽいが修正方法がわからず。なんなら調べてるとplay-dlはしんだとかいう話もみた
疲れたので一旦一休みします。わかる有識者の方いたらぜひご教授ください…
コード
const Discord = require("discord.js");
const { EmbedBuilder } = require('discord.js');
const config = require("../config.js");
const functions = require("../functions.js");
const request = require("request");
const play = require("play-dl");
const { entersState, AudioPlayerStatus, NoSubscriberBehavior, getVoiceConnection,createAudioPlayer, createAudioResource, joinVoiceChannel, StreamType } = require('@discordjs/voice');
const { setTimeout } = require('node:timers/promises');
play.setToken({
youtube: {
cookie: "{クッキーを入れる}"
}
});
const queue = [];
let connection;
let player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play
}
});
module.exports = {
name: "messageCreate",
async execute(message, client) {
if (!message.guild) return;
const channel = message.member.voice.channel;
if (message.content.match(/vc/)) {
if (message.author.bot) return;
connection = joinVoiceChannel({
channelId: channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
});
connection.subscribe(player);
connection.on("stateChange", (oldState, newState) => {
console.log(`🔄 Connection state changed: ${oldState.status} -> ${newState.status}`);
});
return message.reply(`接続しました`)
}
if (message.content.match(/https:/)) {
const url = message.content;
if (!await play.validate(url)) {
return message.reply("このURLは処理できません。");
}
queue.push(url);
console.log(queue);
if (!connection) {
const channel = message.member.voice.channel;
if (!channel) return message.reply("ボイスチャンネルに参加してください!");
const connection = getVoiceConnection(message.channel.guild.id);
connection.subscribe(player);
connection.on("stateChange", (oldState, newState) => {
console.log(`🔄 Connection state changed: ${oldState.status} -> ${newState.status}`);
});
}
if (queue.length === 1) {
playNext(message);
}
}
if (message.content.match(/bye/)) {
if (message.author.bot) return;
// queue = [];
const connection = getVoiceConnection(message.channel.guild.id);
connection.destroy();
return message.reply(`切断しました`)
}
}
}
async function playNext(message) {
if (queue.length === 0) return;
try {
console.log("再生開始: ", queue[0]);
if (!await play.validate(queue[0])) {
return message.reply("このURLは処理できません。");
}
let stream = await play.stream(queue[0], {discordPlayerCompatibility:true});
// let stream = await play.stream(queue[0]);
// console.log("🎥 Stream情報:", stream);
// console.log("Stream type:", stream.type);
// let video_info = await play.video_basic_info(queue[0]);
// console.log("🎥 Video情報:", video_info);
const resource = createAudioResource(stream.stream, {
// inputType: stream.type
// inputType: stream.type === StreamType.OggOpus ? StreamType.OggOpus : StreamType.Arbitrary
// inputType: StreamType.Opus
inputType: StreamType.Arbitrary,
// inputType: StreamType.OggOpus
// inputType: StreamType.WebmOpus,
inlineVolume: true
});
// console.log("🎼 AudioResource を作成しました:", resource);
console.log("🔍 stream.flowing:", stream.stream.readableFlowing);
// stream.stream.resume();
// console.log("🎵 ストリームを手動で再開しました!");
stream.stream.once("data", (chunk) => {
console.log("🎶 ストリームデータを受信:", chunk);
});
resource.playStream.on("readable", () => {
console.log("🎶 ストリームが読み込まれました!");
});
player.play(resource);
console.log("🎼 AudioResource を作成しました:", resource);
console.log("▶️ player.play(resource) を実行しました。");
console.log("📢 player 状態:", player.state.status);
await setTimeout(10000);
console.log("📢 player 状態:", player.state.status);
player.on(AudioPlayerStatus.Playing, () => {
console.log("▶️ 再生開始!");
});
player.on(AudioPlayerStatus.Buffering, () => {
console.log("⏳ バッファリング中...");
});
player.on(AudioPlayerStatus.Idle, () => {
console.log("⏹️ 再生終了、次の曲を再生");
queue.shift();
playNext(message);
});
player.on("error", (error) => {
console.error("❌ 再生エラー:", error);
});
await new Promise((resolve) => {
player.once(AudioPlayerStatus.Idle, resolve);
});
} catch (error) {
console.error("エラー: ", error);
message.channel.send("エラーが発生しました。次の曲にスキップします。");
queue.shift();
playNext(message);
}
}
buffering状態でさらに放置すると以下のエラーが出ることにも気づいた
[2025/2/22 14:34:50] Error: While getting info from url
Video unavailable



ディスカッション
コメント一覧
まだ、コメントがありません