【问题标题】:Streaming ffmpeg output directly to dispatcher将 ffmpeg 输出直接流式传输到调度程序
【发布时间】:2019-11-06 10:36:37
【问题描述】:

我正在尝试使用我的 discord 机器人播放音乐,我想使用 ffmpeg 指定音乐的开头,效果很好,但我只能使用 ffmpeg 下载音乐然后播放。我希望 ffmpeg 对其进行处理,然后将其流式传输以播放音乐。

这是我用来下载然后播放音乐的代码:

message.member.voiceChannel.join().then((con, err) => {
    ytPlay.search_video(op, (id) => {
        let stream = ytdl("https://www.youtube.com/watch?v=" + id, {
            filter: "audioonly"
        });
        let audio = fs.createWriteStream('opStream.divx');

        proc = new ffmpeg({
            source: stream
        })
        proc.withAudioCodec('libmp3lame')
            .toFormat('mp3')
            .seekInput(35)
            .output(audio)
            .run();
        proc.on('end', function() {
            let input = fs.createReadStream('opStream.divx');
            console.log('finished');
            guild.queue.push(id);
            guild.isPlaying = true;
            guild.dispatcher = con.playStream(input);
        });
    });
})

是否可以做我想做的事,如果可以,怎么做?

【问题讨论】:

    标签: javascript node.js ffmpeg discord.js fluent-ffmpeg


    【解决方案1】:

    您可以使用 discord.js 的 seek StreamOptions 来代替使用 ffmpeg 指定音乐的起点,例如:

    const dispatcher = connection.play(ytdl(YOUR_URL, { filter: 'audioonly' }) , {seek:35})

    这对我来说效果很好

    【讨论】:

      【解决方案2】:

      是的,这是可能的,我在我的机器人中做到了。 首先你需要安装 ytdl-core

      然后创建一个 play.js 文件,流函数将在其中。 此代码将:获取 youtube url 并在不下载歌曲的情况下进行流式传输,将歌曲添加到队列中,让机器人在歌曲完成后离开

      根据需要编辑代码。

      exports.run = async (client, message, args, ops) => {
          if (!message.member.voiceChannel) return message.channel.send('You are not connected to a voice channel!');
      
      
          if (!args[0]) return message.channel.send('Insert a URL!');
          let validate = await ytdl.validateURL(args[0]);
      
          let info = await  ytdl.getInfo(args[0]);
      
         let data = ops.active.get(message.guild.id) || {};
          if (!data.connection) data.connection = await message.member.voiceChannel.join();
          if(!data.queue) data.queue = [];
          data.guildID = message.guild.id;
      
          data.queue.push({
              songTitle: info.title,
              requester: message.author.tag,
              url: args[0],
              announceChannel: message.channel.id
      
          });
      
          if (!data.dispatcher) play(client, ops, data);
          else {
              message.channel.send(`Added to queue: ${info.title} | requested by: ${message.author.tag}`)
          }
          ops.active.set(message.guild.id, data);
      
      
      }
      async function play(client, ops, data) {
          client.channels.get(data.queue[0].announceChannel).send(`Now Playing: ${data.queue[0].songTitle} | Requested by: ${data.queue[0].requester}`);
          client.user.setActivity(`${data.queue[0].songTitle}`, {type: "LISTENING"});
      
          data.dispatcher = await data.connection.playStream(ytdl(data.queue[0].url, {filter: 'audioonly'}));
          data.dispatcher.guildID = data.guildID;
      
          data.dispatcher.once('end', function() {
              end(client, ops, this);
      
          });
      
      }
      function end(client, ops, dispatcher){
      
          let fetched = ops.active.get(dispatcher.guildID);
      
          fetched.queue.shift();
      
          if (fetched.queue.length > 0) {
              ops.active.set(dispatcher.guildID, fetched);
              play(client, ops, fetched);
          } else {
              ops.active.delete(dispatcher.guildID);
      
              let vc = client.guilds.get(dispatcher.guildID).me.voiceChannel;
      
              if (vc) vc.leave();
      
      
          }
        }
        module.exports.help = {
          name:"play"
        }``` 
      

      【讨论】:

      • 这不是我想要的。我想流式传输 ffmpeg 输出。如果您准确地阅读了我的代码,您会注意到我已经使用了 ytdl。 @心理
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-16
      • 2014-07-13
      • 2018-08-06
      • 2012-03-30
      • 2016-11-01
      • 2019-03-25
      • 2017-04-29
      相关资源
      最近更新 更多