Search code examples
python-3.xdiscorddiscord.pyyoutube-dl

Discord Music bot VoiceClient' object has no attribute 'create_ytdl_player'


I wanted to programm my own discord bot, which plays some songs from youtube but it wont create the ydl player this is the error Command raised an exception: AttributeError: 'VoiceClient' object has no attribute 'create_ytdl_player' and this is my code. Thanks in advance.

@client.command(pass_context=True)
async def s(ctx):
    user=ctx.message.author
    voicech = ctx.author.voice.channel
    voice = await  voicech.connect()
    player = await voice.create_ytdl_player("some url")

    
    
    player = await vc.create_ytdl_player()
    player.start()

Solution

  • create_ytdl_player was the old way of creating a player. With discord.py@rewrite (> v.1.0), playing music is a bit more complicated. There are two ways to play music. For both ways, using FFmpeg will be necessary, so you'll have to install it.

    Here are two of ways to play videos (with youtube-dl and ffmpeg):

    • From file (you'll have to download files):
    from discord.ext import commands
    from discord.utils import get
    from discord import FFmpegPCMAudio
    from youtube_dl import YoutubeDL
    
    @bot.command(brief="Plays a single video, from a youtube URL") #or bot.command()
    async def play(ctx, url):
        voice = get(client.voice_clients, guild=ctx.guild)
        YDL_OPTIONS = {
            'format': 'bestaudio',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
            'outtmpl': 'song.%(ext)s',
        }
    
        with YoutubeDL(Music.YDL_OPTIONS) as ydl:
            ydl.download("URL", download=True)
    
        if not voice.is_playing():
            voice.play(FFmpegPCMAudio("song.mp3"))
            voice.is_playing()
            await ctx.send(f"Now playing {url}")
        else:
            await ctx.send("Already playing song")
            return
    
    • Without downloading music. This is simpler to play music this way, however, this causes a know issue, well explained here so you'll have to add a FFMPEG_OPTIONS variable:
    from discord.ext import commands
    from discord.utils import get
    from discord import FFmpegPCMAudio
    from youtube_dl import YoutubeDL
    
    @bot.command(brief="Plays a single video, from a youtube URL")
    async def play(ctx, url):
        YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
        FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
        voice = get(client.voice_clients, guild=ctx.guild)
    
        if not voice.is_playing():
            with YoutubeDL(ydl_opts) as ydl:
                info = ydl.extract_info(video_link, download=False)
            URL = info['formats'][0]['url']
            voice.play(FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))
            voice.is_playing()
        else:
            await ctx.send("Already playing song")
            return
    

    These commands will only play songs so you'll have to program every other commands (join, leave, ...).
    There are a lot of example on internet, you should look at them once you're used to creating music bots.

    Reference: VoiceClient documentation.