smoke_video_openrouter.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. """实验B:本地 mp4 → base64 → 经 OpenRouter 把整段视频发给 Gemini,按时间戳提炼。
  2. 我们没有直连 GEMINI_API_KEY,Gemini 走 OpenRouter。OpenRouter 对 Gemini 视频支持
  3. base64 data URL(Vertex 通道)。本脚本验证这条路能否拿到详细的时间戳分段提炼。
  4. 用法:python scripts/smoke_video_openrouter.py <env_file> <video.mp4>
  5. """
  6. from __future__ import annotations
  7. import base64
  8. import sys
  9. import httpx
  10. PROMPT = (
  11. "你在从一条短视频里提炼「创作知识」——能指导别人怎么做内容的方法/原理/清单。\n"
  12. "视频是口播+画面,请**同时听口播、看画面与字幕**。按视频时间顺序分段,"
  13. "每段给时间戳和这段讲到的创作知识。原文(含口播)没有的不要编造。只输出 JSON:\n"
  14. '{"video_title": "", "overall": "全片在教什么,一两句话",\n'
  15. ' "segments": [{"start": "MM:SS", "end": "MM:SS", "title": "这段小标题",\n'
  16. ' "knowledge_types": ["what/why/how"], "what": "或null", "why": "或null", "how": "或null"}]}'
  17. )
  18. def load_env(path):
  19. env = {}
  20. for line in open(path):
  21. line = line.strip()
  22. if line and not line.startswith("#") and "=" in line:
  23. k, v = line.split("=", 1)
  24. env[k.strip()] = v.strip().strip('"').strip("'")
  25. return env
  26. def main():
  27. env_file = next((a for a in sys.argv[1:] if a.endswith(".env")), ".env")
  28. video = next((a for a in sys.argv[1:] if a.endswith((".mp4", ".bin"))), None)
  29. env = load_env(env_file)
  30. key = env.get("OPENROUTER_API_KEY")
  31. base = (env.get("OPENROUTER_BASE_URL") or "https://openrouter.ai/api/v1").rstrip("/")
  32. model = env.get("OPENROUTER_MODEL") or "google/gemini-3-flash-preview"
  33. if not key:
  34. raise SystemExit("缺 OPENROUTER_API_KEY")
  35. raw = open(video, "rb").read()
  36. print(f"video {video}: {len(raw)} bytes ({len(raw)//1024//1024} MB) -> base64")
  37. data_url = "data:video/mp4;base64," + base64.b64encode(raw).decode()
  38. body = {"model": model, "messages": [{"role": "user", "content": [
  39. {"type": "text", "text": PROMPT},
  40. {"type": "video_url", "video_url": {"url": data_url}},
  41. ]}]}
  42. print(f"POST {base}/chat/completions model={model} payload≈{len(data_url)//1024//1024}MB")
  43. r = httpx.post(f"{base}/chat/completions",
  44. headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
  45. json=body, timeout=600)
  46. print("HTTP", r.status_code)
  47. if r.status_code != 200:
  48. print(r.text[:800]); raise SystemExit(1)
  49. out = r.json()
  50. print("provider:", out.get("provider"), "| usage:", out.get("usage"))
  51. print("==== 提炼结果 ====")
  52. print(out["choices"][0]["message"]["content"])
  53. if __name__ == "__main__":
  54. raise SystemExit(main())