如何使用pytube实现YouTube视频下载进度显示?
YouTube 下载进度显示的正确实现方式
我完全懂你查了一堆资料还是摸不着头脑的感觉——这个回调函数的参数规则确实容易让人绕晕!咱们一步步把你的问题拆解清楚:
1. 回调函数的正确传递方式
你代码里有个核心错误:
yt.register_on_progress_callback(on_progress(video, chunk_size, 'D:\\Videos', video.filesize))
register_on_progress_callback需要传入的是函数本身(也就是函数对象),而不是调用函数后的返回值。你现在这样写相当于直接执行了on_progress,把它的返回值(这里是None)传给了方法,自然不会触发进度回调。正确写法是直接传函数名:
yt.register_on_progress_callback(on_progress)
不用带括号和额外参数,因为这些参数是pytube内部自动帮你传递的,根本不需要手动传!
2. 回调函数参数的具体含义
你疑惑的file_handle和bytes_remaining都是pytube自动注入的,不用你自己去获取:
stream: 当前正在下载的视频流对象(就是你用get_highest_resolution()拿到的video),通过它能获取总文件大小stream.filesizechunk: 刚下载完成的一小段二进制数据块(一般用不到,除非你要做自定义数据处理)file_handle: 正在写入的文件句柄(通常不需要操作它,pytube会自动完成文件写入逻辑)bytes_remaining: 还未下载的字节数,用总大小减去它就是已经下载的字节数
3. 修正后的完整可运行代码
调整后的正确实现如下,还加了一点体验优化:
def on_progress(stream, chunk, file_handle, bytes_remaining): total_size = stream.filesize bytes_downloaded = total_size - bytes_remaining percentage = bytes_downloaded / total_size * 100 # 用end="\r"实现进度条动态刷新,不会打印一堆重复行 print(f"下载进度: {percentage:.2f}%", end="\r") def main(): url = "https://www.youtube.com/watch?v=GceNsojnMf0" # 初始化时直接传入回调,和register_on_progress_callback效果一致,写法更简洁 yt = YouTube(url, on_progress_callback=on_progress) video = yt.streams.get_highest_resolution() print(f"获取视频信息 \"{video.title}\"..") print(f"信息获取成功\n") print(f"视频信息: \n" f"文件大小: {round(video.filesize * 0.000001, 2)} MB\n" f"最高分辨率: {video.resolution}\n" f"UP主: {yt.author}") print(f"播放量: {:,}\n".format(yt.views)) print(f"开始下载 \"{video.title}\"..") video.download('D:\\Videos') print("\n下载完成!") if __name__ == "__main__": main()
4. 常见疑问解答
- 为什么别人写
yt = YouTube(url, on_progress)不带括号?因为这里要传的是函数本身(函数对象),如果加了括号,就变成执行函数并把返回值传进去,这就完全错了。 - 我需要处理
file_handle吗?不需要,pytube会自动管理文件的打开、写入和关闭,这个参数只是给你留的钩子,只有当你有特殊需求(比如加密写入)时才需要用到。
内容的提问来源于stack exchange,提问作者Mayfair
相关产品推荐
相关产品推荐

