Youtube-dl搜索时如何跳过直播流避免format not available错误
问题描述
我开发了一个通过Youtube-dl执行关键词搜索并展示结果的程序,当前设置搜索返回5条结果。
目前遇到的问题是:当搜索结果包含直播流时,Youtube-dl会返回ERROR: requested format not available,函数返回的info内容为空,其余非直播结果也无法正常获取。即便配置了"ignoreerrors":True参数,程序不会被错误中断,但仍会输出错误日志,且info依旧为空。
请问Youtube_dl是否提供跳过搜索直播流的配置项?或者是否有其他解决方案可以解决该问题?
原有代码
async def search_song(self, amount, song, get_url=False): info = await self.bot.loop.run_in_executor(None, lambda: youtube_dl.YoutubeDL({"format" : "bestaudio",'default_search': 'auto',"ignoreerrors":True,}).extract_info(f"ytsearch{amount}:{song}", download=False, ie_key="YoutubeSearch")) if len(info["entries"]) == 0: return None return [entry["webpage_url"] for entry in info["entries"]] if get_url else info
运行报错日志
[download] Downloading video 1 of 5 [youtube] q8A_TvjvMjo: Downloading webpage [youtube] q8A_TvjvMjo: Downloading m3u8 information [youtube] q8A_TvjvMjo: Downloading MPD manifest ERROR: requested format not available [download] Downloading video 2 of 5 [youtube] B1go9DPd_xg: Downloading webpage [download] Downloading video 3 of 5 [youtube] XGSSmQiqBl8: Downloading webpage [download] Downloading video 4 of 5 [youtube] u962IzRYPIE: Downloading webpage ERROR: Premieres in 18 hours [download] Downloading video 5 of 5 [youtube] WYYj2DUPHGI: Downloading webpage [download] Finished downloading playlist: sleep Ignoring exception in command search: Traceback (most recent call last): File "C:\Users\kogetu\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped ret = await coro(args, **kwargs) File "C:\Bot\PiyoMusicBot\music.py", line 147, in search embed.description += (f"[{entry['title']}]({entry['webpage_url']})\n") TypeError: 'NoneType' object is not subscriptable The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\kogetu\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke await ctx.command.invoke(ctx) File "C:\Users\kogetu\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke await injected(ctx.args, **ctx.kwargs) File "C:\Users\kogetu\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'NoneType' object is not subscriptable
解决方案
问题根因
ignoreerrors参数生效后,解析失败的直播、待首映内容会以None的形式存入entries列表,后续直接遍历列表取值时,访问None的键就会抛出类型错误。
修复方案
方案1:添加匹配过滤器直接排除无效内容(优先推荐)
youtube-dl提供match_filter配置项,可在解析阶段直接过滤不符合要求的直播、待首映内容,不需要后续二次处理。
方案2:提取结果后兜底过滤空条目
两种方案可同时使用,彻底避免报错。
修改后的代码
import datetime # 过滤规则:排除直播、未上线的首映内容 def match_filter_func(info_dict): if info_dict.get('is_live'): return '跳过直播内容' if info_dict.get('upcoming'): return '跳过待上线首映内容' if info_dict.get('release_date') and info_dict.get('release_date') > datetime.datetime.now().strftime('%Y%m%d'): return '跳过未到上线时间的内容' return None async def search_song(self, amount, song, get_url=False): ydl_opts = { "format" : "bestaudio", 'default_search': 'auto', "ignoreerrors":True, # 应用过滤规则 "match_filter": match_filter_func, # 可选:关闭不必要的错误日志输出 "quiet": True } info = await self.bot.loop.run_in_executor(None, lambda: youtube_dl.YoutubeDL(ydl_opts).extract_info(f"ytsearch{amount}:{song}", download=False, ie_key="YoutubeSearch")) if not info or not info.get("entries"): return None # 兜底过滤所有空条目 valid_entries = [entry for entry in info["entries"] if entry is not None] if len(valid_entries) == 0: return None return [entry["webpage_url"] for entry in valid_entries] if get_url else valid_entries
额外优化建议
如果要进一步降低直播内容的命中概率,可以在搜索关键词后拼接 -live,从搜索源头上过滤大部分带live标识的直播内容。
内容的提问来源于stack exchange,提问作者AmazingSushi
相关产品推荐
相关产品推荐

