ai-news-video
AI News Video — Automated Weekly Digest Production
A deterministic pipeline that turns live web research into a finished, broadcast-quality news video. Built for unattended/scheduled execution: every step either produces an artifact or fails loudly.
Core Principle
Research is non-deterministic; everything after it is deterministic.
Research quality is the only variable, so it gets the strictest gate
(news_fetch.py) plus editorial judgment. Once news.json is validated, the
render is fully scripted and reproducible.
Never skip the validation gate. A news video showing a fabricated or stale headline is worse than no video at all — it destroys the channel's credibility.
Pipeline
RESEARCH → VALIDATE → SCAFFOLD → RENDER → VERIFY → DELIVER
(agent) (script) (script) (script) (script) (agent)
Run steps in order. Do not skip VERIFY — a render can exit 0 and still have the wrong duration.
Step 1 — Research (agent, web tools)
Goal: 3–8 candidate stories, each with a real URL, publisher, and exact date.
- Compute the window at run time — never hardcode dates:
python3 scripts/news_fetch.py window --days 7 # {"start": "2026-10-06", "end": "2026-10-12", "days": 7} - Run 3–5 parallel WebSearch calls covering different angles so results
aren't drawn from a single editorial perspective:
AI news <Month Year>/artificial intelligence news week <dates><major lab> announcement(OpenAI, Google DeepMind, Anthropic, Meta, xAI)AI funding valuation round/AI regulation policy- a region-appropriate sweep (e.g.
人工智能 新闻 本周)
- Confirm the promising results with WebFetch: exact date, exact figures, publisher name. Search snippets alone are insufficient — dates and numbers get garbled in aggregation pages.
- Rank and cut to the final set. Aim for 5 items across diverse categories (model / funding / policy / product / market). Prefer primary sources (vendor blogs, filings) for specs and pricing.
Read references/editorial-standards.md for source tiering, ranking, and the
anti-fabrication rules. Apply them while selecting, not afterward.
Step 2 — Author the draft JSON
Write draft.json per the schema below — the validator is strict by design.
{
"meta": {
"week_range": "2026.10.06 — 2026.10.12",
"window": { "start": "2026-10-06", "end": "2026-10-12" }
},
"items": [
{
"title": "Anthropic 获 **600 亿美元** 芯片融资,华尔街银团豪赌算力",
"summary": "银行团分销债务融资,资助其租用谷歌 TPU 的 2027 年芯片订单。",
"emoji": "🚀",
"keywords": ["600 亿美元"],
"url": "https://www.chinanews.com/…",
"publisher": "中国新闻网 / Financial Times",
"date": "2026-10-06",
"source_tier": "通讯社/主流媒体"
}
]
}
Headline rules: wrap 1–3 keywords in **double asterisks**; keep visual width
≤ 92 CJK units; lead with the subject, land on the number or entity. Emoji must
be semantically tied to the topic. See references/editorial-standards.md §4.
Step 3 — Validate (script — hard gate)
python3 scripts/news_fetch.py validate draft.json -o content/news.json --verify-urls
Rejects: missing URL/publisher, out-of-window dates, empty summaries, oversized
headlines, duplicate stories, unusable emoji. Fix every error and re-run.
--verify-urls performs a live HTTP check (skips gracefully when offline).
Print a QC report and keep it for the final message:
python3 scripts/news_fetch.py report content/news.json
Step 4 — Scaffold (script)
./scripts/setup_project.sh ./remotion-videos
Copies the Remotion template (idempotent; never clobbers existing src/) and
installs dependencies only when missing. Use USE_NP_MIRROR=1 on slow networks.
Then place the validated file at remotion-videos/src/content/news.json.
Step 5 — Render (script)
./scripts/render.sh ./remotion-videos src/index.ts ai-weekly output/ai-weekly.mp4
Always use this script. It sets NODE_OPTIONS="" and
CODEBUDDY_BROKERED_FS_HOOK_ENABLED=false to work around a filesystem-brokering
shim that otherwise makes Remotion's bundler fail with EEXIST ... mkdir (see
references/troubleshooting.md §1). Running npx remotion directly will fail.
Step 6 — Verify (script, inside render.sh)
render.sh runs ffprobe and exits non-zero on any mismatch against
1920x1080 and the expected duration. Confirm manually if needed:
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,r_frame_rate,duration,nb_frames \
-of default=noprint_wrappers=1 output/ai-weekly.mp4
Expected: width=1920 height=1080 r_frame_rate=30/1 duration=20.000000.
Step 7 — Deliver (agent)
Call present_files with the MP4 path. In the reply include:
- verified specs (resolution / fps / duration / size) from ffprobe,
- the headlines with publisher + date (so every claim is checkable),
- the source tiering note,
- any deviation from the brief.
Expected Output
- Duration: 20.0s exactly @ 30fps (600 frames)
- Resolution: 1920×1080
- Structure: 2s intro → 5 × 3s news cards → outro CTA (absorbs the remainder)
- Visual: dark gradient ground, white headlines,
#00D4FFkeyword accents, vertical timeline whose node ignites as each story arrives
Customization
| Change | Edit |
|---|---|
| Colors, fonts, spacing, motion | theme.ts — the only file to touch for re-skins |
| Frame budget / durations | COMP in theme.ts (outro auto-rebalances) |
| Item count | Add/remove entries in news.json (3–8) |
| New scene type | New file in src/compositions/, composed from theme tokens |
| Aspect ratio (9:16, 1:1) | COMP.width/height + re-derive LAYOUT in theme.ts |
Never hardcode a hex value or pixel magic number inside a scene — that defeats the theme and is the main cause of visual drift between variants.
Bundled Resources
scripts/news_fetch.py— window computation, validation gate, QC reportscripts/setup_project.sh— idempotent project scaffolding + depsscripts/render.sh— shim-safe render + ffprobe verificationassets/project-template/— full Remotion project (theme, scenes, components)references/editorial-standards.md— sourcing, ranking, headline craftreferences/visual-design.md— color, type, layout, motion rationalereferences/troubleshooting.md— the nine real failure modes and fixes
Hard Rules
- Never fabricate a URL, date, figure, or publisher.
- Never hardcode a date window — compute it per run.
- Never bypass
news_fetch.py validate. - Never render without
render.sh(the shim workaround is mandatory). - Never report success without ffprobe confirmation.
- Never put raw colors/sizes in a scene file — use
theme.ts.