discord.jsbotsytdl

How can I stream music using YTDL and discordjs/voice package. DiscordJS


I'm using the latest version of discord where they removed the built-in library for voice API. I figured out how can I join to channel but I've tried a lot of attempts to play music on that channel.

I would like to use yt-dl for downloading the file and discordjs/voice for connecting and playing.

Thanks for anyone helping me.


Solution

  • Discord.js V13 and @discordjs/voice

    Since a relatively recent update to the Discord.js library a lot of things have changed in the way you play audio files or streams over your client in a Discord voice channel. There is a really useful guide by Discord to explain a lot of things to you on a base level right here, but I'm going to compress it down a bit and explain to you how you can get it to work.

    Some prerequisites

    It is important to note that for anything to do with voice channels for your bot it is necessary to have the GUILD_VOICE_STATES intent in your client. Without it your bot will not actually be able to connect to a voice channel even though it seems like it is. If you don't know what intents are yet, here is the relevant page from the same guide.

    Additionally you will need some extra libraries that will help you with processing and streaming audio files. These things will do a lot of stuff in the background that you do not need to worry about them, but without them playing any audio will not work. To find out what you need you can use the generateDependecyReport() function from @discordjs/voice. Here is the page explaining how to use it and what dependencies you will need. To use the function you will have to import it from the @discordjs/voice library.

    Playing audio over a client

    So once everything is set up you can get to how to play audio and music. This is a few step process starting with getting a stream from the ytdl-core package. Once you have this stream you need to make an AudioPlayer and give it an AudioResource which is constructed with the stream you got. This may seem a little complicated, but let's break it down.

    ytdl-core

    Getting a stream from this package is actually fairly easy, all you need is a url of the youtube video you want to stream and use it in the following way:

    const stream = ytdl(url, { filter: 'audioonly' })
    

    This makes a readable stream from youtube and the filter makes is so that you don't waste resources on getting the video because you only need the audio.

    AudioPlayer

    The AudioPlayer is essentially your jukebox. You can make one by simply calling its function and storing that in a const like so:

    const player = createAudioPlayer()
    

    This is a function from the @discordjs/voice library and will have to be imported just like generateDependencyReport(). There are a few parameters you can give it to modify its behavior, but right now that is not important. You can read more about that on its page from the Discord guide right here.

    AudioResource

    To get your AudioPlayer to actually play anything you will have to create an AudioResource. This is basically a version of your file or stream modified to work with the player. This is very simply done with another function from the @discord.js/voice library called createAudioResource(...). This must once again be imported. As a parameter you can parse the location of an mp3 or webm file, but you can also use a stream object like you have already acquired. Just input stream as the parameter of that function.

    To now play the resource there are two more steps. First you must subscribe your connection to the player. This basically tells the connection to broadcast whatever your AudioPlayer is playing. To do this simply call the .subscribe() function on your connection object, which you can get from the joinVoiceChannel() function you used to join a channel, with the player as a parameter like so:

    const connection = joinVoiceChannel({
        channelId: channel.id,
        guildId: channel.guild.id,
        adapterCreator: channel.guild.voiceAdapterCreator,
    })
    connection.subscribe(player)
    
    player.play(resource)
    

    The second line of code you see above is how you get your player to play your AudioResource. Just parse the resource as a parameter and it will start playing. You can find more on the AudioResource side of things on its page in the Discord guide right here.

    This way takes a few more steps than it did in V12, but once you get the hang of this system it really isn't that bad or difficult.