YouTube Upload API v3上传大视频触发TimeoutError写入超时问题
问题原因
大体积视频上传触发TimeoutError: The write operation timed out,核心原因是Google API Python客户端默认的单次请求超时阈值较短,小体积视频上传耗时低于阈值可以正常完成,大体积视频上传总时长超过阈值就会触发超时。另外你当前使用的是简单上传模式,单次提交整个文件,失败后无法续传,本身就不适合大文件上传场景。
另外你的代码里存在一处笔误:snippet下的categoryI字段名拼写错误,正确应为categoryId,该问题不会触发超时,但会导致视频分类设置不生效。
解决方案
按优先级从高到低操作:
1. 改用可恢复分块上传(官方推荐方案)
YouTube Data API v3针对大于5MB的媒体文件,官方推荐使用可恢复上传模式,将文件拆分为固定大小的分块逐次上传,既可以避免单次请求超时,上传失败时也可以从失败的分块开始续传,不需要从头重传。
修改对应代码段如下:
request_body = { 'snippet': { 'categoryId': 24, # 修正原拼写错误categoryI -> categoryId 'title': title, 'description': description, 'tags': tags }, 'status': { 'privacyStatus': 'private', 'publishAt': upload_date_time, 'selfDeclaredMadeForKids': False, }, 'notifySubscribers': False } # 初始化媒体文件,开启可恢复上传,设置单块大小为10MB,网络环境差可调整为5MB mediaFile = MediaFileUpload( videoFilename, resumable=True, chunksize=10 * 1024 * 1024 ) # 构建上传请求 upload_request = service.videos().insert( part='snippet,status', body=request_body, media_body=mediaFile ) # 逐块上传,可自定义单块请求超时时间 response_upload = None while response_upload is None: # 单块请求超时设置为60秒即可,单块失败自动重试3次 status, response_upload = upload_request.next_chunk(num_retries=3, timeout=60) # 可选:打印实时上传进度 if status: print(f"当前上传进度:{int(status.progress() * 100)}%")
修改后不需要再调用.execute()方法,循环执行next_chunk()完成所有分块传输后,response_upload就是最终的上传响应结果,后续缩略图上传的逻辑不需要改动。
2. 调整请求超时与重试配置
如果暂时不想改成分块上传(不推荐,大文件失败率极高),可以在创建服务实例和执行请求时调大超时阈值,同时开启自动重试:
- 构建
service实例时,增加num_retries=3参数,遇到网络波动、超时错误时自动重试最多3次 - 调用
.execute()时传入超时参数,比如.execute(timeout=1200),将单次请求超时设置为20分钟,具体时长可以根据你的上行带宽计算:超时时间(秒) = 文件大小(bit) / 上行带宽(bps) * 1.5,预留50%的冗余时间避免网络波动影响。
3. 网络环境排查
如果调整上传逻辑后仍然偶发超时,可逐一排查以下网络相关问题:
- 测试本地上行带宽,确认设置的超时时间可以覆盖最大体积视频的上传耗时
- 如果使用代理服务,检查代理的长连接限制和上行带宽,部分代理会对大流量长连接做拦截,容易触发中途断连超时
- 上传过程中关闭其他占用上行带宽的程序,比如云盘同步、实时直播、其他大文件上传任务,避免带宽被抢占导致传输速度过慢
内容的提问来源于stack exchange,提问作者THEMOUNTAINSANDTHESKIES
相关产品推荐
相关产品推荐

