0

I'm trying to play music with my discord bot and I want to use ffmpeg to specify the start of the music, which works perfectly fine, but I can only download the music with ffmpeg and then play it. I want ffmpeg to process it and then also stream it to play the music.

Here is the code I use to download and then play the music:

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

Is it possible to do what I want and if yes how?

2 Answers2

1

Instead of using ffmpeg to specify your starting point of the music you could use the seek StreamOptions of discord.js like:

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

This worked pretty fine for me

fedann
  • 51
  • 3
0

Yes is is possible, i made it in my bot. First of all you need to install ytdl-core

Then create a play.js file where the stream function will be in. This code will: take the youtube url and stream it without downloading the song, add the song to a queue, make the bot leave when the song is finished

Edit the code for what you need.

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"
  }``` 
  • This is not what I want. I want to stream the ffmpeg output. If you would have read my code precisely you would have noticed that I already use ytdl. @Mental – PP_Hyperion Jun 25 '19 at 19:41