将代码从 youtube-dl 移植到 Python Discord Bot 的 yt-dlp 库
Porting code from youtube-dl to yt-dlp library for Python Discord Bot
这是我的第一个问题,因此我希望这种格式没问题。我在互联网上搜索了这个问题并查看了 yt-dlp 的文档,但是找不到有用的东西,或者我只是不明白该怎么做。
在正常情况下,我使用 youtube-dl 从 youtube 下载音乐并在我的 discord bot 中播放,但它的下载速率限制出现问题 (60-80 KiB/s)。为此我开始使用 yt-dlp。如果我直接使用 url 就可以正常工作。但是,当我使用搜索词而不是 url 时,代码似乎没有提取信息来获取 url。 (下面的代码也适用于 youtube-dl)这是代码:
@bot.command()
async def play(ctx, *, searchword):
ydl_opts = {}
voice = ctx.voice_client
#get the title and url from video
下面的代码可以直接 url 使用,但是当我写一些东西时(顺便说一句!是我的命令前缀) !play By the Sword 下载未启动但控制台显示:
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()
我不确定问题是不是关于
info = ydl.extract_info(f"ytsearch:{searchword}", download = False)["entries"][0]
或自行下载。 yt-dlp 的文档说,
提示:如果您将代码从 youtube-dl 移植到 yt-dlp,需要注意的重要一点是我们不保证 return 的值 YoutubeDL.extract_info 是 json 可序列化的,甚至是字典。它将类似于字典,但如果您想确保它是一个可序列化的字典,请通过 YoutubeDL.sanitize_info 传递它,如上例所示
这是 link:https://github.com/yt-dlp/yt-dlp#embedding-yt-dlp
谢谢。
显然,我用不同的方法自己解决了这个问题。正如我上面提到的 youtube_dl 工作正常但是 yt_dlp .extract_info()
是有问题的。解决此问题的一个简单解决方案是使用 youtube_dl 模块提取信息,然后使用 yt_dlp.
下载文件
使用这个下载:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
但这用于从给定的字符串中提取 url 和标题,这不是 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"]
不要忘记包含这两个模块!
这是我的第一个问题,因此我希望这种格式没问题。我在互联网上搜索了这个问题并查看了 yt-dlp 的文档,但是找不到有用的东西,或者我只是不明白该怎么做。
在正常情况下,我使用 youtube-dl 从 youtube 下载音乐并在我的 discord bot 中播放,但它的下载速率限制出现问题 (60-80 KiB/s)。为此我开始使用 yt-dlp。如果我直接使用 url 就可以正常工作。但是,当我使用搜索词而不是 url 时,代码似乎没有提取信息来获取 url。 (下面的代码也适用于 youtube-dl)这是代码:
@bot.command()
async def play(ctx, *, searchword):
ydl_opts = {}
voice = ctx.voice_client
#get the title and url from video
下面的代码可以直接 url 使用,但是当我写一些东西时(顺便说一句!是我的命令前缀) !play By the Sword 下载未启动但控制台显示:
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()
我不确定问题是不是关于
info = ydl.extract_info(f"ytsearch:{searchword}", download = False)["entries"][0]
或自行下载。 yt-dlp 的文档说,
提示:如果您将代码从 youtube-dl 移植到 yt-dlp,需要注意的重要一点是我们不保证 return 的值 YoutubeDL.extract_info 是 json 可序列化的,甚至是字典。它将类似于字典,但如果您想确保它是一个可序列化的字典,请通过 YoutubeDL.sanitize_info 传递它,如上例所示
这是 link:https://github.com/yt-dlp/yt-dlp#embedding-yt-dlp 谢谢。
显然,我用不同的方法自己解决了这个问题。正如我上面提到的 youtube_dl 工作正常但是 yt_dlp .extract_info()
是有问题的。解决此问题的一个简单解决方案是使用 youtube_dl 模块提取信息,然后使用 yt_dlp.
使用这个下载:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
但这用于从给定的字符串中提取 url 和标题,这不是 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"]
不要忘记包含这两个模块!