使用discord.js和ytdl-core播放音频文件

时间:2017-10-31 23:08:55

标签: javascript node.js discord.js

我尝试使用ytdl和discord.js下载并播放从youtube获取的音频文件:

        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

我成功设法在没有ytdl部分(ytdl(url).pipe(fs.createWriteStream('./music/downloads/music.mp3'));)的./music/downloads/中播放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

为什么会这样,我该如何解决?

2 个答案:

答案 0 :(得分:2)

当您需要播放音频流时,请使用playStream代替playFile。

viewBTopConstraints?.isActive = false
newViewBTopConstraints?.isActive = true

答案 1 :(得分:0)

  

您正在以低效的方式进行操作。读写之间没有同步。   
  或者,等待文件写入文件系统,然后再阅读!

直接流式传输

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);

FWTR(先写,然后读)

您使用的方法非常接近成功!
但是失败是当您不同步读/写时。

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);
});