如何通过Graph API从FastAPI向Facebook Page传视频?格式错误求助
解决Facebook Graph API上传视频格式不支持的问题
我尝试使用Python结合Graph API向Facebook Page上传视频文件,编写了如下上传函数:
def upload_video_file(page_id: str, access_token: str, video_file: UploadFile): upload_url = f"https://graph.facebook.com/{page_id}/videos" headers = {"Authorization": f"Bearer {access_token}"} files = {"file": video_file.file} response = requests.post(upload_url, headers=headers, files=files) data = response.json() if data: return data else: return {"message": "failed uploud video"}
并在以下FastAPI端点中调用该函数:
@router.post("/upload-video/{page_id}") async def post_video(page_id: str, video_file: UploadFile = File(...), access_token: str = Header(..., description="Access Token")): response = upload_video_file(page_id, access_token, video_file) return JSONResponse (response)
但收到如下错误:
{ "error": { "message": "The video file you selected is in a format that we don't support.", "type": "OAuthException", "code": 352, "error_subcode": 1363024, "is_transient": false, "error_user_title": "Format Video Tidak Didukung", "error_user_msg": "Format video yang Anda coba unggah tidak didukung. Silakan coba lagi dengan sebuah video dalam format yang didukung.", "fbtrace_id": "AZNNyQhyPDfi5AhDOBpdA5c" } }
解决步骤
1. 确认视频文件符合Facebook格式要求
Facebook仅支持特定规范的视频:
- 容器格式优先MP4、MOV
- 视频编码必须为H.264,音频编码为AAC
- 帧率不超过60fps,分辨率最高支持4K
- 文件大小超过1GB时,必须使用分块上传方式
如果你的视频是AVI、WMV等非支持格式,或编码不符合要求,先用FFmpeg等工具转码为符合标准的MP4文件。
2. 修正上传代码的文件处理逻辑
当前代码存在两个关键问题:文件指针可能不在开头导致上传不完整,且未明确指定文件元信息让Facebook识别。修改后的代码如下:
上传函数修正版:
def upload_video_file(page_id: str, access_token: str, video_file: UploadFile): upload_url = f"https://graph.facebook.com/{page_id}/videos" headers = {"Authorization": f"Bearer {access_token}"} # 重置文件指针到开头,避免读取不完整内容 video_file.file.seek(0) # 明确传入文件名、文件对象和内容类型,帮助Facebook识别文件 files = { "file": (video_file.filename, video_file.file, video_file.content_type) } response = requests.post(upload_url, headers=headers, files=files) data = response.json() return data if data else {"message": "failed upload video"}
FastAPI端点修正版(修复JSONResponse调用的语法错误):
@router.post("/upload-video/{page_id}") async def post_video(page_id: str, video_file: UploadFile = File(...), access_token: str = Header(..., description="Access Token")): response = upload_video_file(page_id, access_token, video_file) return JSONResponse(response)
3. 大文件使用分块上传
如果视频文件超过1GB,直接POST上传会失败,需按以下流程分块上传:
- 初始化上传会话:发送POST请求到
https://graph.facebook.com/{page_id}/videos,携带upload_phase=start和file_size(文件总字节数),获取upload_session_id和upload_url。 - 分块上传内容:分块读取视频(每块建议10MB-100MB),发送PUT请求到
upload_url,携带offset(当前块起始字节位置)、file_size和块数据。 - 完成上传:发送POST请求到
https://graph.facebook.com/{page_id}/videos,携带upload_phase=finish和upload_session_id,完成视频上传。
分块上传核心逻辑示例:
def init_upload_session(page_id, access_token, file_size): url = f"https://graph.facebook.com/{page_id}/videos" headers = {"Authorization": f"Bearer {access_token}"} params = {"upload_phase": "start", "file_size": file_size} return requests.post(url, headers=headers, params=params).json() def upload_chunk(upload_url, file_obj, offset, chunk_size): file_obj.seek(offset) chunk = file_obj.read(chunk_size) headers = {"Content-Range": f"bytes {offset}-{offset+len(chunk)-1}/*"} return requests.put(upload_url, headers=headers, data=chunk).status_code == 200 def finish_upload(page_id, access_token, upload_session_id): url = f"https://graph.facebook.com/{page_id}/videos" headers = {"Authorization": f"Bearer {access_token}"} params = {"upload_phase": "finish", "upload_session_id": upload_session_id} return requests.post(url, headers=headers, params=params).json()
内容的提问来源于stack exchange,提问作者Dimas Surya
相关产品推荐
相关产品推荐

