基于Python与Youtube Data API的大文件上传问题求助
解决YouTube Data API大文件上传超时/速度慢的问题
看起来你在处理广播公司的日常YouTube上传任务时,遇到了大文件(1GB+)上传超时、速度不达标的问题。结合你的代码片段,我来拆解下核心原因和对应的修复方案:
一、上传失败/超时的关键原因
你的代码里有几个拖慢效率甚至导致失败的问题:
过小的分块大小
你设置的chunksize=1024*1024(1MB)对于1GB文件来说,意味着要发起超过1000次HTTP请求。每次请求都要经历TCP握手、头部传输、响应等待的开销,次数一多不仅速度被拉垮,还容易因为网络波动、API限流导致中间某一次请求失败,直接卡住整个上传流程。错误的上传循环逻辑
原代码里的while upload is None: upload = upload.next_chunk()逻辑完全错误。Resumable上传的正确流程是循环调用next_chunk()直到上传完成,而不是判断upload是否为None。而且你在循环后又调用了upload.execute(),这是冗余且错误的——resumable上传的结果是在next_chunk()的返回值里,重复调用execute()会触发不必要的请求,甚至引发错误。缺少错误重试机制
大文件上传过程中很容易遇到临时网络波动、API限流(429错误),你的代码没有任何重试逻辑,一旦出现一次错误就直接终止上传,自然会出现“上传一小时还没完成”的情况。
二、优化后的代码实现
下面是调整后的代码,解决上述问题并大幅提升上传速度:
from googleapiclient.http import MediaFileUpload import googleapiclient.errors import time youtube = googleapiclient.discovery.build(api_service_name, api_version, credentials=creds) # 1. 大幅提升分块大小,建议设置为8MB-64MB之间,根据带宽调整 # 1GB文件用64MB分块仅需16次请求,极大减少HTTP开销 CHUNKSIZE = 64 * 1024 * 1024 # 64MB # 2. 初始化上传请求 upload_request = youtube.videos().insert( part="snippet,status", body={ "snippet": { "categoryId": "27", "description": descName, "title": titleName, "tags": ['one','two'] }, "status": { "privacyStatus": "public" } }, media_body=MediaFileUpload( y, chunksize=CHUNKSIZE, resumable=True ) ) # 3. 正确的resumable上传循环,带指数退避重试机制 response = None retry_count = 0 max_retries = 5 # 最多重试5次 while response is None: try: status, response = upload_request.next_chunk() if status: print(f"上传进度: {int(status.progress() * 100)}%") except googleapiclient.errors.HttpError as e: if e.resp.status in [404, 429, 500, 502, 503, 504]: # 遇到常见可重试错误,指数退避等待后重试 retry_count += 1 if retry_count > max_retries: raise Exception(f"超过最大重试次数: {max_retries}") wait_time = 2 ** retry_count print(f"上传出错,{wait_time}秒后重试... 错误信息: {e}") time.sleep(wait_time) else: # 不可重试的错误直接抛出 raise except Exception as e: print(f"非HTTP错误: {e}") retry_count += 1 if retry_count > max_retries: raise time.sleep(2 ** retry_count) if response and "id" in response: print(f'视频上传成功,ID: {response["id"]}') videoId = response["id"] else: exit('上传失败: 未获取到视频ID')
三、额外的速度优化建议
- 灵活调整分块大小:如果你的上传带宽较高(比如100Mbps以上),可以尝试将分块调到128MB;带宽较低的话,32MB也是不错的选择,找到最适合你网络的平衡点。
- 优化网络环境:确保运行代码的机器离YouTube上传节点尽可能近(比如使用海外服务器上传),减少跨区域网络延迟。
- 检查带宽限制:确认你的ISP或公司防火墙没有限制YouTube的上传带宽,必要时联系网络管理员调整。
- 预压缩视频:如果原始视频码率过高,先压缩到合适的大小再上传——YouTube会自动转码,不需要上传超大原始文件,这能从根源上减少上传时间。
内容的提问来源于stack exchange,提问作者gintdm
相关产品推荐
相关产品推荐

