用 google-genai 1.1 上传一段 12 分钟录屏,随后立刻调 generate_content 引用这个 file uri,返回 400,提示 file is not in ACTIVE state,文件列表里看到状态一直是 PROCESSING。

一开始怀疑是「视频体积接近 2GB 上限,处理时间被拉长到数分钟」,查了一圈,方向不对。

排查方向其实有限,先把可能性排一排。上传接口只完成接收,转码和索引还没结束。也可能是上传后没有轮询 files.get 就直接发起推理。

不容易想到的是,用了另一个 API key 查询状态,看到的不是同一个文件。

先查询文件对象拿到当前状态

curl "https://generativelanguage.googleapis.com/v1beta/files/$FILE_ID?key=$KEY"

然后写一个带退避的轮询直到 state 变成 ACTIVE

python -c "import time,google.generativeai as g;g.configure(api_key='$KEY');f=g.get_file('$FILE_ID');
while f.state.name!='ACTIVE':time.sleep(5);f=g.get_file('$FILE_ID')
print(f.uri)"

随后把视频压缩到 720p 再上传缩短处理时间

ffmpeg -i screen.mkv -vf scale=-2:720 -c:v libx264 -crf 26 -c:a aac screen_720.mp4

拿到 ACTIVE 后再提交带 file_data 的请求

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$KEY" -H "Content-Type: application/json" -d '{"contents":[{"parts":[{"file_data":{"mime_type":"video/mp4","file_uri":"$URI"}},{"text":"总结这段录屏的操作步骤"}]}]}'

别只看报错消失,验证要多做一步。轮询日志里状态从 PROCESSING 变成 ACTIVE,随后请求返回 200,模型能复述录屏中的关键步骤,不再出现状态相关的 400。

补一句。视频类文件是异步处理的,上传成功不等于可用,轮询要按文件 id 查而不是按列表猜,且必须用同一个 key 查询。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189