Porting code from youtube-dl to yt-dlp library for Python Discord Bot

Question:

This is my first question here therefore I hope this format is fine. I’ve searched for the issue on internet and checked the documentation of yt-dlp however could not find something useful or maybe I just dont understand what to do.

In a normal case, I was using youtube-dl to download musics from youtube and play it in my discord bot but its download rate restrictions became problematic (60-80 KiB/s). For this reason I started the use yt-dlp. It works fine if I use url directly. However, when I use a searchword instead of url, seems like code does not extract the info to get url. (Below code was working fine with youtube-dl too) Here is the code:

@bot.command()
async def play(ctx, *, searchword):
    ydl_opts = {}
    voice = ctx.voice_client

    #get the title and url from video

Below code works fine with direct url but when I write something such as (! is my command prefix by the way) !play By the Sword download does not start but console says:

Downloading playlist: By the Sword
    if searchword[0:4] == "http" or searchword[0:3] == "www":
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(searchword, download = False)
            title = info["title"]
            url = searchword
 
    if searchword[0:4] != "http" and searchword[0:3] != "www":
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(f"ytsearch:{searchword}", download = False)["entries"][0]
            title = info["title"]
            url = info["webpage_url"]
 
    ydl_opts = {
        'format' : 'bestaudio/best',
        "outtmpl" : f"{title}.mp3",
        "postprocessors": 
        [{"key" : "FFmpegExtractAudio", "preferredcodec" : "mp3", "preferredquality" : "192"}],   
    }



    def download(url):
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])
    loop = asyncio.get_event_loop()
    await loop.run_in_executor(None, download, url)

    #playing and queueing audio
    if voice.is_playing():
        queuelist.append(title)
        await ctx.send(f"Added to queue: {title}")
    else:
        voice.play(discord.FFmpegPCMAudio(f"{title}.mp3"), after = lambda e : check_queue())
        await ctx.send(f"Playing {title} !!!")
        filestodelete.append(title)

    def check_queue():
        try:
            if queuelist[0] != None:
                voice.play(discord.FFmpegPCMAudio(f"{queuelist[0]}.mp3"), after = lambda e : check_queue())
                filestodelete.append(queuelist[0])
                queuelist.pop(0)
        except IndexError:
            for file in filestodelete:
                os.remove(f"{file}.mp3")
            filestodelete.clear() 

I am not sure if the problem is about

info = ydl.extract_info(f"ytsearch:{searchword}", download = False)["entries"][0]

or downloading itself. Documentation of yt-dlp says that,

Tip: If you are porting your code from youtube-dl to yt-dlp, one important point to look out for is that we do not guarantee the return value of YoutubeDL.extract_info to be json serializable, or even be a dictionary. It will be dictionary-like, but if you want to ensure it is a serializable dictionary, pass it through YoutubeDL.sanitize_info as shown in the example above

Here is the link: https://github.com/yt-dlp/yt-dlp#embedding-yt-dlp
Thanks.

Asked By: 2-propanol

||

Answers:

Apparently, I solved the issue by myself by using a different way. As I mentioned above youtube_dl works fine however yt_dlp .extract_info() is problematic. A simple solution to fix this is extracting info by using youtube_dl module, then download file by using yt_dlp.

Use this for downlaoding:

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])

But this for extracting url and title from a given string which is not URL

if searchword[0:4] != "http" and searchword[0:3] != "www":
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(f"ytsearch:{searchword}", download = False)["entries"][0]
            title = info["title"]
            url = info["webpage_url"]

Do not forget to include both modules!

Answered By: 2-propanol

bro is there anyway you can help me with my discord bot. im trying to now integrate the Yt.dlp since the Yt.dl wont work sayig its outdaed altough its not. Sicne i dont rly know much about code most of the stuff i have is from google and forums like these. But i cant seem to understand how i should integrate yours to match mine. Cause if i jsut Copy paste yours it just messes everything up.

Like i just need a way to use your setup and mix it with mine i think. Cause my bot joins. But with my code it just doesnt play the music since it thinks itts an outdated vversion of youtube dl….

Answered By: fredeffi82
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.