smoke_video_pipeline.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. """真机验证:抖音视频走完整流水线(原生提取→筛选→拆分→解构→落库),用本地 mp4 绕过下载网络。
  2. 用法:python scripts/smoke_video_pipeline.py <env_file> <video.mp4> [content_id]
  3. """
  4. from __future__ import annotations
  5. import sys
  6. import httpx
  7. from creation_knowledge.config import Settings
  8. from creation_knowledge.integrations.db import CkStore
  9. from creation_knowledge.integrations.llm import default_chat
  10. from creation_knowledge.integrations.video_extract import extract_video
  11. from creation_knowledge.models import Post
  12. from creation_knowledge.stages import (
  13. build_ingest_payload, deconstruct_item, screen_post, split_post)
  14. def main() -> int:
  15. args = sys.argv[1:]
  16. env_file = next((a for a in args if a.endswith(".env")), ".env")
  17. video = next((a for a in args if a.endswith((".mp4", ".bin"))), None)
  18. cid = next((a for a in args if not a.endswith((".env", ".mp4", ".bin"))),
  19. "7612631899479648866")
  20. settings = Settings.from_env(env_file)
  21. chat = default_chat(env_file)
  22. det = httpx.post("http://crawler.aiddit.com/crawler/dou_yin/detail",
  23. json={"content_id": cid}, timeout=40).json()["data"]["data"]
  24. post = Post(id=f"dy_{cid}", platform="douyin",
  25. url=f"https://www.douyin.com/video/{cid}", content_id=cid,
  26. title=det.get("title") or "", content_type="video",
  27. body_text=det.get("body_text") or "",
  28. video_urls=[det["video_url_list"][0]["video_url"]],
  29. raw={"data": {"data": det}})
  30. store = CkStore(settings.pg)
  31. store.delete_post(post.id)
  32. store.upsert_post(post)
  33. print("[extract] 原生整段视频 …")
  34. content = extract_video(post, settings=settings, video_path=video)
  35. store.upsert_post(post)
  36. store.set_extracted(post.id, content.model_dump())
  37. print(f" 段数={len(post.cards)} overall={content.text[:50]}")
  38. print(f" 段卡示例={[(c.index, c.start, c.end) for c in post.cards[:3]]}")
  39. scr = screen_post(post, content, chat=chat)
  40. store.set_screening(post.id, scr.model_dump())
  41. print(f"[screen] passed={scr.passed} score={scr.score}")
  42. if scr.passed:
  43. items = split_post(post, content, chat=chat)
  44. print(f"[split] {len(items)} 条知识")
  45. for it in items:
  46. deco = deconstruct_item(it, chat=chat)
  47. payload = build_ingest_payload(post, it, deco)
  48. store.save_item(post.id, it.model_dump(), deco.model_dump(), payload.model_dump())
  49. store.update_stage(post.id, "done")
  50. p = store.read_post(post.id)
  51. its = store.read_items(post.id)
  52. print(f"[DB] stage={p['stage']} cards={len(p.get('cards') or [])} "
  53. f"kinds={set(c['kind'] for c in (p.get('cards') or []))} items={len(its)}")
  54. if its:
  55. print(f" item0: source_cards={its[0]['item'].get('source_cards')} "
  56. f"evidence0={(its[0]['item'].get('evidence') or [None])[0]}")
  57. return 0
  58. if __name__ == "__main__":
  59. raise SystemExit(main())