Я пытаюсь загрузить и воспроизвести аудиофайл, извлеченный из youtube с помощью ytdl и discord.js:
ytdl(url)
.pipe(fs.createWriteStream('./music/downloads/music.mp3'));
var voiceChannel = message.member.voiceChannel;
voiceChannel.join().then(connection => {
console.log("joined channel");
const dispatcher = connection.playFile('./music/downloads/music.mp3');
dispatcher.on("end", end => {
console.log("left channel");
voiceChannel.leave();
});
}).catch(err => console.log(err));
isReady = true
Я успешно умею играть в mp3 файл в./music/downloads/без части ytdl (ytdl(url).pipe(fs.createWriteStream('./music/downloads/music.mp3'));
). Но когда эта часть находится в коде, бот просто присоединяется и уходит.
Вот результат с частью ytdl:
Bot has started, with 107 users, in 43 channels of 3 guilds.
joined channel
left channel
И вот результат без части ytdl:
Bot has started, with 107 users, in 43 channels of 3 guilds.
joined channel
[plays mp3 file]
left channel
Почему это и как я могу это решить?
Используйте playStream вместо playFile, когда вам нужно воспроизвести аудиопоток.
const streamOptions = { seek: 0, volume: 1 };
var voiceChannel = message.member.voiceChannel;
voiceChannel.join().then(connection => {
console.log("joined channel");
const stream = ytdl('https://www.youtube.com/watch?v=gOMhN-hfMtY', { filter : 'audioonly' });
const dispatcher = connection.playStream(stream, streamOptions);
dispatcher.on("end", end => {
console.log("left channel");
voiceChannel.leave();
});
}).catch(err => console.log(err));
Вы делаете это неэффективным способом. Там нет синхронизации между письмом и чтением.
Или подождите, пока файл будет записан в файловой системе, а затем прочитайте его!
Перенаправьте видеовыход YTDL на диспетчер, который сначала будет преобразован в пакеты аудиоданных opus
затем передан с вашего компьютера на Discord.
message.member.voiceChannel.join()
.then(connection => {
console.log('joined channel');
connection.playStream(YTDL(url))
// When no packets left to sent leave the channel.
.on('end', () => {
console.log('left channel');
connection.channel.leave();
})
// Handle error without crashing the app.
.catch(console.error);
})
.catch(console.error);
Подход, который вы использовали, довольно близок к успеху!
Но ошибка в том, что вы не синхронизируете чтение/запись.
var stream = YTDL(url);
// Wait until writing is finished
stream.pipe(fs.createWriteStream('tmp_buf_audio.mp3'))
.on('end', () => {
message.member.voiceChannel.join()
.then(connection => {
console.log('joined channel');
connection.playStream(fs.createReadStream('tmp_buf_audio.mp3'))
// When no packets left to sent leave the channel.
.on('end', () => {
console.log('left channel');
connection.channel.leave();
})
// Handle error without crashing the app.
.catch(console.error);
})
.catch(console.error);
});