video-editing について
トーク動画や vlog の制作者向けの動画編集スキルです。素材整理から文字起こしの確認、編集、レンダリング、各プラットフォームへの出力までを扱い、制作工程に素材連携の記録とレビューゲートを設けています。
主な機能
- 01素材整理とプロジェクト作成
- 02文字起こしの確認と字幕処理
- 03ラフカット、結合、加工
- 04プラットフォーム別のレンダリングと出力
- 05レビューと承認のゲート
活用シーン
- 01元素材を編集プロジェクトに整理
- 02文字起こしを使って口癖や重複を除去
- 03短編動画を作成して対象プラットフォームへ出力
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ maxazure/ video-editing-skill --skill video-editingインストール後、Claude Code で/video-editingを入力して読み込まれたか確認します。
詳細
Video Editing Skill — 视频剪辑技能(V3)
适配 小红书 / 抖音 / 微信视频号 三大主流平台。一条 从素材导入 → 口播 → 重组故事 → 平台守门 → 自动丰富 → 渲染 → 三平台导出 → 标题文案 的端到端流水线,按各平台的算法、比例、时长、审核规则调过参——不只是剪辑工具。
V3 完整流水线(一图看懂)
口播音频 + 无声素材
│
├─→ project_bootstrap.py 原始素材目录 → source inventory / project.md
├─→ edit_brief_plan.py 用户一句话需求 → 本地脚本 runbook / gates
├─→ runtime_preflight.py workflow profile → FFmpeg/Node 命令、编码器、filters / live gate
├─→ interlace_conform.py 交错/telecine 采样 → progressive 工作副本 / 全长 A/B gate
├─→ frame_rate_conform.py 手机/录屏 VFR → 全量 PTS 检测 / CFR 工作副本 / live gate
├─→ black_edge_trim.py 首尾黑场 + 静音覆盖 → CFR 工作副本 / 原片边界 proof + live gate
├─→ program_breaks.py 内部黑场与全音轨静音重叠 → 只读分段候选 / 复核时间点
├─→ border_crop.py 画面内持续黑边 → 逐时点 cropdetect 证据 / 保守裁切建议
├─→ motion_center.py 局部像素运动中心 → 只读构图复核时间点
├─→ loop_fill.py 短片 → 次数/固定时长 hard repeat / 真实接缝 proof + 完整审片 gate
├─→ ping_pong_loop.py 短动作 → 端帧去重正放/倒放 / 折返+循环双 proof / live gate
├─→ clip_assembly.py 多源片段 → 单次画布/CFR/SAR/音频归一 / 全接缝 proof + live gate
├─→ edit_style_profile.py 个人/品牌创意方向、节奏与渲染/文案默认值 → 可移植 profile
├─→ production_authorization.py
│ 确切素材/动作/provider/权利依据 → 显式授权 + live gate
├─→ transcribe.py 转写 + 词级时间戳 + 口误标记
├─→ transcript_silence_qa.py 原始转写 vs 实测静音 → 幻觉疑点供回听
├─→ transcript_lookup.py 原话检索 / 时间窗口读取 → 少量带源时间码的结果
├─→ visual_transcript_index.py
│ 现有关键帧 + 附近原话 → 带源哈希的 JSON/Markdown 复核索引
├─→ semantic_transcript_review.py
│ 全篇前后文审校包 / 最小补丁验证 / 人工 choices gate
├─→ transcript_review.py 本地同步媒体 HTML 校稿 / CPS 提示 / review.txt 回写
├─→ takes_pack.py 多 take / Scribe transcript → phrase-level 阅读视图
│ speaker / audio_event 编辑节拍
├─→ script_alignment.py 已审目标稿 → 多 take 原话候选 / choices / render_config
│ 词/段边界 / 透明分数 / 歧义与缺素材 gate
├─→ audio_sync.py 外录音轨自动对齐 / 替换音轨计划
├─→ multicam_sync.py 多机位 → 参考时间线 / 时钟漂移证据 / 对齐预览 gate
├─→ multicam_switch.py 已同步机位 → 归一化说话者音频 / 自动导播草稿 / 完整审片 gate
├─→ scene_boundaries.py fixed/adaptive 视觉切点 + 逐切点 evidence
├─→ visual_dedupe.py 多来源场景 → 感知哈希重复组 / 保留建议 / review gate
├─→ video_understanding.py 抽样帧 + 可选 YOLO 检测 / tracks / scene_tags
├─→ video_stabilization.py 手持素材 → source-bound 后端计划 / 工作副本 / 全长 A/B gate
├─→ chroma_key.py 绿幕/蓝幕 → composite + matte 代表帧 / 人工 review / 完整渲染 gate
├─→ highlight_picker.py 长视频精华候选 / brief-query 定向找片段
├─→ audio_boundary_snap.py 已选片段 → 词/句末/静音边界校正
├─→ shorts_batch.py 精华候选 → per-short render_config / render + QA job sheet
├─→ rough_cut.py ASR 粗剪:去纯口头禅 / 相邻重复句
├─→ hook_variants.py 前三秒 hook 批量角度 / 推荐排序 / 风险检查
├─→ rewrite_script.py LLM 重组 5 段式(hook/pain/turn/value/cta)
├─→ content_guard.py 80+ 条平台雷区 lint
├─→ source_receipts.py 事实 claim → URL/截图 source deck + publish gate
├─→ beat_sync.py BGM beat-grid → 可审计剪辑骨架,或吸附已有切点
├─→ speed_ramp.py impact ranges → source-bound 局部变速计划 / 验证 / apply
├─→ freeze_punch.py impact frame → 定格替换窗口 / punch crop / unchanged audio timeline gate
├─→ auto_enrich.py B-roll / 章节卡 / 贴纸 / 强调点 / BGM 卡点 / imagegen 提示词
│ └─→ Codex imagegen gpt-image-2 自动生图(抽象概念配图)
├─→ audio_cue_sheet.py BGM / SFX 音频设计清单 / 生成审批 gate
├─→ audio_cue_mix.py cue sheet + 最终旁白 → 本地/程序化 SFX 单轨 / 1× review gate
├─→ storyboard_plan.py 分镜 shot cards / 生成路由 / 连续性锚点
├─→ storyboard_animatic.py 每镜静帧 + 可选旁白 → timed MP4 / 1× review / live gate
├─→ photo_montage.py 有序照片 → 轻微缩放/叠化/可选配乐 MP4 + 源绑定收据
├─→ sequence_handoff.py 相邻镜头 receive/handoff / edit type / 轴线方向 / live gate
├─→ reference_story_formula.py
│ 参考片时间码情绪机制 → 目标分镜 content anchors / live gate
├─→ provider_capability.py provider/surface/model 能力合同 / 核验日期 / live gate
├─→ video_prompt_pack.py Dreamina/Veo/LTX/Wan/Sora 提示词包 / 审批 + capability gate
├─→ reference_frame_preflight.py
│ 首帧/style key 尺寸/方向/透明背景/画幅 gate
├─→ generation_task_log.py 异步生成任务台账 / submit_id / 下载 gate
├─→ generated_clip_review.py 生成片段 contact sheet / 常识物理 / 连续性 / 重生 gate
├─→ generation_chain_handoff.py
│ 已审上一镜末帧 → 下一镜精确首帧 / 顺序生成 live gate
├─→ generated_motion_window.py
│ 短生成片 0.25s freeze → active intervals / 人工裁切 / live gate
├─→ scoped_video_edit_review.py
│ 原片 vs 局部 AI 编辑结果 / change-only + preserve invariants / A-B gate
├─→ generated_sequence_review.py
│ 已审片段相邻尾帧/首帧/预览 / 跨镜头连续性 gate
├─→ final_audio_storyboard.py
│ 锁定视觉 EDL + 原 storyboard → 最终声音分镜 / voice ledger / live gate
├─→ narration_loudness_qa.py 最终独立旁白 + 精确短语范围 → LUFS/spread/dBTP/LRA live gate
├─→ caption_speech_qa.py subtitle_pack + 独立人声轨 → 孤立/错位/越界字幕 live gate
├─→ subtitle_glyph_qa.py subtitle_pack + 显式字体 → 逐字符 cmap 覆盖 / 缺字 live gate
├─→ generation_lessons.py 已审片段 → provider/model scoped 提示词经验库
├─→ storyboard_assets.py 素材任务清单 / ready 预检 / paid 额度提醒
│ 可选 media_library.py recommend 排名 B-roll 候选
├─→ stock_material_plan.py 远程 stock 搜索规划
│ Pexels / Pixabay / Coverr 查询计划 + 素材登记提示
├─→ screen_focus.py 录屏点击/热点 → 自动聚焦计划
├─→ pip_overlay.py 录屏 + facecam → PIP 小窗计划
├─→ color_grade.py bounded 调色 plan / render_final 单次编码接入
├─→ lut_grade.py 外部 .cube LUT 校验 / SHA-256 绑定 / 单次编码接入
├─→ jump_cut.py 自适应去停顿 + 20% 删除预算 + 可审计 cut list + 30ms 防爆音 fade
├─→ multimodal_dead_air.py 静音 AND 静帧 → source-bound 保守删段 / 单次编码 / live gate
├─→ audio_transition.py 显式 J-cut/L-cut → source handle / hash / 1× 试听 gate
├─→ edit_revision.py 文本剪辑 artifact → source-bound 审批 / 成组 apply / undo / redo
├─→ edit_recipe.py 已审 render_config → typed-slot 可移植配方 / 新素材绑定回放
├─→ edit_preflight.py render_config/enrich_plan/cut list 渲染前预检 gate
├─→ platform_safe_area_qa.py 字幕/PIP/CTA/marker → 平台 UI 安全区 gate + SVG guide
├─→ subtitle_style_preview.py 真实源帧 → 最终 ASS 预设对比 JPEG / 选择 / live gate
├─→ render_final.py 单次编码渲染(可选口播降噪 + enrich_plan/focus_events/pip_overlays + Heavy 字幕 + 响度规范化 + BGM ducking)
│ 可选 --versioned-output 防覆盖旧成片
├─→ subtitle_render_review.py 最终 MP4 + subtitle_pack → 高风险字幕 1× clips / 原尺寸帧 / 完整审片 live gate
├─→ render_qa.py 渲染后黑屏/静帧/静音/尺寸质检 + review packet
├─→ stream_coverage_qa.py 最终 MP4 → decoded 音视频首尾 PTS / 帧数 / 容器覆盖 live gate
├─→ encode_quality_qa.py 同时间线 master vs 重编码件 → SSIM/PSNR / 最差帧 / live gate
├─→ audio_channel_qa.py 成片声道活动/起始/平衡/相位/mono fold-down live gate
├─→ audio_dropout_qa.py 最终人声/混音短促近静音候选 / 1× WAV 听审 live gate
├─→ flash_safety_qa.py 成片亮度/饱和红 flash → 1s/5s 风险窗口 / live gate
├─→ temporal_artifact_qa.py 单帧/少数帧 return-to-state spike → 三帧证据 / 人工 audit / live gate
├─→ shot_color_qa.py 成片镜头亮度/对比/色度/饱和度/broadcast-range + 切点跳变 gate
├─→ retention_rhythm_qa.py 成片 hook 活动 / 长镜头 / 注意力空窗 / 节奏 gate
├─→ reference_edit_rhythm.py 参考片 vs 成片 hard-cut 结构 / contact sheets / live gate
├─→ speech_continuity_qa.py 成片二次 ASR → 切点复读 / 近重复 take / 句内口吃 gate
├─→ lip_sync_review.py 最终 master → 1×/0.25× 口型证据 / 人工 audit / live gate
├─→ review_proxy.py 低码率完整审片 MP4 / 可见时间码 / faststart
├─→ timeline_view.py 源素材删除段 / 成片输出切点 filmstrip + waveform 复盘图
├─→ edit_compare.py 原片连续时钟 vs 最终像素 / 删段置黑 / 映射验证
├─→ subtitle_pack.py SRT/VTT/ASS/JSON 字幕交付包(speed/offset 对齐)
├─→ soft_subtitles.py 已审 SRT → MP4 可开关字幕轨 / 无损复制音视频 / live 收据
├─→ chapter_mux.py 已审章节 JSON → MP4 可跳转章节 / 无损复制音视频 / live 收据
├─→ metadata_scrub.py 分享前清除 MP4 容器标签/章节/额外轨,保留音视频流
├─→ hls_vod.py 已审 SDR MP4 → 单码率 HLS 点播目录 / 分片+收据 live verify
├─→ subtitle_readability_qa.py
│ 最终字幕 CPS / 时长 / 行长 / 重叠 / 媒体越界 gate
├─→ import_capcut_subtitles.py
│ 剪映/CapCut 自动字幕 → transcript / gap cut list
├─→ srt_edit_plan.py SRT + keep/drop 编辑指令 → render_config / cut list
├─→ project_resume.py 续跑上下文包 / agent handoff / 可选 CLAUDE.md
├─→ review_dashboard.py 静态 HTML/JSON 人工复核面板 / gate review queue
├─→ export_edl.py render_config / cut list → EDL + manifest
├─→ export_fcpxml.py render_config / cut list → FCPXML + manifest
├─→ export_otio.py render_config / cut list → OTIO + manifest
├─→ framing_preview.py master → 各平台 cover/contain/blur 真实帧 / 选择 / live gate
├─→ multi_export.py 已审画幅策略 → 小红书 3:4 / 抖音 9:16 / 视频号 ≤60s
├─→ hdr_sdr.py PQ/HLG HDR → source-bound Rec.709 SDR / 完整解码 gate
├─→ video_enhancement.py Lanczos 放大 + 可选运动补帧 / 全长 A-B + 带声复核 gate
├─→ delivery_encode.py source-bound 两遍 H.264/AAC / 硬大小上限 / 完整解码 gate
├─→ gif_preview.py 视频短摘录 → 调色板 GIF / 源绑定收据 / 完整解码
├─→ logo_overlay.py 已审 MP4 + PNG Logo → 四角叠加 / 源绑定收据 / 完整解码
├─→ generate_caption.py 标题 + 200-500 字正文 + 3-6 tags + 发布时段
├─→ cover_variants.py 2-4 套封面 / feed-size 预览 / 最终选择 gate
├─→ approval_receipt.py 已复核交付件 → SHA-256 收据 / stale approval gate
└─→ publish_package.py 平台视频/封面/字幕/章节/文案上传包 + gate 状态
每天做一条短视频的完整提示词模板:docs/prompts/15-xhs-daily-tech-video.md(推荐入口)。
生图优先使用 Codex 内置 image_gen 工具,即 OpenAI GPT Image 2(gpt-image-2)。
V3 新增脚本一览(按调用顺序)
| スクリプト | 役割 | 主な CLI |
|---|---|---|
project_bootstrap.py | 元素材ディレクトリ → プロジェクト構成/source inventory/project.md | --source raw_dir --project-dir work/day61 `--mode copy |
runtime_preflight.py | workflow profile → ローカルの FFmpeg/Node コマンド、エンコーダー、filters、環境差異の live gate | list-profiles / analyze --profile ... --output --strict / verify --report --strict |
edit_brief_plan.py | 自然言語による編集要件 → ローカルスクリプトの runbook/コマンド/manifest gate | --brief --brief-file --source-media --platform --markdown --strict |
interlace_conform.py | インターレース/telecine の複数区間検出 → bwdif/yadif によるプログレッシブ作業用コピー、全長 A/B の手動確認と live gate | analyze / `plan --mode frame |
frame_rate_conform.py | スマートフォン/画面録画の VFR → decoded PTS cadence、正確な CFR 作業用コピー、フレーム数/音声・映像の開始・終了と live gate | plan <source> --fps 30 --delivery / apply <plan> / verify <plan> --strict |
black_edge_trim.py | 冒頭・末尾の blackdetect と無音の照合 → source-bound CFR working copy、元動画の境界 proof と手動 live gate | plan --delivery --edge-proof / apply / confirm / verify --strict |
program_breaks.py | 内部の黒画面と全音声トラックの無音が重なる区間 → ソースに紐づいた分割候補 JSON/Markdown。自動分割はしません | analyze <video> --output <report.json> / verify <report.json> |
loop_fill.py | プログレッシブ CFR の短い素材 → 回数/目標尺に合わせて反復、最初の実際の継ぎ目の 1× proof、全編レビューと live gate | `plan --times |
ping_pong_loop.py | プログレッシブ CFR の短いアクション → 端点フレームを重複させない正再生/逆再生サイクル、折り返し/ループの両方の proof、キャッシュ上限と live gate | `plan --start --end --cycles |
clip_assembly.py | 複数ソースの動画 → 1 回のキャンバス/CFR/SAR/タイムスタンプ/音声の正規化、全継ぎ目の 1× proof と live gate | plan <clips...> --delivery --boundary-proof / apply / confirm / verify --strict |
podcast_audiogram.py | 音声のみの抜粋+静止画カバー+抜粋内の相対時間に基づく SRT → 補助波形付き縦型 MP4 とソースに紐づいたレシート | render <audio> <cover> <captions.srt> --start --duration --output --receipt / verify <receipt> |
gif_preview.py | 動画の短い抜粋 → 無音、パレット最適化 GIF とソースに紐づいたレシート | render <video> --start --duration --output --receipt / verify <receipt> |
photo_montage.py | 写真 2~100 枚 → 固定テンポ、軽いズーム、ディゾルブ、任意の BGM を含む H.264 MP4。元写真、音楽、完成動画を検証 | render <photos...> --output --receipt [--music] / verify <receipt> |
logo_overlay.py | レビュー済み MP4+PNG ロゴ → 指定した四隅/幅/不透明度で重ね、音声トラックを保持して実際に検証 | render <video> <logo.png> --corner --width-fraction --opacity --margin --output --receipt / verify <receipt> |
frame_grid.py | 秒単位のタイムコードから最も近いデコード済みフレームを特定。視認できるグリッド番号付きの正確なフレームグリッドまたは単一フレーム PNG を、フレーム番号/PTS とソースファイルのレシートとともに出力 | locate <video> --at-seconds / grid <video> --start-frame --step --count --output --receipt / frame <video> --start-frame --output --receipt / verify <receipt> |
border_crop.py | 画面内の上下/左右の黒帯を複数時点でサンプリング。全編と 3 区間で一致した場合のみクロップを推奨 | analyze <video> --output <report.json> / verify <report.json> |
motion_center.py | 検出モデルを使わず、複数時点で局所的な動きの中心を表示。大きく変化する場合は焦点を提示せず、手動の構図確認に利用 | analyze <video> --output <report.json> / verify <report.json> |
edit_style_profile.py | 個人/ブランドのクリエイティブ方針、編集テンポ、レンダリング/コピーのデフォルト値 → パスを含まない移植可能な profile/digest 検証/defaults-only のマージ | template / create --spec / verify --profile --strict / apply --config --receipt |
production_authorization.py | 外部へのアップロード、侵襲的な編集、有料生成、音声クローン、実在人物/IP、公開 → ソースに紐づいた承認 gate | prepare --scope --response-template / audit --request --response --strict / verify --report --strict |
transcript_review.py | transcript → テキストまたはローカル同期メディアの HTML 校正 → レビュー済み transcript | export / html --video --max-cps / apply --review --output |
transcript_lookup.py | 読み取り専用の原文検索または時間範囲の読み取り。有界 JSON、ソース区間 ID/タイムコード、transcript SHA-256 を返します | <transcript.json> search <phrase> --limit / <transcript.json> span --start --end |
visual_transcript_index.py | 既存のキーフレームと近くの文字起こし区間を組み合わせ、検証可能な JSON/Markdown インデックスを作成 | build <keyframes.json> <transcript.json> --output --markdown / verify <index.json> |
tutorial_companion.py | レビュー済みチュートリアルの章+最終動画+タイムコード付き transcript → 各章のスクリーンショットと原文を含む Markdown の補助資料ドラフト、ソースに紐づいたレシート | build <video> <chapters.json> <transcript.json> --title --output [--at ch01=秒] / verify <bundle>/receipt.json |
semantic_transcript_review.py | transcript → 前後の文脈を含む校正パッケージ/最小パッチの監査/手動 choices/レビュー済み transcript | prepare / audit --strict / apply --choices |
_internal_text_guard.py | 内部 token が画面に表示されるのを防止 | 内部モジュール。render_final が自動で呼び出します |
content_guard.py | プラットフォームの禁止事項を lint | --script --title --caption --strict |
source_receipts.py | 事実の claim → URL/スクリーンショット proof deck、Markdown/HTML、公開 gate | --claims source_claims.json --html --require-primary-source --strict |
takes_pack.py | 複数 take/トップレベルの Scribe words → 話者/音声イベントを保持した phrase 単位の Markdown/JSON | --transcript take1=... --transcripts-dir --json --break-gap |
script_alignment.py | レビュー済みの目標原稿 → 複数 take の単語/区間境界候補、手動 choices、render_config、gate | --target-script --transcript label=... --media label=... --choices --render-config --strict |
audio_sync.py | scratch audio+外部録音トラック → offset/音声トラック置換コマンド/gate | --reference-media --external-audio --replace-output --apply --strict |
multicam_sync.py | マルチカメラ → offset/coverage/音声トラック選択/pairwise/任意のクロックドリフト/アラインメントプレビュー gate | --reference-media --angle --manual-offset --measure-clock-drift --preview-output --apply-preview --strict |
multicam_switch.py | ready 状態の同期プラン+speaker-mapped カメラアングルの音声 → ソースに紐づいた自動スイッチング編集のドラフト、全編デコードと手動 live gate | plan --sync-plan --speaker --program-audio --delivery / apply / confirm / verify --strict |
rough_cut.py | transcript に基づくラフカット:口癖/重複した文を削除 | --transcript --cut-list / --input --output |
scene_boundaries.py | FFmpeg の fixed/adaptive scene score → シーン境界+カットの根拠 | --method adaptive --adaptive-threshold --min-scene-score --min-scene-duration |
visual_dedupe.py | 複数ソースのシーンを 3 点の知覚ハッシュで比較 → 重複グループ/保持の推奨/レビュー gate | --manifest / <videos...> --hamming-threshold --include-same-source --strict |
video_understanding.py | サンプリングフレーム+任意の YOLO 物体検出+軽量 tracklets | --detector yolo --scene-boundaries --external-detections --strict |
video_stabilization.py | ソース動画 → 正確な FFmpeg backend/ソースハッシュ/安定化した作業用コピー/全長 A/B レビュー gate | doctor / plan --decision / apply --comparison / confirm / verify --strict |
chroma_key.py | グリーン/ブルースクリーンの前景+画像/動画の背景 → composite/matte プレビュー、4 項目の手動レビュー、ソースに紐づいた完全レンダリング gate | prepare --foreground --background --output-video / review / apply / verify --strict |
highlight_picker.py | 長尺動画のハイライト候補+brief/query による対象クリップ検索 | --transcript --brief/--query --scene-boundaries --render-config |
audio_boundary_snap.py | 選択したハイライト → 単語単位、文末、無音境界の補正+blocker | --candidates --transcript --media --markdown --strict |
shorts_batch.py | highlight_candidates → 複数のショート動画 render_config/レンダリング+QA ジョブシート | --highlights --video --render-config-dir --output-dir --strict |
hook_variants.py | transcript/clean_script → 冒頭 3 秒の hook を 8 つの切り口で作成、リスク確認、推奨順の提示 | --transcript --topic --platform --output --markdown --strict |
rewrite_script.py | LLM による 5 部構成への再編+検証 | --transcript --structure --hook-template --emit-prompt / --llm-output |
auto_broll.py | B-roll のスケジューリング | --transcript --assets --max-single-shot |
media_library.py | ローカル素材ライブラリのインデックス作成+B-roll 候補の推奨+素材ソースの登録 | init scan search recommend --category broll --json import annotate |
stock_material_plan.py | テーマ/原稿 → Pexels/Pixabay/Coverr の stock 検索プラン | --subject --script --provider --media-library --output --markdown |
auto_chapter_cards.py | 章カード PNG | --script --audio --style --output-dir |
auto_stickers.py | 感情 → ステッカー | --transcript --min-interval |
auto_emphasis.py | 疑問文/数字/転換/結論 → badge+控えめな push-in cues | --transcript --output --markdown |
beat_sync.py | BGM → beat edit slots/Markdown レビュー、または既存のカット点にスナップ | --bgm --generate-plan --beats-per-cut 4 --output ... --markdown ... / --cuts --window |
speed_ramp.py | impact ranges → snap/ease/s-curve/hold プラン、digest 検証、ローカルのトランザクション形式の apply | plan <video> --ramp --hold --interpolate-fps / verify --strict / apply --output --receipt |
freeze_punch.py | impact frame → ソースに紐づいた静止画強調、軽い anchor crop、尺/音声を維持した完成動画の live gate | plan <video> --freeze --delivery / apply <plan> / verify --strict |
auto_enrich.py | B-roll/ステッカー/強調箇所/章カード/imagegen cues を編成 | --transcript --clean-script --bgm --output |
imagegen_hint.py | 抽象概念を検出 → gpt-image-2 のプロンプトを生成 | --transcript --clean-script --codex-md |
audio_cue_sheet.py | transcript → BGM/SFX cue、生成承認、音声 gate | --transcript --asset-root --require-local-music --require-local-sfx --strict |
audio_cue_mix.py | audio cue sheet+最終ナレーション → ローカル/プログラム生成 SFX、48 kHz ステレオ単一トラック、全編試聴 live gate | plan --cue-sheet --voice --delivery [--synthesize-missing] / apply / confirm / verify --strict |
final_audio_storyboard.py | locked visual EDL+storyboard → 最終タイムラインの音声絵コンテ、voice ledger、omitted-story の決定、live gate | prepare --edl --storyboard audit --request --response verify --report --strict |
storyboard_plan.py | transcript/clean_script → 絵コンテの shot cards+生成ルーティング | --transcript --clean-script --output --markdown |
reference_story_formula.py | 参考動画+タイムコード付き transcript+目標 storyboard → 感情/物語の仕組み、各ショットの content anchor、模倣を除外する方針、ソースに紐づいた live gate | prepare --reference-video --reference-transcript --target-storyboard --response-template / audit --request --response / verify --report --strict |
storyboard_animatic.py | storyboard+各ショットの静止画+任意のナレーション → ソースに紐づいた時間指定 MP4、全編 1× レビュー、live gate | plan --panel SHOT=PATH --delivery / apply / confirm / verify --strict |
sequence_handoff.py | storyboard → 隣接ショット間の受け渡し、編集境界、180° 軸/方向、音声ブリッジ、編集ハンドル、ソースに紐づいた live gate | prepare --storyboard --response-template audit --request --response verify --report --strict |
provider_capability.py | exact provider/surface/model → 日付付きの mode/画角/尺/解像度/参照上限の能力契約 live gate | verify --bundle --max-age-days --output --markdown --strict |
video_prompt_pack.py | storyboard_plan → 複数 provider 向け動画生成プロンプトパック+レビュー済みの物語公式/境界/実際の最終フレーム受け渡し+キャラクター/ブランド/style lock+有料承認/capability gate | --storyboard-plan --project-dir --reference-story-formula --sequence-handoff --generation-chain-handoff --capability-profile --approved --strict |
reference_frame_preflight.py | video_prompt_pack → 最初のフレーム/style key の存在、デコード、寸法、向き、画角、透明背景の gate | --prompt-pack --require-style-reference --reference shot_id=... --strict |
generation_reference_preflight.py | prompt pack+画像/動画/音声 reference manifest+provider profile → 種類/数/尺/mode/@タグ付き役割のソースに紐づいた gate | template --prompt-pack / analyze --references --capability-profile --strict / verify --report --strict |
generation_task_log.py | 非同期生成タスクの台帳:submit_id/task id、ポーリング、ダウンロード、ローカル保存の gate | add update import-provider-decision report --strict |
generated_clip_review.py | 生成動画クリップのソースに紐づいた視覚レビュー:コンタクトシート、評価、クロップ範囲、再生成の提案 | prepare --clip/--asset-manifest audit --request --response verify --report --strict |
generation_chain_handoff.py | レビュー済み生成クリップ+レビュー済み隣接境界 → 正確な最終フレーム PNG、手動確認、次のショットの exact first-frame live gate | prepare --clip-review --sequence-handoff --boundary / confirm --decision use_exact_start_frame / verify --strict |
generated_motion_window.py | 短い生成クリップの全フレームを freeze → active intervals、手動の trim/keep/reject、フレーム精度の作業用コピーと live gate | analyze <clip> confirm --decision apply --output verify --strict |
scoped_video_edit_review.py | 元動画+局所的な AI 編集結果 → 同じ時間位置の A/B 証拠、変更対象の明確化、保護項目ごとのレビューと live gate | prepare --source --edited --change --preserve audit --request --response verify --report --strict |
generated_sequence_review.py | レビュー済み生成クリップのショット間連続性レビュー:実際の最終フレーム/最初のフレーム、並列画像、無音境界プレビュー、live gate | prepare --clip-review [--storyboard-plan] audit --request --response verify --report --strict |
generation_lessons.py | canonical generated-clip review から明示的に承認された provider/model/category の知見を抽出し、次回の prompt pack 選択に利用 | add --review --clip-id --lesson --approved-by [--supersedes] verify --strict select --provider [--model] |
storyboard_assets.py | storyboard_plan → 素材リスト+ready/paid の事前確認 | --storyboard-plan --asset-root --output --strict |
screen_focus.py | 画面録画のクリック/ホットスポット → フォーカスズームの enrich plan | --events --event --screen-width --output |
pip_overlay.py | 画面録画+facecam → PIP カメラ小窓の enrich plan | --camera --segment --sync-offset --output |
color_grade.py | 範囲制限付きのカラーグレーディング plan+FFmpeg filter+任意の既存 master への再適用 | --preset --output --markdown --render-output --strict |
lut_grade.py | ローカル .cube LUT → FFmpeg で読み込み可能なことを実測し、ファイル SHA-256 に紐づけたカラーグレーディングプラン。レンダリング時に実環境で再確認 | plan <look.cube> --output <plan.json> / verify <plan.json>;render_final.py --color-grade <plan.json> |
jump_cut.py | 適応型の無音検出 → 間を詰めるプラン/削除予算 gate/完成動画+カット点の音声フェード | <input.mp4> --dry-run --cut-list cuts.json --strict / --output jumpcut.mp4 --max-removal-ratio 0.20 --allow-over-budget |
multimodal_dead_air.py | 無音+静止フレームの重なり → ソースに紐づいた無音区間のプラン/live verify/1 回エンコードの作業用コピー | plan --delivery --output --markdown --strict / verify --strict / apply --markdown |
audio_transition.py | render_config → 明示的な J-cut/L-cut source handle/hash/1 回エンコードでの apply/receipt | plan --transition AFTER_CLIP,TYPE,DURATION / apply --output / verify --receipt --strict |
edit_revision.py | render_config/enrich_plan などのテキスト artifact → ソースに紐づいた proposal/独立した承認/一括 apply/undo/redo | prepare --artifact --depends-on / audit --strict / apply --approval / `status |
edit_recipe.py | レビュー済み render_config → typed-slot のパスなしレシピ/digest 検証/新しい素材を割り当てて再生 | export --config --name / verify --recipe / replay --bind SLOT=PATH --receipt --strict |
edit_preflight.py | render_config/enrich_plan/cut list のレンダリング前確認 gate | --config render_config.json --enrich-plan enrich_plan.json --output edit_preflight.json --strict |
platform_safe_area_qa.py | 字幕、badge、PIP、CTA、章カード、marker → プラットフォーム UI による遮蔽の gate+SVG ガイド | --config --enrich-plan --elements `--platform xhs |
subtitle_style_preview.py | 実際のソースフレーム → render_final.py の最終 ASS スタイル比較 JPEG、手動選択、ソース/フォント/スタイルの live gate | create --video --platform --preview-dir --require-selection / select --report --style / verify --strict |
render_final.py | 1 回エンコードのレンダリング+任意の個人スタイルのデフォルト値/話し声のノイズ除去/J-cut/L-cut/enrich_plan/ナレーションに連動した BGM ダッキング | --config render_config.json --style-profile work/edit_style_profile.json --audio-transition-plan audio_transition_plan.json --speech-denoise light --enrich-plan enrich_plan.json --bgm-ducking --output final.mp4 |
subtitle_render_review.py | 最終 MP4+subtitle_pack → リスクの高い字幕の前後を含む clip/中点の原寸フレーム、全編 1× の手動レビュー、ソースに紐づいた live gate | prepare --video --subtitle-pack --proof-dir / audit --request --response --strict / verify --report --strict |
render_qa.py | レンダリング後の QA:寸法/音声/黒画面/静止フレーム/無音+レビュー用パケット | <video.mp4> --platform douyin --json qa.json --review-dir verify/qa |
stream_coverage_qa.py | final MP4 → 全体デコード、最初と最後の PTS、A/V とコンテナのカバレッジ、動画フレーム数のソースに紐づいた live gate | analyze <video> --output --markdown [--expected-duration --expected-video-frames] --strict / verify --report --strict |
encode_quality_qa.py | 同一タイムラインの参照 master と再エンコード版 → 全長 SSIM/PSNR、P05、最低品質フレームのタイムコード、2 入力 live gate | analyze <reference> <candidate> --output --markdown --strict / verify --report --strict |
video_enhancement.py | 既存動画 → ローカル Lanczos アップスケーリング、任意の minterpolate フレーム補間、全長 A/B と音声付き手動レビューの live gate | `plan --target-short-edge |
flash_safety_qa.py | final/platform video → 大面積の輝度/高彩度の赤いフラッシュ、ローリング 1s/5s リスクウィンドウ、ソースに紐づいた live gate | analyze <video> --output --markdown --strict / verify --report --strict |
temporal_artifact_qa.py | final/generated video → 1 フレーム/少数フレームの局所的な変化をスクリーニング、before/suspect/after の証拠と手動判断の live gate | analyze <video> --evidence-dir --response-template --strict / audit --report --response / verify --strict |
shot_color_qa.py | レンダリング済み master → ショットの輝度/コントラスト/色度/彩度/broadcast-range とカット点の急変の gate | <video.mp4> --scene-boundaries --output shot_color_qa.json --markdown --strict |
retention_rhythm_qa.py | 完成動画の hook の動き、長回し、注意の空白、等間隔/高速カット、字幕テンポのリスク | <video.mp4> --timed-text subtitles.json --output retention_rhythm_qa.json --strict |
reference_edit_rhythm.py | 参考動画と完成動画の hard-cut 密度、ショット尺、結尾の hold、正規化したカット点、コンタクトシートによるソースに紐づいた比較 | analyze --reference --candidate --evidence-dir [--require-match] / verify --report --strict |
speech_continuity_qa.py | 完成動画の二次 transcript → 読み直し/近似する take の重複/文中のどもりの gate | <final_transcript.json> --output speech_continuity_qa.json --markdown --strict |
lip_sync_review.py | 最終 master → 全フレーズの 1× 音声付き/0.25× 無音の proof、口の動きの手動 audit、ソースに紐づいた live gate | prepare --video --segment --anchor --proof-dir / audit --request --response --strict / verify --report --strict |
review_proxy.py | master/platform MP4 → 低ビットレートのタイムコード付きレビュー動画+JSON/Markdown | <video.mp4> --output verify/review_proxy.mp4 --dry-run --no-timecode |
audio_master_report.py | 完成動画のラウドネスレポート:LUFS/true peak/LRA/長い無音の gate | <video.mp4> --output audio_master_report.json --markdown audio_master_report.md --strict |
audio_channel_qa.py | 最終 master → チャンネルのアクティビティ、開始位置のずれ、L/R バランス、位相相関、mono fold-down のソースに紐づいた live gate | analyze <media> --output --markdown --strict / verify --report --strict |
audio_dropout_qa.py | 最終ナレーション/ミックス → 20 ms の短い準無音候補、1× WAV 証拠、手動試聴レビュー、ソースに紐づいた live gate | analyze <media> --evidence-dir --response-template --strict / audit --response / verify --strict |
narration_loudness_qa.py | 最終の独立ナレーションにおけるフレーズごとの一貫性:target LUFS/segment spread/true peak/LRA のソースに紐づいた live gate | analyze <media> --segments <json> --output --markdown --strict / verify --report --strict |
caption_speech_qa.py | subtitle_pack cue → 独立した音声アクティビティのカバレッジ、冒頭・末尾の無音、内部の間、タイムライン範囲外のソースに紐づいた live gate | analyze <isolated-speech> --subtitle-pack <json> --output --markdown --strict / verify --report --strict |
subtitle_glyph_qa.py | subtitle_pack+プロジェクト内で明示されたフォント → 文字ごとの Unicode cmap カバレッジ、欠落文字/fallback の一覧、ソースに紐づいた live gate | analyze --subtitle-pack --font [--fallback-font] --output --strict / verify --report --strict |
timeline_view.py | ソース素材の削除区間/完成動画の出力カット点を可視化した確認画像 | <video.mp4> --at 42.5 --output view.png / --rendered-cut-list cuts.json --output-dir verify/ |
edit_compare.py | 元動画の連続した時間軸と完成動画のピクセルを並べて比較。削除区間を黒画面にしてマッピングを検証 | <source.mp4> <final.mp4> --cut-list --output-speed --output-offset --output |
subtitle_pack.py | transcript/render_config → SRT/VTT/ASS/JSON 字幕パック | --transcript work/transcript.json --output-dir output/subtitles / --config render_config.json --speed 1.25 --offset 2.0 |
soft_subtitles.py | レビュー済みで完成動画のタイムラインに合わせた SRT → 表示切り替え可能な mov_text MP4 字幕トラック。元動画/音声ストリームをコピーし、内容とタイムコードを検証 | mux final.mp4 final.srt --language zho --output final-soft.mp4 --receipt soft-subtitles.json / verify soft-subtitles.json |
chapter_markers.py | レビュー済みの章 → JSON、FFmetadata、プラットフォーム用タイムスタンプ、ブラウザーの kind="chapters" WebVTT | --chapters draft.json --duration 720 --output-dir output/chapters --strict |
chapter_mux.py | chapter_markers.py のレビュー済み JSON → MP4 に埋め込み済みの章。映像/音声ストリームをコピーし、章タイトル/時間とストリームハッシュを照合 | mux final.mp4 chapters.json --output final-chapters.mp4 --receipt chapter-mux.json / verify chapter-mux.json |
metadata_scrub.py | 共有用 MP4 からコンテナ/ストリームのタグ、章、追加トラックを削除。映像/音声ストリームをコピーして照合 | scrub final.mp4 --output share.mp4 --receipt metadata-scrub.json / verify metadata-scrub.json |
hls_vod.py | レビュー済み H.264/AAC SDR MP4 → 単一ビットレート VOD index.m3u8+TS セグメント。独立したキーフレーム、フレーム数、全体デコード、ファイルハッシュを照合 | package final.mp4 --output-dir output/hls --receipt verify/hls_vod.json / verify verify/hls_vod.json |
subtitle_readability_qa.py | output-aligned 字幕 → CPS、表示時間、行の長さ、重複、メディア範囲外の gate | <subtitle_pack.json> --media final.mp4 --output subtitle_readability_qa.json --strict |
import_capcut_subtitles.py | 剪映/CapCut の自動字幕または SRT → transcript+gap cut list | --draft <draft_dir> / --srt captions.srt --transcript work/capcut_transcript.json --cut-list work/capcut_gap_cut.json |
srt_edit_plan.py | SRT+手動/エージェントの keep/drop 指示 → edit plan/render_config/cut list | --srt captions.srt --guide edit_guide.md --source-media origin/talking.mp4 --render-config work/render_config.json --strict |
project_resume.py | ローカル artifacts → 再開用コンテキストパッケージ/エージェントへの引き継ぎ | --project-dir work/day58 --markdown work/day58/project_resume.md --agent-note work/day58/CLAUDE.md |
review_dashboard.py | ローカル artifacts → 静的 HTML/JSON のレビューキュー+gate snapshot | --project-dir work/day58 --html work/day58/review_dashboard.html --strict |
export_edl.py | NLE への引き継ぎ:EDL+manifest をエクスポート | --config render_config.json --output edit.edl / --cut-list rough_cut.json --output rough.edl |
export_fcpxml.py | NLE への引き継ぎ:FCPXML+manifest をエクスポート | --config render_config.json --output edit.fcpxml / --cut-list rough_cut.json --output rough.fcpxml |
export_otio.py | NLE への引き継ぎ:OpenTimelineIO .otio+manifest をエクスポート | --config render_config.json --output edit.otio / --cut-list rough_cut.json --output rough.otio |
framing_preview.py | master → 各プラットフォーム向け cover/contain/blur の実フレームプレビュー、手動選択、ソース/filter/preview の live gate | create --video --platforms --require-selection / select --platform --strategy / verify --strict |
multi_export.py | 3 つのプラットフォーム向けにエクスポート。レビュー済みの画角戦略を利用可能 | <input.mp4> --platforms xhs douyin wxch --framing-preview work/framing_preview.json |
hdr_sdr.py | PQ/HLG master → ソースに紐づいた Hable tone-map/BT.709 limited tags/全体デコード gate | plan --delivery / apply / verify --strict |
delivery_encode.py | master → 目標サイズの H.264/AAC MP4/ソースハッシュ/2 パスビットレート/全体デコード gate | plan --delivery --max-size-mib / apply / verify --strict |
generate_caption.py | タイトル/本文/tag | --script --profile --output |
cover_variants.py | 複数パターンのカバー A/B 案、個人スタイルのデフォルト値、フィードサイズのプレビュー、タイトルとの連携、最終選択 | <video> --title --style-profile --caption --platform --render --select cover-c --strict |
approval_receipt.py | レビュー済み動画/カバー/コピー/字幕/QA → SHA-256 レシートと期限切れ承認の gate | create --artifact ... --approved-by / verify --strict |
publish_package.py | 公開アップロードパッケージ:プラットフォーム動画、カバー、字幕、章、コピー、gate 状態 | --project-dir --platforms --video xhs=... --strict |
profiles/__init__.py | 視聴者層のプロファイル読み込み | load_profile("tech_pro") |
V3 の render_final.py フラグを追加
| フラグ | デフォルト | 説明 |
|---|---|---|
--profile tech_pro | オフ | scripts/profiles/tech_pro.yaml のテンポ/字幕/BGM のデフォルト値を読み込みます |
--style-profile work/edit_style_profile.json | オフ | 個人/ブランドの編集スタイルプロファイルを検証し、config 内の不足しているフィールド、または null の制御対象フィールドのみを補完します |
--primary-speed 1.25 | 1.0 | メイン出力の速度です。--speed で追加のバリエーションも引き続き作成できます |
--no-loudnorm | 指定なし = ラウドネス正規化を有効化 | dynaudnorm + acompressor + loudnorm を無効にします |
| `--speech-denoise light | medium | strong` |
--no-content-guard | 指定なし = lint を有効化 | プラットフォームルールのチェックを無効にします(非推奨) |
--subtitle-style karaoke | normal | 単語ごとのカラオケ字幕です |
--enrich-plan work/enrich_plan.json | オフ | 繰り返し指定できます。B-roll/章カード/ステッカー/生成画像/focus_events/pip_overlays を自動的に組み込みます |
--color-grade work/color_grade.json | オフ | color_grade.py の出力またはプリセットを組み込みます。字幕/HUD の前に適用します |
--bgm-ducking | オフ | 最終的なナレーショントラックを使って FFmpeg sidechain をトリガーし、BGM の音量を動的に下げます。--no-bgm-ducking で config の設定を上書きできます |
--versioned-output | オフ | 次の <name>_V<N>.mp4 に出力し、前の完成版が上書きされるのを防ぎます |
V3 Day58 の制作上の教訓(デフォルトの動作に反映済み)
| 教訓 | V3 での解決方法 |
|---|---|
冒頭に 1.25x などの内部トークンが漏れる | _internal_text_guard が自動的に拒否します。ルールは scripts/_internal_text_guard.py にあります |
| 字幕の Hiragino W3 が細すぎる | find_chinese_font() のデフォルト順:Source Han Sans Heavy > Smiley Sans > STHeiti Medium > PingFang Semibold |
| 速度変更後、中盤が聞き取りにくい | render_final はデフォルトで dynaudnorm=f=250:g=15 + acompressor=threshold=-18dB:ratio=3 + loudnorm=I=-16:TP=-1.5:LRA=11 を使用します |
--speed に 1.0× が残ったまま、1.25× をメイン出力にしたい | --primary-speed を第一級のオプションとして追加しました |
| 字幕に Whisper の誤認識語(ChatGPTT など)が入る | rewrite_script.py は清書を優先し、元の Whisper の単語はタイムスタンプにのみ使用します |
| プラットフォームの禁止語が原因で制限されてから違反に気づく | content_guard.py がレンダリング前に自動で lint を実行します |
旧版(V2)の参考資料
以下は V2 時代のワークフロードキュメントです。現在も有効ですが、日常的な使用ではまず docs/prompts/15 を参照することをおすすめします。
前提条件(Prerequisites)
操作を実行する前に、まず環境チェックを実行します。
python3 scripts/utils.py
プラットフォーム(macOS/Linux/WSL/Windows)、GPU の種類、利用可能なエンコーダー、Whisper エンジンを自動検出し、診断レポートを出力します。
前提条件(Prerequisites)
操作を実行する前に、まず環境チェックを実行します。
python3 scripts/utils.py
プラットフォーム(macOS/Linux/WSL/Windows)、GPU の種類、利用可能なエンコーダー、Whisper エンジンを自動検出し、診断レポートを出力します。
依存関係が不足している場合は、ユーザーにインストールを案内します。
- ffmpeg:
brew install ffmpeg(macOS)、apt install ffmpeg(Linux/WSL)、または Windows 版をダウンロード - whisper:
- Apple Silicon (M1/M2/M3/M4):
pip install mlx-whisper(推奨。Metal による高速アクセラレーション) - NVIDIA / CPU:
pip install faster-whisper(推奨。4 倍高速)、またはpip install openai-whisper
- Apple Silicon (M1/M2/M3/M4):
- 中国のユーザー向けの高速インストール(Apple Silicon):
pip install mlx-whisper -i https://pypi.tuna.tsinghua.edu.cn/simpleその他のプラットフォーム:pip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple
プロジェクトのルートディレクトリに .venv 仮想環境がある場合は、Python スクリプトを実行する前に有効化します。
source .venv/bin/activate # macOS/Linux/WSL
# Windows: .venv\Scripts\activate
プラットフォームに関する説明
- macOS (Apple Silicon):VideoToolbox によるハードウェアエンコードアクセラレーションを自動的に使用します。Whisper エンジンは
mlx-whisper(インストール済み)を自動選択します。large-v3-turbo モデル(mlx-community/whisper-large-v3-turboを使用)をおすすめします - 字幕フォント(短尺動画):デフォルトでは Heavy / Medium のウェイトを持つ中国語フォントを優先します。ユーザーライブラリの
Source Han Sans SC Heavy/Smiley Sans> システムのSTHeiti Medium>PingFang SC Semiboldの順です。いずれもない場合は、adobe-fonts/source-han-sans から Heavy ウェイトを自動ダウンロードし、~/.cache/video-editing/fonts/にキャッシュします。Hiragino W3 のような細いフォントをデフォルトで使用することはありません - macOS (Intel):VideoToolbox でエンコードし、Whisper は CPU モードで使用します
- Linux:NVIDIA GPU (NVENC)、Intel QSV、AMD AMF を自動検出します
- WSL:対応しています。Windows のフォントパス(
/mnt/c/Windows/Fonts/)を自動検出します - Windows:WSL2 環境での実行をおすすめします。QSV/AMF ハードウェアエンコードに対応しています
- 専用 GPU なし(統合グラフィックス):Intel iGPU は QSV エンコード、AMD iGPU は AMF エンコードを使用します。Whisper には large ではなく medium モデルをおすすめします
- 中国のユーザー向け:中国地域を自動検出し、モデルのダウンロードには Tsinghua の pip ミラーと HuggingFace ミラーを使用します。
--mirrorパラメーターで強制的に有効化することもできます
Linux GPU 設定ガイド(NVIDIA / Intel Arc)
Linux で GPU アクセラレーションを使って Whisper の音声認識を行う場合、グラフィックスカードによって設定方法が異なります。python3 scripts/utils.py を実行すると、グラフィックスカードのモデルを自動検出して推奨設定を表示します。問題が発生した場合は、以下の方法を参照してください。
方法 A:NVIDIA 40 シリーズのグラフィックスカード(RTX 4060 / 4070 / 4080 / 4090)
40 シリーズ(Ada Lovelace アーキテクチャ、Compute Capability 8.9)は faster-whisper との互換性が最も成熟しており、すぐに使用できます。
インストール手順:
# 1. 安装 NVIDIA 驱动(535+)和 CUDA Toolkit 12.4+
sudo apt install nvidia-driver-535 nvidia-cuda-toolkit
# 或从 NVIDIA 官网安装最新驱动:https://www.nvidia.com/drivers
# 2. 验证 CUDA
nvidia-smi # 应显示驱动版本和 CUDA 版本
# 3. 安装 faster-whisper(自动安装匹配的 CTranslate2)
pip install faster-whisper>=1.1.0
設定の説明:
- CUDA Toolkit:12.4 以上(12.6 推奨)
- CTranslate2:>= 4.5.0(faster-whisper と一緒に自動インストールされます)
- 計算精度:
float16(デフォルト)、int8_float16、int8を使用できます - Whisper モデル:
large-v3を推奨(VRAM >= 6GB) - 特別な設定は不要です。
python3 scripts/transcribe.pyが CUDA を自動検出して使用します
方案 B:NVIDIA 50 系列显卡(RTX 5060 / 5060 Ti / 5070 / 5080 / 5090)
50 系列(Blackwell 架构,Compute Capability 12.0,sm_120)需要额外注意 CUDA 版本和计算精度设置。
已知问题:
CTranslate2 在 Blackwell 架构上使用 INT8 精度时会报错 cuBLAS failed with status CUBLAS_STATUS_NOT_SUPPORTED,
这是因为 Blackwell 的 INT8 Tensor Core 需要矩阵维度为 16 的倍数对齐。CTranslate2 >= 4.7.1 已修复此问题,
但为保险起见,本工具在检测到 50 系列显卡时会自动使用 float16 精度。
安装步骤:
# 1. 安装 NVIDIA 驱动(565+,必须支持 Blackwell)
# 从 NVIDIA 官网下载最新驱动:https://www.nvidia.com/drivers
# 或使用包管理器安装 565 以上版本
sudo apt install nvidia-driver-565
# 2. 安装 CUDA Toolkit 12.8+(Blackwell 最低要求)
# 推荐从 NVIDIA 官网安装:https://developer.nvidia.com/cuda-downloads
# 选择 Linux > x86_64 > Ubuntu > deb (network)
# 3. 验证 CUDA
nvidia-smi # 应显示 CUDA 12.8+
# 4. 安装 faster-whisper 和最新 CTranslate2
pip install faster-whisper>=1.1.0
pip install --upgrade ctranslate2>=4.7.1 # 确保包含 Blackwell 修复
# 5. 如果仍然报错,强制使用 float16 精度(本工具已自动处理)
# 手动测试:
python3 -c "
from faster_whisper import WhisperModel
model = WhisperModel('tiny', device='cuda', compute_type='float16')
print('CUDA float16 OK')
"
配置说明:
- CUDA Toolkit: >= 12.8(推荐 13.0+,最新为 13.2)
- NVIDIA 驱动: >= 565
- CTranslate2: >= 4.7.1(包含 INT8 padding 修复)
- 计算精度: 推荐
float16(最稳定);int8_float16在 CTranslate2 >= 4.7.1 上可能可用 - 如果
int8仍然报错,工具会自动降级到float16 - Whisper 模型: 推荐
large-v3(VRAM >= 6GB) utils.py会自动检测 50 系列显卡(通过nvidia-smi查询 GPU 名称中的 "RTX 50"),并选择安全的float16精度
排错:
如果出现 CUBLAS_STATUS_NOT_SUPPORTED 错误:
- 确认 CTranslate2 版本 >= 4.7.1:
python3 -c "import ctranslate2; print(ctranslate2.__version__)" - 确认 CUDA 版本 >= 12.8:
nvidia-smi或nvcc --version - 尝试手动指定
--compute-type float16(如果直接使用 transcribe.py 的话) - 确认驱动版本 >= 565:
nvidia-smi查看 Driver Version
方案 C:Intel Arc 独立显卡(A770 / A750 / B580)
Intel Arc 显卡不支持 CUDA,因此 faster-whisper(依赖 CTranslate2/CUDA)无法直接在 Intel Arc 上 GPU 加速。 需要使用替代方案。
推荐方案:OpenVINO + Whisper(最易用)
# 1. 安装 OpenVINO
pip install openvino openvino-genai
# 2. 使用 OpenVINO GenAI 的 WhisperPipeline
python3 -c "
import openvino_genai as ov_genai
pipe = ov_genai.WhisperPipeline('OpenVINO/whisper-large-v3-fp16-ov', device='GPU')
result = pipe.generate('audio.wav', language='<|zh|>')
print(result.texts[0])
"
# 3. 或使用 Hugging Face 预转换模型
pip install optimum[openvino]
# 从 HuggingFace 下载 OpenVINO 格式 Whisper 模型
# https://huggingface.co/OpenVINO/whisper-medium-int8-ov
备选方案:whisper.cpp + SYCL(性能更好,配置更复杂)
# 1. 安装 Intel oneAPI Base Toolkit
# https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] \
https://apt.repos.intel.com/oneapi all main" \
| sudo tee /etc/apt/sources.list.d/oneAPI.list
sudo apt update && sudo apt install intel-oneapi-base-toolkit
# 2. 编译 whisper.cpp(启用 SYCL 后端)
source /opt/intel/oneapi/setvars.sh
git clone https://github.com/ggml-org/whisper.cpp.git
cd whisper.cpp
cmake -B build -DWHISPER_SYCL=ON
cmake --build build --config Release
# 3. 下载 Whisper 模型并运行
./build/bin/whisper-cli -m models/ggml-large-v3.bin -f audio.wav -l zh
配置说明:
- Intel Arc 不支持 CUDA,faster-whisper 在 Intel Arc 上只能用 CPU 模式
- OpenVINO 方案最简单,支持 Arc A770/A750/B580 和集成显卡
- whisper.cpp + SYCL 性能更好(A770 上接近 NVIDIA 中端显卡水平),但需要 oneAPI 环境
- B580(Battlemage 架构)的 SYCL 支持尚在优化中,A770 目前更稳定
- 推荐 Whisper 模型:
medium(12GB VRAM 的 A770)或small(8GB VRAM 的 A750) - 如果用户有 Intel Arc 显卡,脚本会自动检测并使用 CPU 模式运行 faster-whisper(作为 fallback)
GPU 配置速查表
| 显卡系列 | 架构 | CUDA Toolkit | 驱动版本 | CTranslate2 | 计算精度 | Whisper 引擎 |
|---|---|---|---|---|---|---|
| RTX 40xx | Ada Lovelace (sm_89) | >= 12.4 | >= 535 | >= 4.5.0 | float16 / int8 均可 | faster-whisper |
| RTX 50xx | Blackwell (sm_120) | >= 12.8 | >= 565 | >= 4.7.1 | float16(推荐) | faster-whisper |
| Intel Arc | Xe HPG / Battlemage | N/A | i915 | N/A | N/A | OpenVINO 或 whisper.cpp+SYCL |
| Intel iGPU | 集成显卡 | N/A | i915 | N/A | int8 (CPU) | faster-whisper (CPU 模式) |
| 无独显 | CPU | N/A | N/A | 任意版本 | int8 (CPU) | faster-whisper (CPU 模式) |
Workflow(工作流程)
Phase 0a: Project Bootstrap(项目启动 / 原始素材导入)
当用户给的是一个原始素材文件夹、下载目录或一组还没整理的素材时,先用 project_bootstrap.py 建立稳定项目结构,而不是直接在外部原始路径上剪辑:
python3 scripts/project_bootstrap.py \
--source ~/Downloads/raw-shoot \
--project-dir work/day61 \
--title "Day61 launch edit" \
--output work/day61/work/source_inventory.json \
--markdown work/day61/work/source_inventory.md \
--project-note work/day61/project.md \
--strict
输出:
origin/raw|broll|audio|bgm|images|assets|sidecars/:项目内 working copy。work/source_inventory.json:project_bootstrap.v1,记录外部source_path、项目内project_path、分类、动作和 next actions。work/source_inventory.md:给人审的素材清单。project.md:跨会话项目记忆。next_steps.md:下一步命令清单。
默认 --mode copy,同名文件自动加后缀,不覆盖。大素材同盘可用 --mode hardlink,失败会回退 copy 并写入 warning。此脚本不转码、不渲染、不上传、不调用 LLM,也不提交任何生成任务。需要把素材导入作为 analysis gate 时,跑:
python3 scripts/pipeline_manifest.py \
--project-dir work/day61 \
--target-stage analysis \
--require source_inventory \
--strict
Phase 0aa: Runtime Preflight(按任务核验本机能力)
在打开媒体或启动渲染前,运行 runtime_preflight.py。只转写、probe 或抽流用 media_io;会编码最终画面的任务用 core_edit,再按需要追加 hls_vod / soft_subtitles / gif_preview / logo_overlay / podcast_audiogram / ping_pong_loop / multicam_switch / video_enhancement / storyboard_animatic / audio_cue_mix / generation_chain_handoff / captions / qa / edge_black_trim / hdr_sdr / stabilization / interlace / remotion:
python3 scripts/runtime_preflight.py analyze \
--profile core_edit \
--profile captions \
--profile qa \
--output work/runtime_preflight.json \
--markdown work/runtime_preflight.md \
--strict
python3 scripts/runtime_preflight.py verify \
--report work/runtime_preflight.json --strict
python3 scripts/pipeline_manifest.py . \
--require runtime_preflight --strict
必须分别对待 missing 和 unknown:前者表示可解析清单中明确没有组件,后者表示版本命令或 FFmpeg listing 失败、超时或不可解析;两者都停止当前 workflow。按 Markdown 的 action 修好环境后重新 analyze,不要手改 JSON。报告会绑定所选 profile、相关命令版本、FFmpeg component states 和 report_id;pipeline_manifest.py 现场复验,环境或报告漂移后旧结果立即失效。
这一步只做 introspection,不运行真实编码、GPU、字体或 provider job。通过后仍要执行项目输入 preflight、真实媒体 probe、完整解码和最终视听 QA。详见 Runtime Preflight。
Phase 0ab: Interlace Conform(旧广播 / DV / DVD 条件 gate)
素材出现梳齿、TFF/BFF、1080i/576i/480i 或 telecine 线索时,先运行 interlace_conform.py analyze。它对头、中、尾执行 FFmpeg idet,分类为 progressive、真实 TFF/BFF 交错、telecine candidate 或 mixed/uncertain。telecine 必须停下来走 IVTC;progressive 保持原样;不确定素材只能在逐帧证据支持下使用 classification override。
确认是真实交错后,用 plan --reviewed-by --note --delivery work/<name>-progressive.mp4 --comparison verify/<name>-interlace-compare.mp4 绑定决定。默认优先 bwdif,yadif 是有 warning 的 fallback;frame 保持帧率,field 保留每个 field 的运动并精确加倍 rate。apply 通过 progressive field flag、live idet、尺寸/帧率/时长/音画起止和完整解码后才提升;随后完整 1× 看 A/B,并对 combing、motion、line detail、field order、audio sync 全部 pass 后 confirm。详见 Interlace Conform。
Phase 0ac: Frame-rate Conform(手机 / 录屏 VFR 可选)
当源素材已知是 VFR、r_frame_rate 与 avg_frame_rate 可疑,或多段裁切后出现累积音画漂移时,先创建项目内 CFR 工作副本:
python3 scripts/frame_rate_conform.py plan origin/phone.mp4 \
--fps 30 \
--delivery work/phone-cfr.mp4 \
--project-dir . \
--output work/frame_rate_conform_plan.json \
--markdown work/frame_rate_conform_plan.md
python3 scripts/frame_rate_conform.py apply work/frame_rate_conform_plan.json
python3 scripts/frame_rate_conform.py verify work/frame_rate_conform_plan.json --strict
脚本读取全部解码视频帧的 PTS 间隔,记录 variable/non-monotonic interval、精确目标有理帧率、源/输出 SHA-256、媒体合同和完整解码 receipt。apply 只有在输出帧间隔恒定、frame_count ≈ duration × fps、音画起止在容差内、显示尺寸/方向正确时才原子提升;之后所有转写、裁切、字幕、同步和渲染改用 work/phone-cfr.mp4。30/60 fps 需按真实运动和平台选择;升帧只复制画面,降帧会丢运动采样。HDR/BT.2020/>8-bit、明显既有音画 offset 或独立设备 clock drift 不在此工具的自动修复范围。详见 Frame-rate Conform。
Phase 0ad: Edge-black Trim(片头 / 片尾黑场可选)
采集卡、相机预录或转码文件的首尾出现黑场时,用 black_edge_trim.py plan 运行 FFmpeg blackdetect;默认还会用 silencedetect 核对确切移除范围至少 95% 为静音,只考虑接触时间线头尾的区间,中间黑场保持不变。
python3 scripts/black_edge_trim.py plan origin/capture.mp4 \
--delivery work/capture-edge-trimmed.mp4 \
--edge-proof verify/capture-edge-proof.mp4 \
--audio-policy silent_only \
--project-dir . \
--output work/black_edge_trim_plan.json \
--markdown work/black_edge_trim_plan.md
python3 scripts/black_edge_trim.py apply work/black_edge_trim_plan.json
脚本保留默认 0.08 秒视觉 padding,对音画执行相同 source-time trim,输出 H.264/yuv420p CFR 与可选 48 kHz AAC;媒体合同和完整解码通过后才原子提升。edge proof 来自原片,包含拟议删除区与紧邻内容。完整 1× 看完 proof 和 delivery,确认首尾帧、内容覆盖与声音连续后运行 confirm,再执行 verify --strict。确知黑画面里的声音也应删除时可显式使用 --audio-policy allow_audible,该 override 保留 warning。详见 Edge-black Trim。
长节目或录制母版需要找内部段落边界时,运行 program_breaks.py analyze <video> --output work/program_breaks.json;它只标出内部 blackdetect 与每条音轨 silencedetect 同时成立的重叠区间,默认取重叠中点作复核时间。用 verify <report.json> 重扫源片并核对 JSON/Markdown。候选不是已批准的切点;逐处正常速度看听后再决定分段,尤其要检查淡入淡出、黑底字幕和有声过场。无音轨素材无法证明静音,会明确拒绝。
Phase 0ae: Loop Fill(短背景 / 环境片填满固定时长)
需要把短视频重复到指定次数或固定 slot 时,用 loop_fill.py plan 绑定 progressive CFR 源片、目标、交付件和首个真实接缝 proof。它保留或显式丢弃源音频,重复时音画一起推进;不自动加 crossfade,也不会把任意首尾包装成无缝循环。
python3 scripts/loop_fill.py plan origin/ambient.mp4 \
--duration 00:30 \
--audio-mode drop \
--delivery work/ambient-30s.mp4 \
--seam-proof verify/ambient-loop-seam.mp4 \
--project-dir . \
--output work/loop_fill_plan.json \
--markdown work/loop_fill_plan.md
python3 scripts/loop_fill.py apply work/loop_fill_plan.json
正常速度看完 seam proof 与完整 delivery;确认画面接缝、运动连续性、重复闪帧、声音接缝和 slot 覆盖后运行 confirm,再用 verify --strict 或 pipeline_manifest.py --require loop_fill_plan --strict 放行。VFR 先跑 frame_rate_conform.py,HDR/BT.2020/>8-bit 先确定 hdr_sdr.py 色彩路径。详见 Loop Fill。
Phase 0af: Ping-pong Loop(短动作正放倒放循环)
手势、产品旋转或生成视频动作的首尾不闭合,又需要往返循环时,用 ping_pong_loop.py。先把动作范围限制在几秒内;FFmpeg reverse 会缓存全部选中帧,planner 会记录保守内存估算并在超过 --max-working-set-mib 时提前停止。
python3 scripts/ping_pong_loop.py plan origin/gesture.mp4 \
--start 1.2 --end 2.05 --cycles 4 \
--delivery work/gesture-ping-pong.mp4 \
--turnaround-proof verify/gesture-turnaround.mp4 \
--loop-seam-proof verify/gesture-loop-seam.mp4 \
--project-dir . \
--output work/ping_pong_loop_plan.json \
--markdown work/ping_pong_loop_plan.md
python3 scripts/ping_pong_loop.py apply work/ping_pong_loop_plan.json
周期使用 0…N-1,N-2…1,主动排除折返点和周期末尾的重复端帧。源音频固定丢弃,视觉批准后再接 BGM/SFX。正常速度看完 turnaround proof、loop-seam proof 和完整 delivery,对折返运动、循环运动、重复停帧、构图与创意意图全部 pass 后运行 confirm,再用 verify --strict 或 pipeline_manifest.py --require ping_pong_loop_plan --strict 放行。详见 Ping-pong Loop。
Phase 0ag: Clip Assembly(多源视频安全拼接)
片头、主片、生成片和片尾来自不同画布、方向、帧率、SAR、时间戳、采样率或声道数时,用 clip_assembly.py 代替 concat copy。按最终播放顺序传入每条唯一源片;同一片重复使用 loop_fill.py。
python3 scripts/clip_assembly.py plan \
origin/intro.mp4 origin/main.mov origin/outro.mp4 \
--width 1080 --height 1920 --fps 30 \
--fit contain --audio-mode fill-silence \
--delivery output/assembled.mp4 \
--boundary-proof verify/clip-assembly-boundaries.mp4 \
--project-dir . \
--output work/clip_assembly_plan.json \
--markdown work/clip_assembly_plan.md
python3 scripts/clip_assembly.py apply work/clip_assembly_plan.json
脚本在一条 FFmpeg filter graph 内统一 PTS、画布、rotation、CFR、SAR 1:1、yuv420p 和 48 kHz stereo,再 hard cut 输出 H.264/AAC。至少一段有音频时,无音轨片段用等长静音保持 A/V coverage;完全不需要声音时用 --audio-mode drop。已有音轨与视频首尾失配或 HDR/BT.2020/>8-bit 会在 plan 阶段停止。
apply 通过总时长、尺寸、帧率、decoded cadence、SAR、音画首尾和完整解码后才原子提升,并从确切交付件生成覆盖所有接缝的正常速度 proof。完整播放 delivery 和 proof 后,对 clip order、visual seams、frame continuity、audio seams、complete coverage 全部做出可观察结论,再 confirm 和 verify --strict。本工具不发明转场或语义连续性;需要 J-cut/L-cut 时走独立 audio transition 计划。详见 Clip Assembly。
Phase 0b: Production Authorization(按确切范围授权)
当流程涉及把素材交给外部服务、改变原始叙事顺序/删减范围、消耗生成额度、克隆真人声音、使用真人/未成年人/公众人物/品牌/IP,或直接发布时,在动作发生前先写 production_authorization_scope.v1。scope 必须命名项目内素材、具体动作、用途、exact provider/surface、可能的 cost/quota,以及适用的 rights subject;完整 schema 见 Production Authorization。
python3 scripts/production_authorization.py prepare \
--project-dir . \
--scope work/production_authorization_scope.json \
--output work/production_authorization_request.json \
--markdown work/production_authorization_request.md \
--response-template work/production_authorization_response.json \
--strict
# 逐项填写 approve/reject、note、rights basis 与 evidence_note 后:
python3 scripts/production_authorization.py audit \
--project-dir . \
--request work/production_authorization_request.json \
--response work/production_authorization_response.json \
--output work/production_authorization.json \
--markdown work/production_authorization.md \
--strict
python3 scripts/production_authorization.py verify \
--project-dir . \
--report work/production_authorization.json \
--strict
prepare 绑定 scope 与每个 source asset 的相对路径、大小和 SHA-256;audit 要求动作与权利项完整逐项决定;verify 现场重读 scope、素材、request、response 并重算 report。任一 provider、用途、成本说明、权利对象、素材字节或决定变化都会让旧报告失效。该 artifact 只记录本地、自报的复核范围,不执行上传/剪辑/生成/发布,也不替代身份认证、数字签名、真实授权文件或法律意见。
Phase 0: Media Library Setup(素材库初始化)
首次使用时,帮助用户建立素材目录结构:
python3 scripts/media_library.py init [project_dir]
这会创建以下目录结构:
media/
├── raw/ — 原始素材(摄像机/手机直出的视频)
├── broll/ — B-roll 素材(城市街景、产品特写等)
├── bgm/ — 背景音乐(MP3/WAV/M4A)
├── assets/ — 叠加素材(水印 PNG、Logo 等)
└── output/ — 输出目录
询问素材来源:
- 询问用户的视频文件位置(本地路径、外部设备或云端)
- 建议将原始素材复制/移动到
media/raw/目录 - 询问是否有 B-roll、BGM 等辅助素材
- 如果用户视频散落在多个目录,建议先集中到
media/raw/
扫描并建立索引:
python3 scripts/media_library.py scan [project_dir]
索引系统会自动:
- 扫描所有视频/音频/图片文件
- 提取时长、分辨率、帧率等元数据
- 关联已有的 transcript 文件
- 小型项目(< 200 文件)使用 JSON 索引(
media_index.json) - 大型项目自动升级为 SQLite 索引(
media_index.db) - 手动升级:
python3 scripts/media_library.py upgrade
查看素材库状态:
python3 scripts/media_library.py status
搜索素材:
python3 scripts/media_library.py search "关键词"
推荐 B-roll 候选:
python3 scripts/media_library.py recommend "AI workflow dashboard" \
--project-dir . \
--category broll \
--target-duration 3 \
--target-aspect 9:16 \
--json
推荐结果包含 score、reasons、absolute_path,用于人工/agent 先确认再写入 render_config 或 enrich_plan。默认过滤已经不存在的索引文件;需要清理 stale index 时可加 --include-missing。
本地素材不足时规划 stock 查询:
python3 scripts/stock_material_plan.py \
--subject "AI workflow automation" \
--script work/transcript.json \
--provider pexels \
--provider pixabay \
--provider coverr \
--media-library . \
--output work/stock_material_plan.json \
--markdown work/stock_material_plan.md
stock_material_plan.py 只生成 stock_material_plan.v1 和 Markdown review,不联网、不下载、不消耗额度。它借鉴 MoneyPrinterTurbo 的 video_terms / Pexels / Pixabay / Coverr / video_count 素材规划方式,但保持本 skill 的 artifact-first 风格。
下载或客户给的素材确认授权后登记:
python3 scripts/media_library.py import /path/to/downloaded.mp4 \
--project-dir . \
--category broll \
--copy \
--provider pexels \
--source-url "https://www.pexels.com/video/demo-123/" \
--creator "Demo Creator" \
--license "Pexels License" \
--tag "workflow,dashboard"
python3 scripts/media_library.py annotate media/broll/downloaded.mp4 \
--project-dir . \
--source-url "https://example.com/source" \
--license "owned" \
--tag "client-approved"
登记后的 provider、source_url、creator、license 会进入 media_index.json/db,后续由 asset_provenance.py 做发布门禁。
Phase 0.25: Creator-owned Edit Style Profile(个人/品牌剪辑风格,可选)
当用户希望多个项目保持同一套创意方向、剪辑节奏、字幕/封面/调色/BGM 习惯和标题拼写时,先生成并人工编辑 spec,再创建可移植 profile:
python3 scripts/edit_style_profile.py template \
--output work/edit_style_profile_spec.json
# 编辑 spec 中的真实偏好和 approval basis 后:
python3 scripts/edit_style_profile.py create \
--spec work/edit_style_profile_spec.json \
--output work/edit_style_profile.json \
--markdown work/edit_style_profile.md \
--strict
python3 scripts/edit_style_profile.py verify \
--profile work/edit_style_profile.json \
--strict
渲染时加 render_final.py --style-profile work/edit_style_profile.json;生成标题文案和封面时,分别给 generate_caption.py 和 cover_variants.py 加同一参数。Profile 只填充 config 中缺失或 null 的受控字段;项目 config 和显式 CLI(包括封面 --style)始终优先。它描述“通常怎么剪”,而 edit_recipe.py 保存“这条时间线怎么复刻”,两者不互相替代。Profile 的 digest 只能发现文件漂移,不是签名、身份认证或权利证明。完整用法见 docs/prompts/98-edit-style-profile.md。
Phase 0.5: Source Receipts(事实来源 proof deck,可选但推荐)
如果视频包含新闻、数据、产品事实、健康/金融/法律判断、来源页截图或“官方说法”,在进入分镜/发布前先把 claim 和证据落成 source receipts:
python3 scripts/source_receipts.py \
--claims work/source_claims.json \
--project-dir . \
--output work/source_receipts.json \
--markdown work/source_receipts.md \
--html work/source_receipts.html \
--require-primary-source \
--strict
source_receipts.py 只验证已提供的 URL 和本地截图/证据文件;不联网抓取、不截图、不上传。source_claims.json 里的 screenshot / source_file 相对 claims JSON 所在目录解析。新闻、数据、金融、健康、法律等高风险 claim 必须有 source_url;需要视觉 proof card 时加 --require-screenshot。发布门禁可用 pipeline_manifest.py --require source_receipts --strict 强制检查,summary.blocking > 0 会阻塞。
Phase 1: Audio Extraction(音频提取)
对每个输入视频文件,使用 extract_audio.py 提取音频:
python3 scripts/extract_audio.py "<video_path>"
输出:与视频同目录下的 <video_name>_audio.wav 文件。
フェーズ 2:音声認識
transcribe.py を使って音声を認識し、タイムスタンプ付きの文ごとのテキストを生成します。
python3 scripts/transcribe.py "<audio_path>" --model auto --language zh --detect-fillers
--model auto:ハードウェアに応じて最適なモデルを自動選択します(NVIDIA GPU → large-v3、Apple Silicon → large-v3-turbo、内蔵グラフィックス → medium、CPU のみ → small)- 手動で指定することもできます:
tiny、base、small、medium、large-v3、large-v3-turbo --engine auto:faster-whisper(推奨)または openai-whisper を自動検出します--mirror:中国のユーザーはミラーソースからモデルをダウンロードします--language:zh(中国語)、en(英語)、ja(日本語)などを指定します。省略すると whisper が自動検出します--silence-threshold 1.0:無音検出のしきい値(秒)。デフォルトは 1.0 です。0 に設定すると無効になります--word-timestamps:単語ごとのタイムスタンプを有効にします(カラオケ字幕に必須)--detect-fillers:フィラー(中国語:嗯/呃/那个/就是说、英語:um/uh/like/you know)を検出し、フィラーのみの区間にスキップ推奨のマークを付けます
出力:音声と同じディレクトリに <video_name>_transcript.json ファイルが生成されます。形式は次のとおりです。
{
"segments": [
{"id": 1, "start": 0.0, "end": 2.5, "text": "大家好"},
{"id": 2, "start": 2.5, "end": 5.1, "text": "今天我们来聊一个话题"}
],
"silences": [
{"start": 15.2, "end": 18.5, "duration": 3.3, "before_segment": 5, "after_segment": 6}
],
"filler_words": [
{"segment_id": 3, "text": "嗯那个", "fillers_found": ["嗯", "那个"], "is_filler_only": true},
{"segment_id": 7, "text": "就是说我觉得这个方案", "fillers_found": ["就是说"], "is_filler_only": false}
]
}
無音検出:transcribe.py は、隣接する音声区間の間隔を自動で分析します。しきい値(デフォルトは 1 秒)を超える間隔は無音としてマークされ、silences フィールドに出力されます。これらの無音は通常、話者の間、言いよどみ、言い間違いです。render_config.json の選択範囲を作成する際は、これらの領域を避けるよう注意してください。
独立した音声トラック、または音楽が継続していないナレーション音声の場合は、元の文字起こしに対して無音の照合も実行します。
python3 scripts/transcript_silence_qa.py analyze origin/talking_audio.wav \
origin/talking_transcript.json --output verify/transcript_silence_qa.json
python3 scripts/transcript_silence_qa.py verify verify/transcript_silence_qa.json
レポートには、区間ごとの実際の無音時間(秒)、割合、ソースファイルのハッシュが記録されます。デフォルトでは -40 dBFS、最短無音時間は 0.15s です。無音の割合が 0.8 に達すると review とマークされます。マークされたタイムコードをもとに音声を聞き直し、文字起こしの校正で修正してください。文字やタイムコードが自動的に削除・変更されることはありません。静かな音声が誤ってマークされることがあり、音楽や環境音が幻覚を覆い隠す場合もあります。verify は再計測を行い、レポートまたは入力の不一致を拒否します。
長い transcript から特定の発言を探す場合は、python3 scripts/transcript_lookup.py work/transcript.json search "製品発売日" --limit 10 を使います。ソース動画の一部のテキストを見る場合は、python3 scripts/transcript_lookup.py work/transcript.json span --start 90 --end 120 を使います。出力は、ソース区間 ID、ソースタイムコード、transcript の SHA-256 を含む、範囲が制限された JSON です。検索では大文字と小文字、空白、句読点が無視され、間隔が 2 秒以内の隣接区間をまたいで検索できます。これは発言の位置を特定するものであり、意味的に類似した内容を推測するものではありません。カット位置と表現は、元のメディアを見直して校正してください。
フェーズ 2a:動画キーフレーム抽出
ナレーション動画(特に屋外を歩きながら撮影した環境音付きの素材)では、音声の文字起こしだけでは動画の視覚的な内容を把握できません。extract_keyframes.py を使って動画のキーフレームを抽出し、内容を包括的に把握できるようタイムライン画像を生成します。
シーン検出、字幕、レビュー用のタイムコードを取得した場合は、まず frame_grid.py locate origin/clip.mp4 --at-seconds 20.4 を実行して、nearest.decoded_frame と前後 2 フレームの実際の PTS を確認します。次に、そのフレーム付近を --start-frame に指定して frame_grid.py grid origin/clip.mp4 --start-frame 240 --step 2 --count 16 --output verify/grid.png --receipt verify/grid.json を実行します。PNG 内の CELL 1 などのマークは JSON の cell に対応しています。対象を見つけたら、frame_grid.py frame origin/clip.mp4 --start-frame 250 --output verify/frame.png --receipt verify/frame.json を実行して正確なフレームを出力します。引き継ぎ前に verify <receipt> を実行して、ソース動画、PNG、対応関係のレシートを確認してください。位置の特定とフレーム抽出はいずれも先頭から順にデコードするため、長い動画の後半を検索するには時間がかかります。グリッドは最大 36 コマで、グリッド画像は通常速度での再生の代わりにはなりません。
python3 scripts/extract_keyframes.py "<video_path>"
パラメーターの説明:
--max-frames 16:キーフレームの最大数(デフォルトは 16)--threshold 0.4:シーン変化検出の感度(0.0~1.0。値が低いほど多くのキーフレームを抽出します。デフォルトは 0.4)--cols 4:タイムライン画像のグリッド列数(デフォルトは 4)--thumb-width 320:サムネイルの幅(デフォルトは 320px)--output-dir:キーフレームの出力先ディレクトリ(デフォルトは<video_name>_keyframes/)--no-storyboard:キーフレームのみを抽出し、タイムライン画像は合成しません
出力:
<video_name>_keyframes/— 各キーフレームの PNG 画像(タイムスタンプ付きのファイル名)<video_name>_storyboard.png— 合成されたタイムライン画像(グリッドレイアウト+タイムスタンプ表示)<video_name>_keyframes.json— キーフレームのメタデータ(タイムスタンプ、フレーム番号、ファイルパス)
キーフレーム抽出が必要な理由:
- ナレーション動画は歩きながら撮影されることが多く、映像内のシーン変化(街路→公園→カフェ)は重要なストーリー上の手がかりです
- タイムライン画像を使うと、AI が音声の内容(transcript)と映像の内容(keyframes)を同時に確認でき、より適切なクリップ選択ができます
- 音声のみの分析では捉えられない情報(身ぶり、表情の変化、環境の切り替わり、製品の紹介など)を見つけられます
代表的なワークフロー:
# 1. 提取音频并转录
python3 scripts/extract_audio.py video.mp4
python3 scripts/transcribe.py video_audio.wav --model auto --language zh --detect-fillers
# 2. 提取关键帧生成时序图
python3 scripts/extract_keyframes.py video.mp4
# 3. 把每帧与前后 3 秒内的原话对齐,查看索引并核验来源
python3 scripts/visual_transcript_index.py build video_keyframes.json video_transcript.json \
--output work/visual_transcript_index.json --markdown work/visual_transcript_index.md
python3 scripts/visual_transcript_index.py verify work/visual_transcript_index.json
インデックスでは、各フレームに最大 8 件の発言を表示し、切り捨てがある場合はその旨を示します。--radius は 0.1~30 秒、--max-segments は 1~12 に設定できます。映像はサンプリングされたフレームで、発言は近傍の時間窓に含まれるものです。これを根拠に、映像内で何かが起きていると断定することはできず、元動画の全編再生の代わりにもなりません。ソース動画、キーフレームのメタデータ、画像、文字起こし、または Markdown に変更を加えた場合は、インデックスを再構築する必要があります。
チュートリアル動画に画像付きの伴走資料が必要な場合は、まず chapter_markers.py が出力した章タイトル、境界、説明を人手で確認してから、tutorial_companion.py build output/master.mp4 output/chapters/chapters.json work/transcript.json --title "教程标题" --output output/companion を実行します。各章ではデフォルトで中間点の画像を 1 枚取得します。中間点がトランジションの場合は、--at ch01=12.5 を指定して、その章内のより適切な時点を選びます。verify output/companion/receipt.json を実行すると、ソース動画、章、文字起こし、スクリーンショット、Markdown のバイト列を確認できます。生成ステータスは、ドラフトが作成されたことだけを示します。各章の画像を確認し、元動画を聞いて、画像がその手順を正確に示しており、説明が証拠を超えていないことを確認してから、外部に提出してください。伴走資料は最大 24 章で、各章に最大 6 件の発言を掲載します。上限を超えた場合は、省略された件数が表示されます。
AI エージェントによる総合分析のポイント:
- キーフレームのタイムライン画像と文字起こしを照合し、各時間帯について「何を話しているか+映像には何が映っているか」を記録します
- 映像と音声が最もよく一致する高品質な区間(例:「この店」と話しているときに、ちょうど店が映っている場面)を探します
- 映像のぼけ、遮蔽、照明不足がある区間を特定し、スキップを提案します
- 屋外で撮影した場合は、手ぶれの激しい区間に注意し、クリップ選択時の優先度を下げます
フェーズ 2a:適応型ビジュアルシーン境界
長い動画を分割したり、サンプリングして内容を把握したり、完成動画のテンポを分析したりする前に、動きのあるショットに適応型シーン境界を生成することを優先してください。
python3 scripts/scene_boundaries.py video.mp4 \
--method adaptive \
--adaptive-threshold 3.0 \
--min-scene-score 0.15 \
--min-scene-duration 1.0 \
--output work/scene_boundaries.json \
--markdown work/scene_boundaries.md
adaptive は各フレームの FFmpeg scene score を前後の近傍の平均値と比較します。これにより、継続するパン、動き、ちらつきによる過剰な分割を抑えられます。boundary_evidence[] には score、adaptive ratio、近傍の平均値が保持されます。必ず先に Markdown を確認してから、highlight_picker.py --scene-boundaries に渡してください。以前のワークフローを再現する場合や、固定カメラの素材を扱う場合は、--method fixed --threshold 0.35 を使います。
Phase 2b: ビジュアル重複排除(素材間の重複ショットの再確認)
複数カメラ、複数テイク、再エンコードの重複、または B-roll 候補をタイムラインに加える前に、visual_dedupe.py を使って複数の source のシーンを3点の知覚ハッシュで再確認します。
python3 scripts/visual_dedupe.py \
--manifest work/visual_dedupe_sources.json \
--output work/visual_dedupe.json \
--markdown work/visual_dedupe.md \
--strict
manifest の sources[] では、各ソースに id、video、任意の scene_boundaries と quality_score を指定します。相対パスの基準は manifest のディレクトリです。スクリプトはデフォルトで異なるソース間のみを比較し、10%/50%/90%のうち少なくとも2つのサンプリング点が一致することを要求します。また、保持候補の提案には quality_score、解像度、ファイルサイズを使用します。出力するのはレビュー用 artifact のみで、ソース素材を削除または移動することはありません。重複グループが見つかった場合は、まず source range を人手で確認してから、下流の edit plan で重複が確認された候補を除外します。
Phase 2c: 動画理解(サンプリングフレーム + オプションの YOLO)
素材内の人物、スマートフォン、PC 画面、製品、車両、その他の動くオブジェクトが、クロップ、プライバシー保護のためのマスキング、または B-roll の選択に影響する場合は、video_understanding.py を使って構造化された視覚理解 artifact を生成します。デフォルトでは detector のインストールは不要です。YOLO を実行する場合は、先にオプションの依存関係 ultralytics をインストールしてください。
検出モデルなしで動きの位置を確認するには、python3 scripts/motion_center.py analyze video.mp4 --output work/motion_center.json を実行し、その後 verify work/motion_center.json で現場の動きを再確認します。レポートではデフォルトの 2 fps で縮小した隣接グレースケールフレームを比較します。local_motion は0~1に正規化された中心を示し、static と global_change では中心を示しません。ピクセルの動きは背景やカメラの移動が原因の場合があるため、人物検出の結果としてそのまま smart_reframe.py --detections に渡すことはできません。まず該当する時間を見返し、そのうえで構図を決めてください。
# 无 detector:只抽样帧并生成 review shell
python3 scripts/video_understanding.py video.mp4 \
--output work/video_understanding.json \
--markdown work/video_understanding.md
# 可选 YOLO:检测对象并生成 detections/tracks/scene_tags
pip install ultralytics
python3 scripts/video_understanding.py video.mp4 \
--scene-boundaries work/scene_boundaries.json \
--detector yolo \
--model yolo11n.pt \
--output work/video_understanding.json \
--markdown work/video_understanding.md \
--strict
出力:
video_understanding.json—video_understanding.v1。frames[]、detections[]、tracks[]、scene_tags[]、warnings[]を含みますvideo_understanding.md— サンプリングフレーム、検出数、トラック、タグ、警告を一覧表示する人手レビュー用の表
一般的な下流処理:
python3 scripts/smart_reframe.py video.mp4 \
--detections work/video_understanding.json \
--platform douyin \
--output work/reframe_douyin.json \
--markdown work/reframe_douyin.md
python3 scripts/privacy_redact.py \
--video video.mp4 \
--detections work/video_understanding.json \
--output work/privacy_redaction.json \
--markdown work/privacy_redaction.md
注意:内蔵の tracklets はトーク動画の編集向けに軽量な関連付けを行うものであり、フレームごとのマルチオブジェクト追跡と同等ではありません。スポーツ、交通量の多い道路、複数人が遮蔽し合う素材など、動きの多い素材には、Ultralytics の model.track(..., tracker="bytetrack.yaml")、BoT-SORT、または Norfair を使用して、より密度の高い検出/track 結果を生成し、同じ detections[]/tracks[] JSON に変換できます。
Phase 2.5: Transcript Review(文字起こしテキストの校正)
文字起こしが完了したら、transcript.json 内のすべてのテキストを必ず1件ずつ確認し、次の2種類の問題を修正してください。
1. 音声認識の誤り(ASR errors): Whisper でよく見られる認識ミスの種類:
- 固有名詞/製品名:例:"opencloud" → "OpenClaw"、"cloudcode" → "Claude Code"、"cloud ops" → "Claude Opus"
- 同音異字の誤り:例:"小红树" → "小红书"、"检映" → "剪映"、"断耕" → "断更"、"懒得讲" → "懒得剪"
- 英語のスペル:例:"scale" → "skill"、"箱子" → "视频"
- 末尾の幻覚:Whisper は無音部分の末尾に意味のない繰り返しテキストを生成することがあります。その場合は直接削除してください
2. 話者の誤りのマーク付け(Speaker errors):
- 繰り返し/言いよどみ:話者が同じ文を繰り返したり、言葉に詰まった後に言い直したりした場合は、スキップ可能としてマークします
- 文字化けした断片:音声が不明瞭なため意味のないテキスト(連続する単独の文字の断片など)として認識された箇所は、スキップ可能としてマークします
専門用語、人名、同音異字、中英混在の発話が多い場合は、まず semantic_transcript_review.py prepare を実行して、現在の Agent/モデルに provider-neutral response を記入させてから、audit を実行してください。モデルの confidence を承認とみなしてはいけません。audit Markdown から source_sha256 + review_id に紐付けられた choices テンプレートをコピーし、各項目を approve/reject してから apply を実行してください。audit はソース transcript から完全な網羅率を導き出し、文全体の推敲、最小限でない文字パッチ、数字/句読点の変更、範囲外/重複するパッチ、古い transcript hash を拒否します。apply が成功したら、以下の同期メディア HTML での聞き取り確認に transcript_semantic_reviewed.json を渡してください。詳しくは docs/prompts/79-semantic-transcript-review.md を参照してください。
python3 scripts/semantic_transcript_review.py prepare \
--transcript work/transcript.json \
--output work/semantic_review_request.json \
--markdown work/semantic_review_request.md
python3 scripts/semantic_transcript_review.py audit \
--transcript work/transcript.json \
--response work/semantic_review_response.json \
--output work/transcript_semantic_review.json \
--markdown work/transcript_semantic_review.md \
--strict
python3 scripts/semantic_transcript_review.py apply \
--transcript work/transcript.json \
--audit work/transcript_semantic_review.json \
--choices work/semantic_review_choices.json \
--output work/transcript_semantic_reviewed.json
校正手順:
transcript_review.py htmlを使って外部依存のないローカルページを生成します。純粋なターミナル環境ではexportを使ってテキストを生成します。- ページ上のタイムコードをクリックして、メディアを再生しながら原稿を校正します。再生中は現在のセグメントが自動的にハイライトされます。行内編集では、ローカルへの自動保存、検索と置換、CPS の黄色表示に対応しています。
transcript_review.txtを明示的に保存してください。ページや agent が元の transcript を直接上書きしないようにしてください。applyを使ってtranscript_reviewed.jsonを生成します。以降の文字起こしの整理、ラフカット、絵コンテ、字幕では、すべてこの reviewed ファイルを使用します。- 言い間違い/文字化けした断片は、セグメント一覧を表示する際(Phase 3)にスキップ推奨としてマークします。
python3 scripts/transcript_review.py html \
--transcript work/transcript.json \
--video origin/talking.mp4 \
--corrections work/corrections.json \
--output work/transcript_review.html \
--max-cps 20
python3 scripts/transcript_review.py apply \
--transcript work/transcript.json \
--review work/transcript_review.txt \
--output work/transcript_reviewed.json
HTML とメディアはローカルでのみ開き、アップロードも LLM の呼び出しも行いません。ブラウザーからファイルに直接書き込めない場合は transcript_review.txt がダウンロードされるため、これを work/ に戻してから apply を実行してください。CPS は事前レンダリングされた目安です。最終的には subtitle_readability_qa.py --strict も実行してください。
注意:字幕のテキストは transcript.json を元にするため、この手順は Phase 5(レンダリング)より前に必ず完了させてください。修正してからレンダリングすることで、最終動画の字幕が正しいことを保証できます。
Phase 2.5a: Target Script Alignment(確認済み原稿に基づく原話の組み立て、任意)
クライアント、ディレクター、またはユーザーが完成版の原稿をすでに承認しており、同じセリフを複数のテイクで録音していたり、異なる素材に分散していたりする場合は、まず目標原稿を「1行につき1つの完全な spoken unit」となるように整理してから、reviewed transcript と照合します。
python3 scripts/script_alignment.py \
--target-script work/target_script.md \
--transcript take-a=work/take-a_transcript_reviewed.json \
--transcript take-b=work/take-b_transcript_reviewed.json \
--media take-a=origin/take-a.mp4 \
--media take-b=origin/take-b.mp4 \
--output work/script_alignment.json \
--markdown work/script_alignment.md \
--render-config work/render_config.json \
--clean-script work/clean_script.md \
--strict
スクリプトはローカルでの字句照合のみを行い、LLM の呼び出し、ソースファイルの変更、表情/ショット/演技の品質判定は行いません。各文について、安定した candidate id、source time、原話、sequence/coverage/ngram/length の evidence を出力します。word timestamps がある場合は単語境界まで優先的に絞り込み、segment のタイムスタンプしかない場合はセグメント全体を保守的に保持します。スコアが低い場合、上位2候補の差が小さい場合、候補がない場合、素材が欠落している場合、またはソース時間が重複して使用されている場合は、summary.blocking に記録し、--strict は 2 を返します。
同じ文言の複数テイクで ambiguous_match が発生した場合は、Markdown 内の候補を見たり聞いたりして確認し、{"choices":{"target-001":"<candidate-id>"}} の形式で確認結果を記述してから、--choices work/script_alignment_choices.json を指定して再実行してください。人手による choice で解決できるのは、字句上の低スコア/複数候補のみです。ファイルの欠落や時間の重複は回避できません。summary.blocking=0 になった後で edit_preflight.py/render_final.py に進んでください。詳しい使い方は docs/prompts/78-script-alignment.md を参照してください。
Phase 2.6: ASR Rough Cut(口头禅/重复句粗剪,可选)
如果 transcript 中纯口头禅、卡壳重说或相邻重复句较多,先用 rough_cut.py 生成可审计粗剪计划:
python3 scripts/rough_cut.py --transcript work/transcript.json --cut-list work/rough_cut.json
确认计划后可直接渲染粗剪版:
python3 scripts/rough_cut.py \
--transcript work/transcript.json \
--input origin/talking.mp4 \
--output output/talking.roughcut.mp4 \
--cut-list work/rough_cut.json
rough_cut.py 会输出 decisions / removed_segments / keep_segments / speedup_ratio。它不调用 LLM,不提交任何付费任务;只用 transcribe.py --detect-fillers 的 filler metadata 和相邻文本相似度做保守粗剪。渲染前用 timeline_view.py --cut-list work/rough_cut.json 看源素材删除段;渲染后用 --rendered-cut-list work/rough_cut.json 看成片实际拼接点。
Phase 2.6b: Multimodal Dead-Air(静音 + 静帧保守去死区,可选)
如果纯音频 jump_cut.py 可能误删仍有表情、手势、产品展示或屏幕操作的停顿,改用音频静音与画面静帧的 AND gate:
python3 scripts/multimodal_dead_air.py plan origin/talking.mp4 \
--delivery work/talking-dead-air-tight.mp4 \
--output work/multimodal_dead_air_plan.json \
--markdown work/multimodal_dead_air_plan.md \
--strict
python3 scripts/multimodal_dead_air.py verify work/multimodal_dead_air_plan.json --strict
DEAD_AIR_CUT_COUNT="$(python3 -c 'import json; print(len(json.load(open("work/multimodal_dead_air_plan.json"))["removed_segments"]))')"
python3 scripts/timeline_view.py origin/talking.mp4 \
--cut-list work/multimodal_dead_air_plan.json \
--output-dir verify/dead-air-cuts \
--limit "$DEAD_AIR_CUT_COUNT"
python3 scripts/multimodal_dead_air.py apply work/multimodal_dead_air_plan.json \
--markdown work/multimodal_dead_air_plan.md
默认只有静帧覆盖静音至少 60% 才入选,并且只删除二者交集;80ms padding、30ms 音频 fade 和 20% 删除预算继续生效。计划绑定源 SHA-256 和媒体契约,apply 使用临时 MP4,并在 H.264/AAC、yuv420p、尺寸、帧率、采样率、声道、时长和完整解码全部通过后原子提升。timeline_view.py 默认只看 20 个切点,因此必须像上面一样把本计划的实际删除段数传给 --limit;若计数为 0,停止并保留原片。它不理解表演、语义或有意留白;所有源切点仍须先看,输出仍须 1× 带声音完整复核。详见 docs/prompts/88-multimodal-dead-air.md。
Phase 3: User Interaction(用户交互)
展示片段列表给用户,格式如下:
视频片段列表:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# | 时间区间 | 内容
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1 | 00:00.0 - 00:02.5 | 大家好
2 | 00:02.5 - 00:05.1 | 今天我们来聊一个话题
3 | 00:05.1 - 00:08.3 | 这个话题非常有意思
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
请选择要合成的片段(示例):
- 连续范围:1-10
- 多个片段:1,3,5,7
- 混合选择:1-4,6,8-10
如果有多个视频文件,分别展示每个视频的片段列表,让用户跨视频选择。
AI 智能选片建议
在展示片段列表时,AI agent 应基于以下维度为每个片段提供推荐评分(1-5 星):
吸引力评分维度:
- Hook 强度(前 3 秒):是否有吸引人的开头(提问、反直觉观点、情感触发)
- 信息密度:每秒传递的有效信息量(避免重复、废话)
- 情感变化:是否有情感起伏(幽默→严肃→惊喜)
- 完整性:片段是否构成完整叙事单元(有开头、展开、收尾)
自动跳过建议:
- transcript 中
is_filler_only: true的片段(纯填充词) - 静音间隙 > 2 秒的相邻片段(卡壳后重说)
- 转录文字与前一片段高度重复的片段(口误重说)
长视频自动拆短片(视频 > 3 分钟时): AI agent 应分析 transcript 识别话题转换点(语义断裂、过渡词如"接下来"、"另外"),将片段按话题分组为独立短视频(每个 30-90 秒),并为每组计算整体吸引力评分:
推荐短视频拆分方案:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
方案 | 片段范围 | 时长 | 主题 | 推荐指数
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
A | #1-#8 | 45s | 痛点引入 | ★★★★★
B | #9-#18 | 62s | 核心方法 | ★★★★☆
C | #19-#25 | 38s | 实操演示 | ★★★☆☆
D | #1-#25 | 2m25s | 完整版 | ★★★★☆
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
等待用户回复选择后,进入 Phase 4。
选择完成后、批量渲染前,建议用词级时间戳校正切点,避免候选范围落在词中间或半句结尾:
python3 scripts/audio_boundary_snap.py \
--candidates work/highlight_candidates.json \
--transcript work/transcript.json \
--media origin/long-talk.mp4 \
--output work/audio_boundary_plan.json \
--markdown work/audio_boundary_plan.md \
--strict
输出 audio_boundary_plan.v1 的 selected[] 可直接传给 shorts_batch.py --highlights。脚本只读本地候选、transcript 和可选媒体;它不渲染、不上传、不调用 provider。--strict 会在缺词级时间戳、非法时间段、源媒体缺失或安全边界超平台时长时返回 2。
Phase 4: Render Config(渲染配置)
根据用户的选择,生成 render_config.json 配置文件。
重要说明:渲染配置是项目级文件
SKILL 中展示的 render_config.json 格式只是模板/参考,不要直接修改 Skill 仓库中的任何文件。每个视频项目应在用户工作目录下创建独立的渲染配置:
# 在用户的视频项目工作目录下创建 script/ 文件夹
mkdir -p script/
# 在 script/ 下为每个视频项目创建独立的渲染配置文件
# 例如:script/render_config.json
目录结构示例:
~/Videos/my-project/ ← 用户工作目录
├── script/ ← 渲染配置目录(每个项目独立)
│ └── render_config.json ← 本项目的渲染配置
├── media/
│ ├── raw/ ← 原始素材
│ ├── broll/
│ └── output/ ← 最终输出
├── *_audio.wav ← 提取的音频
└── *_transcript.json ← 转录文件
渲染配置文件格式(script/render_config.json):
{
"clips": [
{"video": "path/to/video1.MOV", "segment_id": 4, "transcript": "path/to/transcript1.json"},
{"video": "path/to/video1.MOV", "segment_id": 5, "transcript": "path/to/transcript1.json"},
{"video": "path/to/video2.MOV", "segment_id": 1, "transcript": "path/to/transcript2.json",
"broll": "path/to/cityscape.mp4", "broll_start": 5.0}
],
"title": "封面标题文字",
"subtitle": "副标题/情感钩子(可选)",
"cover_style": "news",
"cover_duration": 2.0,
"cover_image": "path/to/custom_cover.png",
"cover_use_frame": false,
"video_overlay": "path/to/overlay.png",
"rec_blink": {
"dot_image": "path/to/dot.png",
"x": 55, "y": 66,
"period": 1.0
},
"end_cards": [
{"text": "感谢观看\n更多内容敬请期待", "duration": 3.5}
],
"bgm": "path/to/background_music.mp3",
"bgm_volume": 0.15,
"bgm_fade_out": 3.0,
"bgm_ducking": true,
"bgm_ducking_threshold": 0.03,
"bgm_ducking_ratio": 8,
"bgm_ducking_attack_ms": 20,
"bgm_ducking_release_ms": 500,
"subtitle_style": "karaoke",
"subtitle_highlight_color": "#FFFF00",
"chapters": [
{"title": "章节名", "start": 0.0, "end": 30.0}
],
"text_badges": [
{"text": "关键结论", "start": 12.0, "end": 13.5}
],
"broll_overlays": [
{"video": "path/to/cityscape.mp4", "start": 8.0, "end": 10.0, "source_start": 2.0}
],
"image_overlays": [
{"image": "path/to/generated.png", "start": 18.0, "end": 21.0, "fit": "cover"}
],
"pip_overlays": [
{"video": "path/to/facecam.mp4", "start": 0.0, "end": 42.0, "position": "bottom_right", "sync_offset": 0.18}
]
}
使用渲染配置:
# 渲染时指定 script/ 下的配置文件
python3 scripts/render_final.py --config script/render_config.json --output media/output/final.mp4
B-roll 替换(broll 字段):
- 在 clip 中添加
"broll": "path/to/video.mp4"可替换该片段的画面,同时保留原始音频 broll_start指定从 B-roll 视频的哪个时间点开始截取(默认 0.0)- B-roll 视频会自动缩放/裁切以匹配主视频分辨率
- 适用场景:屏幕录制口播配城市街景、音频配音配画面等
Auto-Enrich 自动接入(推荐):
- 先运行
auto_enrich.py --output work/enrich_plan.json - 渲染时加
--enrich-plan work/enrich_plan.json broll[].suggested_asset会转成定时 B-roll video overlay;chapter_cards[]、stickers[]和emphasis_cues[]会转成 ASS badge;emphasis_cues[]还可生成无红框的轻微 center push-in;chapter_cards[].png/imagegen[].image_path/imagegen[].generated_path会转成定时图片 overlaypip_overlays[]会转成定时 facecam / camera 小窗;camera audio 默认忽略,主音频仍来自 render config- 没有实际生成文件的 imagegen cue 只作为提示输出,不会阻塞渲染
- 合并后的可见文字仍会走
_internal_text_guard和content_guard.py
Beat Edit Plan 节拍剪辑骨架(音乐视频 / 卡点 montage 可选):
- 运行
beat_sync.py --bgm origin/bgm.mp3 --generate-plan --duration 30 --beats-per-cut 4 --min-segment 0.75 --max-segment 3 --output work/beat_edit_plan.json --markdown work/beat_edit_plan.md - 输出
beat_edit_plan.v1:cut_times[]、program-timesegments[]、逐切点boundary_evidence[]、检测方法和summary - 默认每 4 拍提出一个切点;最短/最长镜头守卫会优先改选附近 beat,实在没有合适 beat 才插入
duration_guard librosa不可用或读取失败时只生成固定 BPM 网格,并把状态标为review;必须听音乐复核,不能把 fallback 当作真实节拍- 计划只定义时间槽,不选择素材、不渲染、不改源文件;确认后再把镜头映射进
render_config/ EDL / OTIO - 已有 cut times 仍使用原命令
beat_sync.py --bgm origin/bgm.mp3 --cuts work/cut_times.json --window 0.2
Speed Ramp 局部慢动作 / velocity edit(动作、产品 reveal、游戏、montage 可选):
- 先逐帧找到 impact frame,再运行
speed_ramp.py plan origin/action.mp4 --ramp 4.6,5.0,1,0.25,s_curve --hold 5.0,5.8,0.25 --ramp 5.8,6.2,0.25,1,ease --interpolate-fps 120 --output work/speed_ramp_plan.json --markdown work/speed_ramp_plan.md verify会重算 plan id、源文件 SHA-256、source/output coverage 和逐段duration / speed;源片或 pieces 漂移立即阻塞apply用同目录临时文件渲染,成功后才替换目标;默认不覆盖、不跟随 output symlink,也不能覆盖 source--interpolate-fps是 FFmpeg motion interpolation,可能产生肢体 / 边缘伪影;极慢音频必须试听,必要时 plan 阶段加--mute-audio- 最终必须用 1×、带声音完整播放;变速后重新生成字幕 / timecoded artifacts、跑 render QA,并重新做最终审批。详见
docs/prompts/83-speed-ramp.md
Freeze-Punch 关键帧定格强调(表情峰值、动作落点、产品揭晓可选):
- 先逐帧确定 impact,再运行
freeze_punch.py plan origin/reaction.mp4 --freeze 4.8,0.8,1.08,0.5,0.42 --delivery work/reaction-freeze-punched.mp4 --output work/freeze_punch_plan.json --markdown work/freeze_punch_plan.md - 它用 impact frame 替换其后的短画面窗口;音频和总时长保持不变,所以不会因本操作漂移字幕、章节或 cue 时间码
- pending plan 会阻塞;读完 Markdown 后运行
apply,再运行verify --strict。apply 只有在 H.264/AAC、yuv420p、尺寸/fps/时长/音轨契约和全长解码通过后才原子提升输出并写回 hash - 必须 1× 带音频检查 freeze 入口/出口、可见说话人冻嘴、动作跳跃、主体裁切和放大软化。源片/plan/成片漂移会让 live gate 失效;旧 QA、approval receipt 和 publish package 必须重做。详见
docs/prompts/101-freeze-punch.md
J-cut / L-cut 声音先行 / 延续转场(访谈、叙事、场景切换可选):
- 只在人工明确选定的边界运行:
audio_transition.py plan work/render_config.json --transition 1,j_cut,0.4 --transition 3,l_cut,0.5 --output work/audio_transition_plan.json --markdown work/audio_transition_plan.md - J-cut 使用下一 clip 入点之前的真实源音频 handle;L-cut 使用上一 clip 出点之后的 handle,并跳过下一 clip 等长的开头音频以恢复同步。handle 不足直接阻塞,不用静音伪造
- 计划绑定 render config、transcript、源片/B-roll SHA-256 和 canonical plan id;
verify会从 live inputs 重新编译,手改 digest 不能隐藏漂移 - 用
audio_transition.py apply ... --output output/master.mp4 --receipt work/audio_transition_apply.json,或给render_final.py加--audio-transition-plan;字幕、overlay、BGM 和错位主音频仍在一次 FFmpeg 编码中完成 - 必须在 1× 用耳机和手机逐个试听改变的边界,确认无吞字、复读、双人声、click、泵动和环境底噪跳变。机器只能验证时序/hash,不能判断交叠对白是否合适。详见 docs/prompts/86-audio-transition.md
Audio Cue Mix 音效 cue 单轨混音(audio_cue_sheet.v1 已审后运行):
- 用最终独立旁白执行
audio_cue_mix.py plan --project-dir . --cue-sheet work/audio_cue_sheet.json --voice work/final_narration.wav --delivery work/audio_cue_mix.wav --output work/audio_cue_mix.json --markdown work/audio_cue_mix.md;本地音效必须位于项目内并绑定 SHA-256/媒体契约 - 缺少
transition_whoosh / emphasis_ping / success_chime / warning_tick时,可显式加--synthesize-missing使用确定性 FFmpeg recipe;未知类别、显式素材丢失、cue 越界或非法增益保持阻塞 apply统一 48 kHz stereo、trim/pad、短 fade、毫秒级adelay和受限增益;amix normalize=0保持旁白电平,limiter 只做峰值保护,完整解码通过后才原子提升输出- 完整 1× 听完后运行
confirm,逐项确认speech_intelligibility / cue_timing / sfx_level / creative_fit / clicks_or_clipping;随后verify --strict。cue sheet、旁白、音效、输出或 review 绑定漂移都会重新阻塞 - 该输出不含 BGM;音乐继续走
render_final.py --bgm-ducking,混入音乐后重新完整试听并运行最终音频 QA。详见 docs/prompts/123-audio-cue-mix.md
Video Stabilization source-bound 手持防抖(仅用于不想要的抖动):
- 先运行
video_stabilization.py doctor。plan --backend auto优先两遍vidstab;缺少该 filter 时会把单遍deshake明确写进计划并保留降级 warning,不会在 apply 时静默换后端 - 原片看过后,用
plan origin/handheld.mp4 --decision stabilize --reviewed-by editor --output work/video_stabilization_plan.json --markdown work/video_stabilization_plan.md记录源 SHA-256、profile 和人工决定;有意手持 / pan 应改用--decision keep apply ... --output work/handheld-stabilized.mp4 --comparison verify/handheld-stabilization-compare.mp4只写新工作副本与全长左/右 A/B;随后必须 1× 看完整 comparison,再运行confirm --reviewed-by ... --note ...pipeline_manifest.py会实时检查源片、稳定版、comparison 的 hash 与复核状态。稳定化不能修复滚动快门、运动模糊或失焦;后续用工作副本,不覆盖origin/。详见docs/prompts/84-video-stabilization.md
Video Enhancement 本地放大 / 补帧交付(现有成片需要更高尺寸或帧率时运行):
- 先跑
runtime_preflight.py analyze --profile video_enhancement ... --strict,再用video_enhancement.py plan output/master.mp4 --target-short-edge 1080 --fps 60 --enhanced output/master-enhanced.mp4 --comparison verify/video-enhancement-ab.mp4 --output work/video_enhancement_plan.json --markdown work/video_enhancement_plan.md --target-short-edge同时适配横竖屏,也可改用--scale 2;只补帧时省略尺寸参数。脚本只接受放大和不低于源 cadence 的目标,源 hash、显示尺寸、目标设置、filter、输出与 review 都进入 canonical planapply用 Lanczos 与可选 FFmpeg motion-compensatedminterpolate,输出 H.264/AAC;尺寸、帧率、时长、音轨存在性和两份 MP4 的完整解码都通过后才原子提升- 完整正常速度看 source-left/enhanced-right A/B,再单独带声看完整增强件;
confirm必须逐项给detail / edges / motion_cadence / audio_sync的pass|fail。任一 fail 继续阻断 - Lanczos 只是确定性 resize,不能恢复源片不存在的细节;补帧可能在切点、遮挡、手、脸和高速运动产生 ghost/warp。需要 ML VSR 或生成式修复时另走经授权工具,并重新执行真实输出复核。详见 docs/prompts/126-video-enhancement.md
Chroma Key 绿幕 / 蓝幕抠像与换背景(仅用于明确纯色幕布):
- 先运行
chroma_key.py prepare --project-dir . --foreground origin/presenter-green.mp4 --background origin/studio.png --output-video output/presenter-studio.mp4 --preview-dir verify/chroma_key --report work/chroma_key.json --markdown work/chroma_key.md prepare在默认 15%/50%/85% 时间点各生成 composite 与黑白 matte;检查头发/手/衣物边缘、主体缺口、绿/蓝溢色和背景透视/光色,必要时只改一项--similarity / --blend / --despill后重新预览- 四项均确认后运行
review --edge-quality pass --subject-integrity pass --spill-control pass --background-fit pass --reviewer ... --note ...,再运行apply --strict和verify --strict - 图片背景保持,视频背景从第一帧循环且忽略其音轨;最终声音只沿用前景。源/背景/预览/filter/output 任一漂移都会让 live gate 失效
- 这不是无幕布 AI matting 或逐帧 roto;复杂透明物、反光、幕布皱褶或主体同色应重拍或交给专业 keyer。完整说明见
docs/prompts/99-chroma-key.md
PIP Overlay 录屏摄像头小窗(录屏教程可选):
- 运行
pip_overlay.py --camera origin/facecam.mp4 --segment "0,18,bottom_right" --segment "18,42,top_right" --sync-offset 0.18 --output work/pip_overlay_plan.json --markdown work/pip_overlay_plan.md - 渲染时追加
--enrich-plan work/pip_overlay_plan.json;可和screen_focus_plan.json、enrich_plan.json重复传入 - 输出
pip_overlay_plan.v1,包含pip_overlays[]、每段位置、source_start、sync offset、尺寸比例、透明度和淡入淡出 render_final.py会随--primary-speed/--speed同步压缩 camera 小窗时间线,避免变速输出时 PIP 和主画面错位
Audio Sync 外录音频自动对齐(相机内录 + 外录麦克风时推荐):
- 运行
audio_sync.py --reference-media origin/camera.mp4 --external-audio origin/lav.wav --output work/audio_sync_plan.json --markdown work/audio_sync_plan.md --replace-output output/camera_lav_synced.mp4 --strict - 输出
audio_sync_plan.v1,包含alignment.offset_seconds、confidence、replace_audio.command、Markdown 复核表和summary.blocking - 正数 offset 表示延迟外录音轨;负数 offset 表示裁掉外录音轨开头
- 确认计划后再加
--apply执行 FFmpeg 替换音轨;脚本会 copy 原视频流、用同步后的外录音轨编码 AAC - 如果自动估计低置信度,可用
--offset 0.18这类手动偏移跳过估计;pipeline_manifest.py会拦截低置信度或缺文件的 audio sync artifact
Multicam Sync 多机位可逆同步计划(两台以上设备录制同一事件时推荐):
- 运行
multicam_sync.py --reference-media origin/cam-a.mp4 --angle origin/cam-b.mp4 --angle origin/cam-c.mp4 --measure-clock-drift --output work/multicam_sync_plan.json --markdown work/multicam_sync_plan.md --preview-output output/verify/multicam_sync_preview.mp4 --apply-preview --strict - 输出
multicam_sync_plan.v1:每路 offset/confidence、自动最响音轨、reference/source coverage、公共 overlap、pairwise 一致性、可选 drift probes/线性 fit 和 preview command - 原片不修改、不重编码;只有
--apply-preview会生成短网格预览。正 offset 表示该机位t=0位于参考时间线更晚的位置 - 多音轨相机可用
--audio-stream "origin/cam-b.mp4=2"指定有效轨;无音轨/人工拍板用--manual-offset "origin/cam-c.mp4=1.24" - 漂移测量默认关闭;启用后默认取 5 个 20 秒窗口,至少 4 个共识 inlier 才拟合
offset(R)=intercept+slope*R,报告明确符号的 ppm、测量分辨率、累计漂移、残差和未应用的atempo/setptsadvisory factors - 漂移证据只覆盖选择的参考/源音轨;不能据此自动断言视频 PTS 或其他音轨共享同一时钟
- 漂移超阈值或拟合不可靠会进入 review gate;脚本不自动校正,音画必须使用同一仿射映射。未启用时,30 分钟以上仍必须复核头/中/尾
- 详细使用与边界见 docs/prompts/76-multicam-sync.md
Audio-guided Multicam Switch 按说话者音频生成导播草稿(同步通过后可选):
- 运行
multicam_switch.py plan --sync-plan work/multicam_sync_plan.json --speaker angle_00_cam-a=主持人 --speaker angle_01_cam-b=嘉宾 --program-audio angle_00_cam-a --delivery output/multicam_switch_draft.mp4 --output work/multicam_switch_plan.json --markdown work/multicam_switch_plan.md --strict - 每路音频分别按 P10 噪声底/P95 峰值归一;只有活动分数和领先 margin 同时达标才换机位,含糊窗口保持上一机位,短于
--min-shot的闪切折回相邻镜头 - 高相关音频默认按共享混音/强串音阻断;
--allow-correlated-audio只保留显式 override warning,不能证明 speaker detection 可靠。广角、节目 master 或没有独立说话者音轨的机位不要映射成 speaker candidate --program-audio指定连续节目声音,不随画面换麦。apply 统一画布/FPS/SAR 后硬切渲染,完成媒体合同与全量解码才提升输出- 完整带声 1× 播放后,confirm 必须逐项记录
speaker_selection / cut_timing / sync / audio_continuity;源、同步计划、设置、输出或 review 漂移都会使 manifest gate 失效 - 详细使用与边界见 docs/prompts/127-multicam-switch.md
Storyboard Plan 分镜与生成路由(生成素材前推荐):
- 运行
storyboard_plan.py --transcript work/transcript.json --clean-script work/clean_script.md --output work/storyboard_plan.json --markdown work/storyboard_plan.md - 输出每个 shot 的时间码、narration、first/motion/last-frame 描述、
codex_imagegen/dreamina_video/remotion_hyperframes/media_library_broll路由、fallback 和 continuity anchors - 使用生成视频 provider 前先运行
provider_capability.py verify --bundle work/provider_capabilities.json --max-age-days 30 --strict,核对 exact UI/API surface、model、mode、画幅、时长、分辨率、参考上限和证据日期 - 可选运行
video_prompt_pack.py --storyboard-plan work/storyboard_plan.json --asset-root work --style-reference work/imagegen/style-key.png --capability-profile work/provider_capabilities.json --require-capability-profile --resolution 720p --output work/video_prompt_pack.json --markdown work/video_prompt_pack.md --strict,把分镜转成 Dreamina/即梦 Seedance、Veo、LTX、Wan、Sora 提示词包、共享 style lock、approval 和 capability gate - image-to-video 提交前运行
reference_frame_preflight.py --prompt-pack work/video_prompt_pack.json --output work/reference_frame_preflight.json --markdown work/reference_frame_preflight.md --require-style-reference --strict,拦截缺失/损坏/方向冲突/严重画幅冲突参考帧 - 再运行
storyboard_assets.py --storyboard-plan work/storyboard_plan.json --asset-root work --media-library . --output work/storyboard_assets.json --markdown work/storyboard_assets.md --strict,渲染前确认素材ready dreamina_video只表示适合视频生成,不会自动提交任务;提交 Dreamina/即梦前必须确认,因为可能消耗 credits- 生图优先使用 Codex 内置
image_gen工具,即 OpenAI GPT Image 2(gpt-image-2)。
Reference Story Formula 参考片故事公式迁移(用户要求借鉴参考片情绪机制时运行):
- 把参考视频和其 timecoded transcript 放进项目,再运行
reference_story_formula.py prepare --project-dir . --reference-video origin/reference.mp4 --reference-transcript origin/reference_transcript.json --target-storyboard work/storyboard_plan.json --output work/reference_story_formula_request.json --markdown work/reference_story_formula_request.md --response-template work/reference_story_formula_response.json --strict - 完整看参考片并填写每个 beat 的
mechanism / viewer_state_before / viewer_state_after / trigger / camera_function / transferable_rule / do_not_copy;每个 reference transcript segment 必须恰好属于一个有序 beat - 为目标 storyboard 的每个 shot 填
beat_id / content_anchor / viewer_shift / surface_change / visual_action,顺序不能倒退;同时明确排除参考片 pixels、audio、wording、branding 和 specific plot - 运行
audit --request ... --response ... --output work/reference_story_formula.json --markdown work/reference_story_formula.md --strict,再执行verify --report work/reference_story_formula.json --strict。输入、response 或派生报告漂移会 fail closed;长原文重合进入可见 warning - 给
video_prompt_pack.py加--reference-story-formula work/reference_story_formula.json。脚本会 live-verify 与当前 storyboard 的 byte binding,并给每条 prompt 注入对应的结构、目标内容锚点和禁止复制合同。它不证明版权、原创度、留存效果或生成质量。详见 docs/prompts/125-reference-story-formula.md
Storyboard Animatic 分镜时长预演(付费生成或正式剪辑前推荐):
- 为每个 storyboard shot 准备一张已审静帧,再运行
storyboard_animatic.py plan --project-dir . --storyboard work/storyboard_plan.json --panel shot_001=work/storyboard/shot_001.png --panel shot_002=work/storyboard/shot_002.png --delivery verify/storyboard_animatic.mp4 --output work/storyboard_animatic.json --markdown work/storyboard_animatic.md --panel SHOT_ID=PATH必须精确覆盖全部 shots;可选加--audio work/narration.wav。工具绑定 storyboard、panels、音频的 SHA-256 和媒体元数据,按 shot starts 生成带镜头 ID/时间码的 CFR H.264 MP4- 执行
apply后完整 1× 播放,检查shot_order / timing_rhythm / panel_legibility / visual_continuity / audio_sync,再运行confirm;无音频时audio_sync=not_applicable verify --strict与pipeline_manifest.py --require storyboard_animatic --strict会现场重读全部输入、完整解码交付件并核对 review/output 绑定。Animatic 只验证静帧顺序和节奏,后续生成片与成片仍需各自 review。详见 docs/prompts/121-storyboard-animatic.md
Sequence Handoff 生成前镜头接力与剪辑边界(两条以上生成镜头时推荐):
- 运行
sequence_handoff.py prepare --project-dir . --storyboard work/storyboard_plan.json --output work/sequence_handoff_request.json --markdown work/sequence_handoff_request.md --response-template work/sequence_handoff_response.json --strict - 逐相邻镜头复核
carrier_type / offer_from / receive_in / edit_type / match_requirement,同时声明 180° 轴、屏幕运动方向、音频桥、头尾 edit handles、风险、fallback 和具体 review note;自动建议只读 storyboard 文本,不能代替人的空间/动作判断 - 用
audit --request work/sequence_handoff_request.json --response work/sequence_handoff_response.json --output work/sequence_handoff.json --markdown work/sequence_handoff.md --strict生成报告,再以verify --report work/sequence_handoff.json --strict现场重算;revise、缺字段、非法轴线/方向翻转、源分镜或决定漂移都 fail closed - 最终 prompt pack 加
--project-dir . --sequence-handoff work/sequence_handoff.json;工具会先 live-verify,再将首镜 handoff-out、末镜 receive-in 和中间镜头的双向合同写进对应 provider prompt - 文本合同不证明最终像素连续;生成后仍执行
generated_clip_review.py和generated_sequence_review.py,组装后正常速度复核所有边界。详见 docs/prompts/120-sequence-handoff.md
Video Prompt Pack + Reference Frame Preflight 视频生成提示词与参考帧门禁(生成视频前推荐):
- 先按 docs/prompts/96-provider-capability.md 建立
provider_capabilities.json,再运行provider_capability.py verify --bundle work/provider_capabilities.json --max-age-days 30 --strict;profile 绑定 exact provider/surface/model 和来源,默认超过 30 天就阻塞 - 运行
video_prompt_pack.py --project-dir . --storyboard-plan work/storyboard_plan.json --sequence-handoff work/sequence_handoff.json --asset-root work --character "same host" --brand-anchor "palette=charcoal,white,signal yellow" --style-reference work/imagegen/style-key.png --capability-profile work/provider_capabilities.json --require-capability-profile --resolution 720p --output work/video_prompt_pack.json --markdown work/video_prompt_pack.md --strict - 输出
global.character_sheet_prompt、global.style_reference、global.sequence_handoff、items[].prompt、items[].sequence_handoff、items[].negative_prompt、items[].surface/model/resolution、items[].capability_profile、items[].capability_issues、items[].approval_status和summary.blocking --style-reference会把同一 style key 绑定到所有 shot,并在每条 provider prompt 加同一条STYLE LOCK- 参考图落盘后运行
reference_frame_preflight.py --prompt-pack work/video_prompt_pack.json --output work/reference_frame_preflight.json --markdown work/reference_frame_preflight.md --require-style-reference --strict reference_frame_preflight.v1检查首帧/style key 是否存在、可解码、方向/画幅是否匹配、分辨率是否过低和透明背景;阻塞项接入pipeline_manifest.py--provider veo|ltx|wan|sora|dreamina_seedance可把同一分镜改写成指定模型提示词;--animate-stills会把codex_imagegen参考图 route 转为 image-to-video 提示词--strict会在 generated-video provider 还没--approved,或 capability profile 缺失/过期/设置越界时返回 2;脚本不提交 provider 任务、不消耗 credits- 生图优先使用 Codex 内置
image_gen工具,即 OpenAI GPT Image 2(gpt-image-2)。
Generation Reference Preflight 图片 / 视频 / 音频生成参考门禁(使用多模态 reference 时必跑):
- provider profile 的
reference_media要记录 frame/reference 是否互斥、是否支持 audio-only、总文件数,以及图片/视频/音频的扩展名、字节、单条时长和总时长上限;未核验的限制不得靠猜测补齐 - 先用
generation_reference_preflight.py template --project-dir . --prompt-pack work/video_prompt_pack.json --output work/generation_references.json建清单;每个实际提交素材填写kind / path / role / exclude,顺序就是各类型的@ImageN / @VideoN / @AudioN顺序 - 运行
generation_reference_preflight.py analyze --project-dir . --prompt-pack work/video_prompt_pack.json --references work/generation_references.json --capability-profile work/provider_capabilities.json --output work/generation_reference_preflight.json --markdown work/generation_reference_preflight.md --strict - 报告会完整解码本地 reference,检查类型、扩展名、大小、单条/合计时长、数量、audio-only、frame/reference 模式互斥和 capability profile 绑定,并输出带明确角色与排除项的
shots[].provider_prompt - 提交时使用 ready 报告里的有序素材清单和
provider_prompt;之后以verify --report ... --strict或pipeline_manifest.py --require generation_reference_preflight --strict现场复查。详见 docs/prompts/122-generation-reference-preflight.md
Generation Task Log 异步生成任务台账(提交生成任务后推荐):
- 从 provider 决策生成待审批台账:
generation_task_log.py import-provider-decision --provider-decision work/provider_decision.json --log work/generation_tasks.json --markdown work/generation_tasks.md --strict - Dreamina/即梦提交后必须保存
submit_id:generation_task_log.py add --log work/generation_tasks.json --provider dreamina --task-id <submit_id> --shot-id shot_002 --expected-path work/generated_video/shot_002.mp4 --status submitted - 下载完成后更新本地文件:
generation_task_log.py update --log work/generation_tasks.json --provider dreamina --task-id <submit_id> --status downloaded --asset-path work/generated_video/shot_002.mp4 --markdown work/generation_tasks.md - 输出
generation_task_log.v1,包含poll_command、download_command、readiness和summary.blocking completed但没有本地asset_path仍会阻塞;pipeline_manifest.py会自动识别generation_tasks.json并把未清零任务列为 gate
Generated Clip Review 生成视频片段复核(生成结果下载后、组装前必跑):
- 先刷新
storyboard_assets.json,再运行generated_clip_review.py prepare --project-dir . --asset-manifest work/storyboard_assets.json --contact-sheet-dir verify/generated_clips --output work/generated_clip_review_request.json --markdown work/generated_clip_review_request.md --response-template work/generated_clip_review_response.json - reviewer 必须完整执行 1× 带声、0.25×、静音看画面、只听声音四遍检查;contact sheet 只是抽样导航,不能代替播放完整片段
- response 对每条 clip 记录 identity/wardrobe、action/end state、motion/anatomy/physics、camera、frame integrity、look consistency 六项 1–5 分,以及 hard-fail code、
keep_ranges/remove_ranges、是否重生和具体prompt_fix pass要求加权分 ≥80 且无删段;pass_with_edits要求 ≥65,并由 keep/remove 精确覆盖全片;常识/物理、身份、道具、文字水印、连续性或音画 hard fail 无论总分多高都必须fail- 填完 response 后运行
generated_clip_review.py audit --request work/generated_clip_review_request.json --response work/generated_clip_review_response.json --output work/generated_clip_review.json --markdown work/generated_clip_review.md --strict;任何 clip/contact sheet 漂移、缺审、非法区间或需重生都会阻塞 - 组装/发布前再运行
generated_clip_review.py verify --report work/generated_clip_review.json --strict,也可用pipeline_manifest.py --require generated_clip_review --strict。reviewer label 不是身份认证或数字签名
Generation Chain Handoff 生成済みクリップの最終フレーム引き継ぎ(同一シーンを連続生成する際に実行):
sequence_handoff.v1で隣接する境界が承認済みで、前のショットのgenerated_clip_review.v1がpassまたはpass_with_editsの場合にのみ使用します。シーン切り替え、時間のジャンプ、意図的なジャンプカット、通常の編集上のマッチでは、無理に引き継がないでくださいgeneration_chain_handoff.py prepare --project-dir . --clip-review work/generated_clip_review.json --sequence-handoff work/sequence_handoff.json --boundary boundary_001 --frame-output work/generation_chain/boundary_001_tail.png --output work/generation_chain_handoff.plan.json --markdown work/generation_chain_handoff.plan.mdを実行します。スクリプトはデコード済みフレームを列挙し、クリップ全体または最後の承認済み keep range から正確な最終フレームを取得します。また、ソースフレームと PNG の RGB24 ピクセルダイジェストが一致することを要求します- 前のショットと PNG を確認したうえで、
confirm --decision use_exact_start_frame --reviewed-by ... --same-scene-confirmed --tail-frame-accepted --original-anchors-preserved --notes ... --output work/generation_chain_handoff.json --strictを実行します。最終フレームが適切でない場合はrejectを使用し、ストーリーボード、生成、または通常の編集境界に戻します - 次のショットを提出する前に
verify --plan work/generation_chain_handoff.json --strictを実行し、video_prompt_pack.pyに--generation-chain-handoff work/generation_chain_handoff.jsonを追加します。対象ショットはimage_to_videoに切り替わり、確認済みの最終フレームが正確な最初のフレームになります。プロンプトには元のキャラクター/製品/スタイルのアンカーを維持し、主な動作を 1 つ、カメラの動きを 1 種類に制限します - 上流レポート、クリップ、承認済み区間、フレームのインデックス/PTS、PNG のバイト列/ピクセル、人による判断、または canonical artifact ID に差異があると処理はブロックされます。新たに生成した各クリップも個別にレビューする必要があります。すべて完了したら、ショット間レビューを実行してください。詳しくは docs/prompts/124-generation-chain-handoff.md を参照してください
Generated Motion Window 生成動画の有効な動作区間(クリップごとの視覚レビュー後、ショット間の組み立て前に実行):
- コンタクトシートでは、0.25~1 秒の静止した冒頭や短時間の動きを見逃すことがあります。視覚レビューに合格した生成クリップごとに
generated_motion_window.py analyze work/generated_video/shot_001.mp4 --project-dir . --output work/generated_motion_window/shot_001.json --markdown work/generated_motion_window/shot_001.mdを実行します - スクリプトはローカルの FFmpeg
freezedetectを使ってfreezes[]とその補集合であるactive_intervals[]を保存し、ソースの SHA-256、メディア契約、パラメーター、canonical plan id を紐付けます。analyze直後はブロック状態です。検出器の提案を承認済みとして扱うことはできません - ソースクリップを 1 倍速で最初から最後まで再生した後、
confirm ... --decision trim|keep|reject --reviewed-by ... --note ...を実行します。trimはデフォルトで提案区間を使用しますが、--start/--endを明示することもできます。両方の境界が active interval 内に収まっている必要があります trimはapplyの前もブロック状態です。apply ... --output work/generated_motion_window/shot_001-active.mp4は、新しい H.264/AAC のyuv420p作業用コピーのみを書き込みます。再生時間/サイズ/fps/音声トラックを検証し、完全にデコードしてからアトミックに昇格します。元のクリップ、計画、検出エビデンス、または出力に差異がある場合は fail closed になります- 新しい作業用コピーは最初から最後まで再生し直し、generated-clip review、sequence/final QA、下流の承認も再実行する必要があります。
pipeline_manifest.py --require generated_motion_window --strictはwork/generated_motion_window/*.jsonを個別に live verify します。FFmpeg の freeze 検出が測定するのは全フレームの類似度のみであり、動作の意味、演技、同一性、物理的な正しさ、製品の品質は判断できません。詳しくは docs/prompts/102-generated-motion-window.md を参照してください
Scoped Video Edit Review 局所 AI 動画編集の範囲レビュー(衣装/背景/パッケージの変更、部分的な VFX などの edit mode の後に必ず実行):
- provider の呼び出しごとに、正確な変更を 1 つだけ指定します。
scoped_video_edit_review.py prepare --project-dir . --source origin/source.mp4 --edited work/scoped_video_edit.mp4 --change-category wardrobe --change "change only the jacket from blue to red" --preserve subject_identity --preserve performance_motion --preserve camera_motion --preserve framing_composition --preserve source_audio --evidence-dir verify/scoped_video_edit --output work/scoped_video_edit_review_request.json --markdown work/scoped_video_edit_review_request.md --response-template work/scoped_video_edit_review_response.jsonを実行します prepareは元のクリップ/編集結果の SHA-256 とメディア契約を紐付け、範囲内の 15%/50%/85% の同時点を並べた JPEG と、左右に並べた全編 H.264 プレビューを生成します。両方の入力に音声トラックがある場合、プレビューではソースと編集結果をそれぞれ独立した音声トラックとして保持します- reviewer は元のクリップと編集結果をそれぞれ 1 倍速で音声付きで最初から最後まで再生し、その後、A/B の範囲プレビュー全体を確認する必要があります。対象の変更と各
--preserveの判定はpass|fail|not_observableのみです。はっきり確認できない場合に推測で pass にしてはいけません audit --strictが ready になるのは、対象の変更が実際に完了し、保護対象のすべてに合格し、3 回の再生確認がすべて揃い、再生時間/サイズ/フレームレートに差異がない場合のみです。失敗時は具体的なrepair_actionを記入する必要があります- 組み立て/公開の前に
verify --report work/scoped_video_edit_review.json --strict、またはpipeline_manifest.py --require scoped_video_edit_review --strictを実行します。スクリプトは provider を呼び出さず、素材をアップロードせず、credits も消費しません。推奨プロンプトは provider に依存しない契約であり、現在使用している surface の機能確認の代わりにはなりません。詳しくはdocs/prompts/100-scoped-video-edit-review.mdを参照してください Generated Sequence Review 跨镜头连续性复核(两条以上生成片段逐片通过后、组装前必跑): - 运行
generated_sequence_review.py prepare --project-dir . --clip-review work/generated_clip_review.json --storyboard-plan work/storyboard_plan.json --evidence-dir verify/generated_sequence --output work/generated_sequence_review_request.json --markdown work/generated_sequence_review_request.md --response-template work/generated_sequence_review_response.json - 脚本按 storyboard 顺序,为每个相邻边界提取批准范围内的上一镜尾帧、下一镜首帧、并排图和“尾部 + 头部”无声 1× preview;如果上游是
pass_with_edits,只使用批准的首个/最后一个 keep range - 完整查看 preview 和 comparison 后,为 identity/wardrobe、prop state、spatial orientation、action end state、camera framing、lighting/palette 填
match|intentional_change|mismatch|not_applicable。至少两项必须真实评估;mismatch必须fail,给 failure code 和具体repair_action - 运行
generated_sequence_review.py audit --request work/generated_sequence_review_request.json --response work/generated_sequence_review_response.json --output work/generated_sequence_review.json --markdown work/generated_sequence_review.md --strict,组装/发布前再verify --report work/generated_sequence_review.json --strict;clip、上游 review、storyboard 或任一 evidence bytes 漂移都会阻塞 pipeline_manifest.py --require generated_clip_review --require generated_sequence_review --strict可把逐片和跨镜头两层都设为门禁。preview 无声,不能替代最终 master 的完整声画复核;reviewer label 和 SHA-256 不是身份认证或签名
Generation Lessons 生成视频经验闭环(可选;只沉淀可泛化且人工明确批准的经验):
- 从已完成的
generated_clip_review.json选定一条 clip,运行generation_lessons.py add --library work/generation_lessons.json --review work/generated_clip_review.json --clip-id shot_002 --category hand_contact --lesson "For hand-to-prop contact, isolate one interaction and keep the hand visible through release." --approved-by "<reviewer-label>" --model seedance-2.0 add会实时重算 canonical review,允许“片段确实需要重生”这一预期 blocker,但拒绝 source/contact-sheet 漂移、漏审、非法 response、stored summary/report-id 篡改;entry 绑定 report/request/clip/contact-sheet SHA-256。approved_by只是审计标签,不是身份认证或签名- 复用前运行
generation_lessons.py verify --library work/generation_lessons.json --strict;按 provider/model/category 预览可用generation_lessons.py select --library work/generation_lessons.json --provider dreamina_seedance --model seedance-2.0 --limit 3 --output work/selected_generation_lessons.json --markdown work/selected_generation_lessons.md - 新证据与旧规则冲突时,不删除旧 entry;新建 lesson 并加
--supersedes <old-lesson-id>。旧 evidence 继续留在 library,但只要新 entry 也匹配当前 provider/model/category,select就排除被替代规则 - 下一次生成提示词包显式加
video_prompt_pack.py ... --lesson-library work/generation_lessons.json --lesson-model seedance-2.0 --lesson-limit 3。provider 专属规则优先,未给--lesson-model时不会误用 model-specific 经验;脚本只追加人工批准的lesson,不会自动把 clip-specificprompt_fix当成通用规则,也不会自动重生或消费 credits - 生图优先使用 Codex 内置
image_gen工具,即 OpenAI GPT Image 2(gpt-image-2)。 - 详细说明见 docs/prompts/89-generated-clip-review.md
Storyboard Assets 素材清单与预检(分镜后、渲染前推荐):
- 运行
storyboard_assets.py --storyboard-plan work/storyboard_plan.json --asset-root work --media-library . --output work/storyboard_assets.json --markdown work/storyboard_assets.md - 输出每个 shot 的素材状态:
ready/candidate_found/needs_generation/needs_approval/needs_render/search_needed - 如果传入
--media-library,media_library_brollshot 会从素材索引里生成candidate_paths+candidate_scores,按 tag、文件名、metadata、时长和画幅透明排名 - 加
--strict时,任何素材未 ready 都会返回退出码 2,适合放在最终渲染前 needs_approval代表 Dreamina/即梦等可能消耗 credits 的任务,必须先确认再提交;生图优先使用 Codex 内置image_gen工具,即 OpenAI GPT Image 2(gpt-image-2)。
自定义封面(cover_image):
- 提供自定义封面 PNG 路径,优先于自动生成的封面
- 尺寸应与视频分辨率匹配(如 1080x1920)
持续叠加层(video_overlay):
- 提供透明 PNG 路径,在封面之后的整个视频上持续叠加显示
- 适用场景:品牌水印、系列标识(如 DAY 标签、数据指标)等
- PNG 必须包含 Alpha 通道(RGBA),透明区域不会遮挡视频
闪烁圆点(rec_blink):
- 在视频上叠加一个周期性闪烁的小圆点 PNG(如录像机 REC 标志)
dot_image:圆点 PNG 路径(建议 12-16px,RGBA 格式)x,y:圆点在视频画面中的像素坐标period:闪烁周期(秒),默认 1.0(0.5 秒亮 + 0.5 秒灭)
结尾卡片(end_cards):
- 在视频末尾追加黑屏文字卡片,每张卡片有 300ms 淡入淡出
text:卡片文字内容,用\n换行duration:每张卡片显示时长(秒),建议 3.0-4.0- 文字居中显示,字号为正文字幕的 1.4 倍
口播稳态底噪清理(speech_denoise):
- 默认
off;只有空调、风扇、电流声、轻微房间底噪相对稳定时才启用"light"/"medium"/"strong" - CLI 可用
--speech-denoise light;配置已开启时可用--no-speech-denoise临时关闭 - 三档固定 80 Hz、2-pole 高通,FFT reduction 为 6/9/12 dB;
strong不会超过 12 dB - 顺序固定为
highpass → afftdn → atempo → dynaudnorm → acompressor → loudnorm → cover delay → BGM ducking/mix - 已做 VAD/noise gate、Adobe Podcast、Descript、RX 或机内强降噪的音轨通常保持 off;数字静音、噪声突变、多麦、瞬态敲击/咳嗽和混响必须另行处理
- 先渲染 10–20 秒 off/light/medium A/B,戴耳机正常速度试听辅音、尾音和停顿;渲染后继续运行
audio_master_report.py --strict
背景音乐(bgm):
- 提供背景音乐文件路径(MP3/M4A/WAV 等 FFmpeg 支持的格式)
bgm_volume:BGM 音量(0.0-1.0),默认 0.15(人声为主,BGM 为辅)bgm_fade_out:结尾淡出时长(秒),默认 3.0bgm_ducking: true或 CLI--bgm-ducking:用最终旁白轨作为 sidechain,旁白出现时自动压低 BGM;封面、停顿和片尾无旁白时音乐会自然恢复- 默认 ducking 参数是 threshold
0.03、ratio8、attack20ms、release500ms;只有试听或audio_master_report.py证据表明需要时才调整 - ducking 分支用
amix normalize=0保留人声响度,并在混音末尾加alimiter=0.95防止峰值溢出;旧配置默认仍关闭,保持已有输出兼容 - BGM 自动循环播放直到视频结束,不需要预先剪辑长度
- 推荐免费可商用音乐源:Pixabay Music、Mixkit、YouTube Audio Library
- 选曲建议:口播/教程用轻柔纯音乐(无人声),节奏不要太强,避免抢人声
字幕风格预设(subtitle_style):
| 风格 | 效果 | 适用场景 |
|---|---|---|
normal | 白字黑描边(默认) | 适合所有场景 |
karaoke | 逐词高亮 | 音乐/节奏感内容 |
bold_pop | 粗描边高对比 | MrBeast/Hormozi 风格 |
pop_in | 每条字幕入场缩放后回弹 | 节奏较快的短视频;短于 0.3 秒的字幕保持静态 |
neon | 霓虹灯青紫色 | 科技/潮流内容 |
minimal | 极简无描边 | 文艺/安静内容 |
yellow_pop | 黄字黑描边 | 高可见度,户外/嘈杂画面 |
卡拉OK字幕 / 逐词高亮(subtitle_style: "karaoke"):
- 在 config 中设置
"subtitle_style": "karaoke"启用逐词高亮字幕 - 需要先用
--word-timestamps参数进行语音识别,获取逐词时间戳 subtitle_highlight_color:当前词高亮颜色,默认"#FFFF00"(黄色)subtitle_base_color:未说到的词底色,默认"#FFFFFF"(白色)subtitle_base_alpha:底色透明度 hex,默认"80"(半透明)- 如果 transcript 中没有 word 级时间戳,会自动回退到按字符均匀分布(效果稍差)
- 也可通过 CLI 参数
--subtitle-style karaoke覆盖 config - 典型工作流:
# 1. 转录时开启逐词时间戳 python3 scripts/transcribe.py audio.wav --model auto --language zh --word-timestamps # 2. 渲染时选择 karaoke 字幕风格 python3 scripts/render_final.py --config render_config.json --output final.mp4 --subtitle-style karaoke
逐条弹入字幕(subtitle_style: "pop_in"):用 render_final.py --subtitle-style pop_in,或在 render config 中设 "subtitle_style": "pop_in"。每条字幕按成片速度后的时长独立做 80% → 108% → 100% 缩放;短于 0.3 秒的字幕直接全尺寸显示。subtitle_style_preview.py --styles pop_in 的静帧只能检查最终字形、位置和对比度,须在最终 MP4 中按正常速度检查入场动画及安全区。
音频源替代(M4A/独立音频):
- 如果有独立录制的音频文件(M4A 等),可先用 ffmpeg 转为带黑屏视频轨的 MP4:
ffmpeg -f lavfi -i "color=c=black:s=1080x1920:r=30:d=60" -i audio.m4a -c:v libx264 -c:a aac -shortest audio.mp4 - 然后在 clip 中用
"video": "audio.mp4"提供音频源,用"broll"提供画面 - 这样可以将补录的配音与任意画面组合
封面标题:
- 如果用户提供了标题,直接使用。
- 如果用户没有特别要求,站在观众角度总结一个吸引人的标题(6-15 个字)。
subtitle可选,用于补充情感钩子或关键信息。- 移动端优先:封面在手机列表页里只是一个缩略图,标题必须先保证可读性,再考虑画面细节。
封面文字排版规则:
- 标题按一行最多约 8 个汉字来设计;超过时自动换行,不要把单行塞得过满。
- 英文/数字按约半个汉字宽度估算;例如
AI、GPT-5之类不应把整行宽度挤爆。 subtitle字号默认按标题的约 50% 处理,只承担补充信息,不和主标题争抢视觉中心。- 如果标题超过两行,优先缩短文案,不要继续缩小字号来硬塞。
- 做教程/工具类封面时,主标题尽量控制在 4-8 个字,副标题控制在 6-12 个字。
封面风格(cover_style)— 根据视频内容选择最合适的风格:
| 风格 | 适用场景 | 视觉效果 |
|---|---|---|
bold | 教程、科普、技术 | 黑底 + 大号白色粗体字,简洁有力 |
news | 热点、观点、争议 | 深色渐变底 + 白色标题 + 黄色副标题,冲击力强 |
frame | Vlog、实拍、场景 | 视频首帧做背景 + 暗色遮罩 + 描边白字 |
gradient | 生活、情感、艺术 | 紫粉渐变底 + 发光白字,温柔优雅 |
minimal | 思考、文化、深度 | 纯黑底 + 细体白字,极简克制 |
white | 教程、产品、品牌化内容 | 纯白底 + 深色字,现代感更强 |
techcard | 屏幕录制、软件教程、AI 工具演示 | 左侧大标题 + 右侧画面卡片,兼顾信息量和可读性 |
AI agent 应根据视频主题和内容语气自动选择:
- 科技/工具类 →
bold或news - 争议/观点类 →
news(白标题+黄副标题效果最抢眼) - Vlog/实拍类 →
frame - 情感/生活类 →
gradient - 深度/文化类 →
minimal - 纯桌面录屏 / 软件教程 →
techcard优先;如果画面太杂,就退回bold/white
背景取帧规则:
- 不要机械地使用第一帧。对于录屏教程,优先选择信息密度更高、界面更完整的一帧做背景或卡片图。
- 如果背景画面会影响标题识别,优先使用
bold/white/minimal这类纯底风格。 - 单独预览封面时,可用
scripts/generate_cover_image.py --frame-timestamp 00:10:00指定取帧时间。
多封面 A/B 方案与最终选择:
python3 scripts/cover_variants.py output/final_xhs.mp4 \
--title "20分钟出片" \
--subtitle "AI剪辑完整流程" \
--caption output/caption.json \
--platform xhs \
--frame-timestamp 12.5 \
--output-dir output/covers \
--render \
--output work/cover_variants.json \
--markdown work/cover_variants.md
デフォルトでは 3 種類の案と *_preview.png のサムネイルを生成します。まず feed-size のプレビューを見比べてから、再実行時に --select cover-c --require-selection --strict を追加し、最終的なカバーを記録します。タイトルはテーマ/キーワードを担い、カバーは結果/感情/対比/証拠を担います。重複を確実に避ける必要がある場合は、--require-distinct-cover-text を追加します。pipeline_manifest.py --require cover_variants を使うと、選択を公開ゲートに設定できます。カバーの背景画像を AI で生成または編集する必要がある場合は、画像生成には Codex 内蔵の image_gen ツール、つまり OpenAI GPT Image 2(gpt-image-2)を優先して使用します。
カバーの表示時間(cover_duration):
- デフォルトは 2.0 秒で、最初のフレームを静止させてカバーを重ねます
--cover-durationコマンドライン引数でも上書きできます
章分け:
- 動画の内容に沿って章を分けます。4 章以内を推奨します
- 章名は簡潔に(2~4 文字)します。例:課題、原因、解決策、ツール
- 章の時間は、選択したクリップの累積時間に基づいて正確に計算する必要があります
Phase 4.8: 編集リビジョン(編集 artifact の可逆的な修正、任意)
ユーザーが render_config.json、enrich_plan.json、caption、または字幕 sidecar の変更を求め、完全なレビュー、依存関係のドリフト防止、undo/redo も必要な場合は、まず proposal を準備します:
python3 scripts/edit_revision.py prepare \
--project-dir . \
--artifact work/render_config.json \
--artifact work/enrich_plan.json \
--depends-on work/transcript_reviewed.json \
--title "收紧开头并调整 B-roll" \
--reason "已完成时间码审片,采用第二版开头。" \
--output work/edit_revision_proposal.json
proposal の artifacts[].proposed_content のみを変更し、その後 audit を実行します。--strict で合法な audit の pending_approval が 2 を返すのは、想定どおりの人手によるゲートです。apply で複数のファイルを 1 つの revision としてまとめて書き込み、work/edit_revision_history.json を作成するには、同じ review_id に紐づく decision: approve と空でない approved_by_label を含む approval JSON を別途保存する必要があります。実行時に書き込みエラーが発生した場合は、旧 bytes の復元を試みますが、ファイルをまたぐ OS レベルのアトミックなコミットは保証されません。プロセス異常の後は、まず status --strict を実行してください。status は artifact、適用済み dependency、content-addressed before/after blobs をリアルタイムで検査します。外部からの直接編集、依存関係のドリフト、symlink、blob の破損がある場合は、undo/redo を拒否します。元のメディア、コード、出力動画、verify/ は管理対象外です。詳しい手順は docs/prompts/80-edit-revision.md を参照してください。
Phase 4.85: Portable Edit Recipe(可搬型編集レシピ、任意)
レビュー済みの render_config.json をテンプレートとして保存する場合、または別の素材一式で同じタイムライン/字幕/BGM/overlay 構成を再現する場合は、まずパスを含まない recipe をエクスポートします:
python3 scripts/edit_recipe.py export \
--config work/render_config.json \
--name fast-tech-explainer \
--description "快节奏科技口播" \
--output work/recipes/fast-tech-explainer_edit_recipe.json \
--markdown work/recipes/fast-tech-explainer_edit_recipe.md
エクスポート前に、source preflight に合格する必要があります。ローカルファイルへの参照は typed slots に置き換えられ、同じパスは 1 つのスロットだけを使用し、recipe に元のパスは保存されません。新しいプロジェクトでは Markdown のスロット表を開き、各スロットに対して --bind SLOT=PATH を 1 回ずつ指定して replay を実行し、同時に --receipt と --markdown も指定します。スクリプトは portable digest、スロットの集合、ファイルの種類と存在を検証し、新しい binding hash を記録して、出力された config に対して preflight を再実行します。デフォルトでは上書きしません。対象が正しいことを明示的に確認した場合に限り、--force を追加してください。recipe hash は署名でも人手による承認でもありません。再生後も、レンダリングして完成動画を最初から最後まで確認する必要があります。詳しい手順は docs/prompts/82-edit-recipe.md を参照してください。
Phase 4.9: Platform Safe Area QA(プラットフォーム UI セーフエリアのゲート)
レンダリングまたは複数プラットフォームへのエクスポート前に、対象プラットフォームごとに、字幕、強調 badge、PIP の人物、CTA、章カード、クリック marker が、上部のステータスバー、下部の説明文エリア、右側のアクションボタン欄に入り込まないかを確認します:
python3 scripts/platform_safe_area_qa.py \
--config work/render_config.json \
--enrich-plan work/enrich_plan.json \
--platform xhs \
--output verify/xhs_platform_safe_area_qa.json \
--markdown verify/xhs_platform_safe_area_qa.md \
--guide verify/xhs_platform_safe_area_guide.svg \
--strict
Douyin と WeChat Channels の派生版では、それぞれ --platform douyin/--platform wxch を指定します。スクリプトは render_final.py のデフォルトの ASS、PIP、focus-marker のジオメトリ規則に基づいて bbox を推定します。renderer 外の CTA/Logo は、--elements custom_elements.json を使ってピクセルまたは normalized bbox で指定できます。プラットフォームアプリの UI が変わった場合は、--safe-left/--safe-top/--safe-right/--safe-bottom で実測した余白を上書きします。
これはローカルで監査可能なレイアウトゲートです。アップロードせず、LLM を呼び出さず、OCR も行わず、生成画像やカバー内部の被写体/文字の位置も推定しません。画像全体で作られた章カードには uncheckable とマークされるため、SVG guide またはレンダリングフレームを開いて人手で確認する必要があります。summary.blocking > 0 の場合、--strict は 2 を返します。制作パイプラインの必須項目にするには、pipeline_manifest.py --require platform_safe_area_qa --strict を使用します。
Phase 4.95: 字幕スタイルプレビュー(実映像での字幕スタイル確認)
最終エンコードの前に、実際の ASS プリセットをソース動画の序盤/中盤/終盤の代表フレームにレンダリングします:
python3 scripts/subtitle_style_preview.py create \
--project-dir . \
--video origin/talking.mp4 \
--platform xhs \
--text "这句字幕要覆盖中英文和数字 2026" \
--preview-dir verify/subtitle_styles \
--output work/subtitle_style_preview.json \
--markdown work/subtitle_style_preview.md \
--require-selection
python3 scripts/subtitle_style_preview.py select \
--report work/subtitle_style_preview.json \
--style normal
python3 scripts/subtitle_style_preview.py verify \
--report work/subtitle_style_preview.json \
--strict
デフォルトでは normal/minimal/bold_pop を比較し、render_final.py と同じ ASS builder、フォント、文字サイズ、出力画角に合わせた中央クロップを使用します。スマートフォンサイズとフルサイズの両方を確認してください。確認後、選んだ値を render_final.py --subtitle-style に渡します。ソース動画、フォント、スタイル定義、または JPEG bytes が変わると、以前の選択は無効になります。karaoke プレビューで確認できるのは視覚的なスタイルだけです。実際の単語ごとのタイミングは、単語レベルのタイムスタンプに左右されます。最後に safe-area、readability QA を実行し、1× の完成動画を確認してください。詳細は docs/prompts/94-subtitle-style-preview.md を参照してください。
フェーズ 5:シングルパスレンダリング(単一パスでのレンダリング)
render_final.py を使用して、元動画から最終動画を1回のエンコードで生成します:
# 如没有在 Phase 0.25 生成 profile,删去 --style-profile。
python3 scripts/render_final.py --config render_config.json \
--style-profile work/edit_style_profile.json \
--enrich-plan work/enrich_plan.json \
--output final.mp4 --speed 1.25 1.5
基本原理:
- 単一の動画(最も一般的なケース):
select/aselectとbetween()式を使用して、残すすべての区間を一度に選択します。FFmpeg はソース動画全体をデコードしますが、選択したフレームのみをエンコードし、-crf 18 -preset mediumと組み合わせて、エンコードを1回だけ行います - 複数動画のミックス編集:
trim/atrimで切り出し、concatで連結します(自動的にフォールバックします) - カバーは
tpadで最初のフレームを静止させ、adelayで無音を追加します。字幕のタイミングは自動的にオフセットされ、すべて1回のエンコードで完了します - チャプターのタイムラインは動画に焼き込まず、レンダリング完了後にテキストとして出力されます。ユーザーが小紅書などのプラットフォームに手動で貼り付けられます
パラメーターの説明:
--config:レンダリング設定 JSON のパス--style-profile:任意。検証後、config に不足している個人/ブランドスタイルのデフォルト値のみを補完します--enrich-plan:任意。auto_enrich.pyの出力 JSON を読み込み、B-roll/チャプターカード/ステッカー/強調ポイント/生成済み画像の cue を自動的にレンダリングへ反映します--output:出力ファイルのパス--speed 1.25 1.5:速度変更版も同時に出力します(各速度変更版も元動画から直接エンコードされ、エンコード済み動画を再圧縮するものではありません)--cover-duration 2.0:カバーの静止時間(秒)。設定内のcover_durationを上書きします--font-path:カスタムフォントファイル--font-size:字幕のフォントサイズ(デフォルトは 120。縦画面の幅 1080 ÷ 9 = 120 で、漢字1文字が画面幅の 1/9 を占めます。実際の解像度に基づいて自動的に拡大縮小されます)--no-subtitles、--no-cover:対応する機能をスキップします
出力:
final.mp4(通常速度)final_1_25x.mp4(1.25 倍速)final_1_5x.mp4(1.5 倍速)- レンダリング完了後、ターミナルにチャプターのタイムラインテキストが出力され、そのまま小紅書にコピーできます
複数プラットフォーム向けフォーマットのエクスポート:
python3 scripts/render_final.py --config render_config.json --output final.mp4 \
--formats vertical square horizontal
同時に以下を出力します:
final_vertical.mp4(9:16、抖音/小紅書/TikTok)final_square.mp4(1:1、Instagram)final_horizontal.mp4(16:9、YouTube/Bilibili)
クロップ方法は中央クロップ(center-crop)で、映像の主体を変えずに維持します。
自動機能:
- 字幕の言語を自動検出し、自動で折り返して、縦画面向けに位置を最適化します
- カバーにタイトル文字(縁取りと影付き)を自動で重ね、最初のフレームを 1~2 秒間静止させます
- 速度変更版では字幕のタイミングを自動的に調整します
- B-roll を自動的に拡大縮小・クロップして、メイン動画の解像度に合わせます
--enrich-planのタイミング指定された B-roll/画像オーバーレイを自動的に拡大縮小・クロップして、メイン動画の解像度に合わせます- エンドカードに黒フレーム+無音+フェードイン/フェードアウトする字幕を自動的に連結します
- 継続表示されるオーバーレイと点滅するドットを、カバーの後から自動的に有効にします
- 動画と音声の長さを自動的に合わせ(
-shortest)、プラットフォームへのアップロード時に長さが一致しない問題を防ぎます
フェーズ 5b:JianYing/CapCut へのエクスポート(剪映プロジェクトのエクスポート)
剪映で編集を続けたい場合(エフェクトの追加、カラー調整、トランジションの微調整など)、FFmpeg でレンダリングせずに、編集プランをそのまま剪映のプロジェクトファイルにエクスポートできます:
python3 scripts/export_capcut.py --config render_config.json --output ./my_draft
エクスポート内容:
- ビデオトラック:選択したすべてのクリップをメインビデオトラックに順番に配置します。冒頭のカバー(最初のフレームの静止画またはカスタムカバー画像)も含まれます
- 字幕トラック:各クリップの文字起こしテキストを個別の字幕セグメントとして、画面の下部に配置します
- テキストトラック:カバーのタイトル、副題、エンドカードのテキスト(字幕とは別なので、個別に編集できます)
- オーディオトラック:BGM を追加し、音量を自動設定します
- トランジション:クリップ間にフェードイン/フェードアウトのトランジション(300ms)を自動追加します
- B-roll:B-roll による映像の置き換えに対応します(動画ソースとして broll のパスを使用します)
パラメーターの説明:
--config:レンダリング設定 JSON のパス(render_final.py と同じ render_config.json を使用します)--output:出力フォルダーのパス(draft_content.json と draft_meta_info.json が作成されます)--name:プロジェクト名(デフォルトでは設定内のタイトルを使用します)
使用方法:
- エクスポートしたフォルダーを剪映の下書きフォルダーにコピーします:
- macOS:
~/Movies/JianyingPro/User Data/Projects/com.lveditor.draft/ - Windows:
%APPDATA%/JianyingPro/User Data/Projects/com.lveditor.draft/
- macOS:
- 剪映を開くと、「下書き」一覧にプロジェクトが表示されます
- 剪映でエフェクトの追加、トランジションの調整、カラー調整、エクスポートなどを続けられます
注意:
- エクスポートされたプロジェクトファイルは、動画/音声素材を絶対パスで参照します。素材ファイルを移動しないでください
- 剪映プロ版(JianyingPro)に対応しています。剪映 6+ で生成された下書きを開けます
- この機能はフェーズ 5(FFmpeg によるレンダリング)とのいずれか一方を選択します。最終動画だけが必要な場合は render_final.py を使用し、剪映でさらに編集する場合は export_capcut.py を使用してください
字幕を剪映/CapCut の Auto Captions で生成し、手動で校正済みの場合は、プロジェクトの transcript に逆方向でインポートできます:
python3 scripts/import_capcut_subtitles.py \
--draft ~/Movies/JianyingPro/User\ Data/Projects/com.lveditor.draft/day58 \
--transcript work/capcut_transcript.json \
--cut-list work/capcut_gap_cut.json \
--markdown work/capcut_subtitles.md \
--source-media origin/talking.mp4
剪映からエクスポートした SRT をインポートすることもできます:
python3 scripts/import_capcut_subtitles.py \
--srt exports/capcut_auto_captions.srt \
--transcript work/capcut_transcript.json \
--srt-output output/subtitles/capcut_clean.srt
--cut-list は字幕間の空白から keep_segments を生成します。まず timeline_view.py --cut-list で確認してから、export_edl.py や後続のラフカットのワークフローに渡すのに適しています。デフォルトでは字幕素材のみを読み込みます。下書きで自動字幕が通常のテキストトラックとして保存されている場合は、--include-overlays を追加してください。
SRT と、人手またはエージェントが作成した字幕番号ごとの編集指示がある場合は、srt_edit_plan.py を使用して、確認可能な編集プランを直接生成できます:
work/edit_guide.md の例:
title: 发布会高光
platform: xhs
keep 3-5: 先用产品发布和用户反应
drop 1-2: 铺垫太慢
keep 8: 补一句核心结论
python3 scripts/srt_edit_plan.py \
--srt exports/capcut_auto_captions.srt \
--guide work/edit_guide.md \
--source-media origin/talking.mp4 \
--output work/srt_edit_plan.json \
--render-config work/render_config.json \
--cut-list work/srt_edit_cut.json \
--markdown work/srt_edit_plan.md \
--strict
keep/include/use/select の行は、出現順に最終出力の順番を決定します。drop/skip/exclude/remove の行は review に記録されます。--cut-list の出力は元素材の時間順に並ぶため、timeline_view.py --cut-list でカット位置を確認するのに適しています。実際の並べ替え結果は --render-config の出力を確認してください。すべての字幕番号を必ず確認済みにするには、--require-all-reviewed --strict を追加してください。
フェーズ 5c:NLE への引き渡し(EDL/FCPXML/OTIO)(Premiere/FCP/Resolve へ引き渡す)
剪映の下書きは不要で、自動編集プランをプロ向け編集ソフトに渡してカラー調整、ミキシング、細かな編集、共同レビューを行いたい場合は、単一トラックの EDL、単一 spine の FCPXML、または OpenTimelineIO .otio にエクスポートできます:
python3 scripts/export_edl.py --config render_config.json --output work/edit.edl --fps 30
python3 scripts/export_edl.py --cut-list work/rough_cut.json --output work/rough_cut.edl --fps 30
python3 scripts/export_fcpxml.py --config render_config.json --output work/edit.fcpxml --fps 30 --width 1080 --height 1920
python3 scripts/export_fcpxml.py --cut-list work/rough_cut.json --output work/rough_cut.fcpxml --fps 30
python3 scripts/export_otio.py --config render_config.json --output work/edit.otio --fps 30
python3 scripts/export_otio.py --cut-list work/rough_cut.json --output work/rough_cut.otio --fps 30
export_edl.py/export_fcpxml.py/export_otio.py はいずれも <output>.json マニフェストを同時に書き込み、ソースの絶対パス、正確な秒数、record/source timecode、イベント一覧を保持します。export_otio.py はデフォルトで V1 と A1 の 2 つのトラックを書き込みます。動画のみを引き渡す場合は --no-audio-track を使用できます。複雑な字幕、オーバーレイ、チャプターカード、B-roll については、引き続き render_final.py/export_capcut.py を使用してください。NLE への引き渡しで扱うのは、軽量なクリップ選択タイムラインのみです。
Phase 5d: Final Audio Storyboard(ビジュアル EDL ロック後の音声再構築)
複数の生成動画や連続する短編を制作する場合、まずビジュアル EDL を確定し、最終的な record timeline に合わせてナレーション、台詞、環境音、フォーリー、音楽を再構築します。編集前の動画全体の audio plan を、短縮した映像にそのまま当てはめないでください。EDL の各 event の label は、storyboard_plan.json の shot id に対応させます:
python3 scripts/export_edl.py \
--config work/render_config.json \
--output work/locked_visual.edl \
--manifest work/locked_visual.edl.json \
--fps 30
python3 scripts/final_audio_storyboard.py prepare \
--project-dir . \
--edl work/locked_visual.edl.json \
--storyboard work/storyboard_plan.json \
--output work/final_audio_storyboard_request.json \
--markdown work/final_audio_storyboard_request.md \
--response-template work/final_audio_storyboard_response.json \
--strict
# 填完 response 后:
python3 scripts/final_audio_storyboard.py audit \
--project-dir . \
--request work/final_audio_storyboard_request.json \
--response work/final_audio_storyboard_response.json \
--output work/final_audio_storyboard.json \
--markdown work/final_audio_storyboard.md \
--strict
python3 scripts/final_audio_storyboard.py verify \
--project-dir . \
--report work/final_audio_storyboard.json \
--strict
各 final section では、single_track / sectioned_tracks / stems、shared tone、voice、sound、music、stems、およびネイティブ音声を残す理由を明確にしてください。完全に削除した各 story beat には、remove / rewrite_into_adjacent / offscreen_bridge のいずれかを選択してください。台詞の重複、レビュー漏れ、時間マッピング、入力/response/report の不整合があれば fail closed します。スクリプトは音声を生成せず、プロバイダーにジョブを送信せず、クレジットも消費しません。承認済み JSON も、実際の音声ツールに合わせて timed cue sheet に書き換える必要があります。有料生成の前に、別途確認してください。詳しくは docs/prompts/95-final-audio-storyboard.md を参照してください。
最終ナレーションが複数回の TTS、分割録音、または文ごとの後処理をつないで作られている場合、BGM/SFX とミックスする前に、最終的な独立ナレーショントラックを短いフレーズ単位で測定します:
python3 scripts/narration_loudness_qa.py analyze work/final_narration.wav \
--segments work/final_narration_segments.json \
--project-dir . \
--output verify/narration_loudness_qa.json \
--markdown verify/narration_loudness_qa.md \
--strict
python3 scripts/narration_loudness_qa.py verify \
--report verify/narration_loudness_qa.json \
--project-dir . \
--strict
各セグメントのデフォルト目標は -18 LUFS ±2 LU、例外でないセグメントの spread は ≤1 LU、true peak は ≤-2 dBTP、LRA は ≤5 LU です。クリエイティブ上の例外には、セグメントごとに reason + reviewer を記載する必要があります。また、peak ceiling は例外扱いにできません。spread を判定するには、例外でないフレーズが少なくとも 2 つ必要です。レポートは、ナレーション、segment manifest、メディア契約、アルゴリズム、現場での再測定にひも付けられます。音色、発音、呼吸、接合部、演技は評価せず、ミックス後に audio_master_report.py で行う動画全体の -16 LUFS チェックに代わるものでもありません。詳しくは docs/prompts/105-narration-loudness-qa.md を参照してください。
Phase 6: Post-render Validation(レンダリング後の検証)
レンダリング完了後、最終動画に対して検証を実行します:
6a. 機械的 QA(最初に実行):
python3 scripts/render_qa.py final.mp4 \
--platform douyin \
--json final_qa.json \
--review-dir verify/final_qa \
--review-clips
render_qa.py は、コンテナのメタデータ、プラットフォームのサイズ、動画/音声ストリーム、黒画面、長い静止画、長い無音をチェックします。小紅書向け派生ファイルには --platform xhs、抖音/視頻号向けには --platform douyin または --platform wxch を使用してください。--review-dir は render_qa_review.json / .md を出力し、--review-clips は疑わしい区間の短い MP4 を抽出します。メタデータだけを手早く確認する場合は、--no-filters を追加してください。
6a00. 最終の音声/動画ストリームカバレッジ(master と各重要プラットフォーム版で必須):
python3 scripts/stream_coverage_qa.py analyze final.mp4 \
--project-dir . \
--output verify/stream_coverage_qa.json \
--markdown verify/stream_coverage_qa.md \
--strict
python3 scripts/stream_coverage_qa.py verify \
--report verify/stream_coverage_qa.json \
--project-dir . --strict
このゲートでは完成動画を全体デコードし、最初の動画/音声ストリームについて、それぞれ decoded frame count、先頭フレームの PTS、末尾の終了時間、timeline digest を集計します。デフォルトでは、音声と動画の先頭/末尾のずれ、または各ストリームがコンテナのタイムラインをカバーしていない場合にブロックします。render plan に正確な時間/フレーム数がある場合は、--expected-duration、--expected-video-frames を追加してください。AAC の priming/discard では nb_frames をハードゲートとして使用しませんが、動画のフレーム数は引き続き照合します。レポートの通過後、納品対象のファイルを 1 倍速で最初から最後まで再生してください。詳しくは docs/prompts/114-stream-coverage-qa.md を参照してください。
6a0. 同一タイムラインでの再エンコード画質(圧縮/トランスコード派生ファイルで必須):
python3 scripts/encode_quality_qa.py analyze output/master.mp4 output/final_delivery.mp4 \
--project-dir . \
--output verify/encode_quality_qa.json \
--markdown verify/encode_quality_qa.md \
--strict
python3 scripts/encode_quality_qa.py verify \
--report verify/encode_quality_qa.json --project-dir . --strict
reference と candidate のタイムラインおよび構図が同一の場合にのみ使用してください。fps の差が 0.01 を超える場合、時間の差が 1 フレームを超える場合、または表示アスペクト比が異なる場合は、即座に拒否します。デフォルトでは mean SSIM ≥0.95、P05 SSIM ≥0.88、有限フレームの mean PSNR ≥35 dB が必要です。candidate の解像度が異なっていてもアスペクト比が一致する場合に限り、Lanczos で正規化して WARN を出します。Markdown に記載された最悪フレームのタイムコードで A/B 確認し、1 倍速で全編再生してください。指標を人による画質承認の代わりにしてはいけません。音声は測定せず、crop/grade/HDR/retime/interpolation には適用できません。この実装は libvmaf を呼び出さず、VMAF をうたうものでもありません。pipeline_manifest.py --require encode_quality_qa --strict でリリースゲートに設定できます。詳しくは docs/prompts/107-encode-quality-qa.md を参照してください。
6a1. 音声チャンネルの完全性(最終 master と重要なプラットフォーム版で必須):
python3 scripts/audio_channel_qa.py analyze final.mp4 \
--project-dir . \
--output verify/audio_channel_qa.json \
--markdown verify/audio_channel_qa.md \
--strict
python3 scripts/audio_channel_qa.py verify \
--report verify/audio_channel_qa.json \
--project-dir . \
--strict
audio_channel_qa.py は、ローカルの FFmpeg を使って固定ウィンドウで、左右チャンネルの音声活動、開始位置のずれ、エネルギーバランス、位相相関、モノラルへのダウンミックスによるエネルギー損失を測定します。mono はチャンネル固有のチェックをそのまま通過します。stereo は現場で測定します。マルチチャンネルでは、まず明確な downmix を定義する必要があります。音声の変更は行わず、1 倍速での完全な stereo/mono 試聴、audio_master_report.py によるラウドネス/ピーク超過チェック、同期確認に代わるものでもありません。詳しくは docs/prompts/106-audio-channel-qa.md を参照してください。
6a2. 短い音声のドロップアウト(最終の独立した音声を優先):
python3 scripts/audio_dropout_qa.py analyze work/final_narration.wav \
--project-dir . \
--evidence-dir verify/audio_dropout_clips \
--output verify/audio_dropout_qa_scan.json \
--markdown verify/audio_dropout_qa_scan.md \
--response-template verify/audio_dropout_qa_response.json \
--strict
デフォルトでは 20 ms のウィンドウを使い、音声活動の間にある 40–400 ms の短いほぼ無音の区間を特定します。候補が見つかった場合は、入力とすべての WAV を 1 倍速で最初から最後まで再生し、dropout | intentional_pause | uncertain を記入してから audit と verify を実行してください。ドロップアウトと不確定な区間が確認された場合は引き続きブロックし、意図的な間は warning を残します。BGM/SFX がドロップアウトを隠す可能性があるため、最終の独立した台詞/ナレーション stem を優先してください。音声認識や音声修復は行わず、audio_master_report.py に代わるものでもありません。詳しくは docs/prompts/113-audio-dropout-qa.md を参照してください。
Caption / Speech QA(字幕と独立音声の活動の整合性確認)
python3 scripts/caption_speech_qa.py analyze work/final_narration.wav \
--subtitle-pack output/subtitles/final.json \
--project-dir . \
--output verify/caption_speech_qa.json \
--markdown verify/caption_speech_qa.md \
--strict
python3 scripts/caption_speech_qa.py verify \
--report verify/caption_speech_qa.json \
--project-dir . --strict
最終の独立した台詞/ナレーショントラック、または BGM/SFX が明確に含まれていない speech-dominant トラックのみを、このスクリプトに渡してください。ローカル FFmpeg の silencedetect を使って無音区間を audio-activity intervals に反転し、subtitle_pack.v1 の各 cue について、全区間に音声活動がない、実効音声活動率が低すぎる、先頭/末尾の無音が長すぎる、内部の間が長すぎる、音声トラックのタイムラインを超えている、といった点をチェックします。レポートは音声トラック、字幕 JSON、メディア契約、パラメーター、全測定値、canonical id にひも付けられます。pipeline_manifest.py --require caption_speech_qa --strict でリリースゲートに設定できます。振幅に基づく活動判定は speech recognition/forced alignment ではありません。BGM/SFX があると誤って通過する可能性があり、ready であっても最終ミックスで字幕を 1 倍速で全編確認する作業に代わるものではありません。詳しくは docs/prompts/109-caption-speech-qa.md を参照してください。
Subtitle Glyph QA(まれな文字/絵文字/多言語字幕で推奨)
python3 scripts/subtitle_glyph_qa.py analyze \
--subtitle-pack output/subtitles/final.json \
--font 'fonts/NotoSansSC[wght].ttf' \
--project-dir . \
--output verify/subtitle_glyph_qa.json \
--markdown verify/subtitle_glyph_qa.md \
--strict
python3 scripts/subtitle_glyph_qa.py verify \
--report verify/subtitle_glyph_qa.json \
--project-dir . --strict
スクリプトは TTF/OTF/TTC/OTC の Unicode cmap を直接読み取り、subtitle_pack.v1 内の表示されるすべての文字を網羅して、字幕、メインフォント、明示的な fallback、カバレッジの割り当て、canonical report id をひも付けます。システムによる暗黙のフォント置換は根拠として認められません。文字が欠けている場合はブロックし、明示的な fallback はデフォルトで警告します。--require-primary を使うと fallback を禁止できます。shaping、カラー絵文字、ASS レイアウト、視覚的な読みやすさを証明するものではありません。最終的には字幕を 1 倍速で全編確認し、フル解像度でフレームを抽出してください。詳しくは docs/prompts/110-subtitle-glyph-qa.md を参照してください。
Subtitle Render Review(字幕焼き込み済みの最終動画で必須)
python3 scripts/subtitle_render_review.py prepare \
--project-dir . \
--video output/final.mp4 \
--subtitle-pack output/subtitles/final.json \
--proof-dir verify/subtitle_render \
--output work/subtitle_render_review_request.json \
--markdown work/subtitle_render_review_request.md \
--response-template work/subtitle_render_review_response.json
# 完整 1× 看完 final,并逐条填写 response 后:
python3 scripts/subtitle_render_review.py audit \
--request work/subtitle_render_review_request.json \
--response work/subtitle_render_review_response.json \
--output work/subtitle_render_review.json \
--markdown work/subtitle_render_review.md --strict
python3 scripts/subtitle_render_review.py verify \
--report work/subtitle_render_review.json --project-dir . --strict
脚本从确切 final 选择首尾、最长、最高 CPS、最短、中段和均匀分布 cue,导出带声 1× context clips 与字幕中点原尺寸 JPEG。通过要求完整播放全片,且每个样本均为 visible / matches / readable / clear / repair_action=none;缺失、旧文案、不可读、裁切、遮挡或不可观察都会 fail closed。报告绑定 final、subtitle pack、proof bytes、媒体契约、采样设置、人工 response 与 canonical id;任何重渲染或证据漂移后都要重做。它不做 OCR 或自动可读性评分,默认抽样也不替代逐条完整审片。详见 docs/prompts/111-subtitle-render-review.md。
6a2. 闪烁 / 光敏风险启发式预检(最终 master 和重要平台版必跑):
python3 scripts/flash_safety_qa.py analyze final.mp4 \
--project-dir . \
--output verify/flash_safety_qa.json \
--markdown verify/flash_safety_qa.md \
--strict
python3 scripts/flash_safety_qa.py verify \
--report verify/flash_safety_qa.json \
--project-dir . \
--strict
flash_safety_qa.py 用本地 FFmpeg 低分辨率逐帧采样,分别记录覆盖至少 25% 画面的亮度与饱和红相反 transition,并配成 flash;滚动 1 秒超过 3 次、或滚动 5 秒至少 10 次会阻断。命中后按 Markdown 时间段正常速度播放,优先删除重复闪白/闪红、降低反差/红饱和度、缩小闪烁面积或降频,再从时间线重渲染。报告绑定 source SHA-256、媒体契约、参数、算法合同和现场重算证据;pipeline_manifest.py --require flash_safety_qa --strict 可设为发布 gate。它只是启发式筛查,不检测有害空间 pattern,也不是医疗建议、法律合规证据或 WCAG/Harding/广播认证;高风险或受监管交付必须升级到认可的专业 photosensitivity analyzer。详见 docs/prompts/104-flash-safety-qa.md。
6a3. 单帧 / 少数帧瞬态伪影(最终 master 和生成素材推荐):
python3 scripts/temporal_artifact_qa.py analyze final.mp4 \
--project-dir . \
--evidence-dir verify/temporal_artifact_frames \
--output verify/temporal_artifact_qa.json \
--markdown verify/temporal_artifact_qa.md \
--response-template work/temporal_artifact_response.json \
--strict
脚本寻找 1–3 个采样帧短暂偏离、随后回到近似原画面的局部 spike;普通 hard cut 不应满足双边突变与恢复相似合同。命中候选后,必须完整 1× 播放,再逐张描述 before / suspect / after,填写 intentional_edit|artifact|uncertain 并运行 audit。后两种决定保持阻塞;source、算法、分析、JPEG、response 或派生状态漂移都会让 live gate 失效。它不识别人脸、身份、物理或语义,也可能漏掉持续漂移和小区域问题。详见 docs/prompts/108-temporal-artifact-qa.md。
6b. 镜头色彩 / 曝光 QA(多机位、B-roll、生成素材或调色后推荐):
python3 scripts/shot_color_qa.py final.mp4 \
--output verify/shot_color_qa.json \
--markdown verify/shot_color_qa.md \
--strict
shot_color_qa.py 在最终编码文件上用 FFmpeg signalstats 按镜头聚合亮度、对比、U/V、饱和度和 broadcast-range 指标,并比较相邻镜头的亮度/色度差。视觉跳变默认只 WARN,必须结合 Markdown 时间码和 timeline_view.py 看 master;非 full-range 输出的持续越界或镜头无 sample 默认阻塞。可用 --scene-boundaries work/scene_boundaries.json 复用已审场景,或由脚本自动检测。它不是校准 scopes、HDR proof、白平衡/肤色判断或审美评分。pipeline_manifest.py --require shot_color_qa --strict 可把报告设为发布必需项。
6c. 留存节奏风险审计(短视频 master / platform export 推荐):
python3 scripts/subtitle_pack.py \
--config render_config.json \
--output-dir output/subtitles \
--basename final_master \
--speed 1.25 \
--offset 2.0
python3 scripts/retention_rhythm_qa.py final.mp4 \
--timed-text output/subtitles/final_master.json \
--output verify/retention_rhythm_qa.json \
--markdown verify/retention_rhythm_qa.md \
--strict
retention_rhythm_qa.py 在已渲染成片上复用 FFmpeg scene score,并可合并 output-aligned subtitle JSON,检查前三秒 scene/subtitle activity、长视觉 hold、scene + subtitle attention gap、机械等距节奏、过密快切和字幕长时间不刷新。没有 timed text 时,inactive hook 只警告,避免把持续运镜或轻微动效误判成硬失败;高置信严重长 hold / attention gap 会写入 summary.blocking。这是可观测节奏风险,不是平台留存率或爆款预测。命中后先看 Markdown 时间范围和 master,再回到源 timeline 重渲染。pipeline_manifest.py --require retention_rhythm_qa --strict 可把报告设为发布必需项。
6c.1. 参考视频剪辑节奏量化(用户明确给参考片时跑):
python3 scripts/reference_edit_rhythm.py analyze \
--project-dir . \
--reference origin/reference-ad.mp4 \
--candidate final.mp4 \
--evidence-dir verify/reference_edit_rhythm \
--output work/reference_edit_rhythm.json \
--markdown work/reference_edit_rhythm.md \
--strict
python3 scripts/reference_edit_rhythm.py verify \
--report work/reference_edit_rhythm.json \
--strict
reference_edit_rhythm.py 对参考片和候选片运行同一套 hard scene detection,绑定两条视频和两张 contact sheet 的 SHA-256/媒体契约,并比较 cuts/minute、median shot、final-hold 比例、归一化切点位置及 opening/middle/closing cut share。默认偏差只 WARN;只有结构匹配是明确验收条件时才加 --require-match。完整看两条视频,只借鉴结构,不复制参考片的画面、音频、品牌或故事。scene score 会漏掉部分 dissolve 与镜头内动作,contact sheet 也不能替代 1× 播放。详见 docs/prompts/92-reference-edit-rhythm.md。
6c.2. 最终成片 Lip-sync 复核(数字人 / 生成口播 / 对口型 close-up):
python3 scripts/lip_sync_review.py prepare \
--project-dir . \
--video final.mp4 \
--segment hook=2.40:6.10 \
--anchor hook="把品牌卖点说清楚" \
--proof-dir verify/lip_sync \
--output work/lip_sync_review_request.json \
--markdown work/lip_sync_review_request.md \
--response-template work/lip_sync_review_response.json
# 看完 1× 带声和 0.25× 静音 proofs、填写 response 后:
python3 scripts/lip_sync_review.py audit \
--request work/lip_sync_review_request.json \
--response work/lip_sync_review_response.json \
--output work/lip_sync_review.json \
--markdown work/lip_sync_review.md \
--strict
python3 scripts/lip_sync_review.py verify --report work/lip_sync_review.json --strict
短语必须来自最终 master 且完整可见,长度 1–10 秒,优先包含 p/b/m 类闭唇锚点。pass 要求爆破音闭唇、元音 timing、讲话时嘴部运动、可见说话人和音频质量全部通过;not_observable fail closed。脚本只绑定人工审过的 master/proof bytes,不做人脸或自动音素识别。任何剪切、变速、换音、重编码或 evidence 漂移都要重新 prepare → audit。详见 docs/prompts/93-lip-sync-review.md。
6d. 完整审片代理(需要分享整条视频或精确时间码反馈时跑):
python3 scripts/review_proxy.py final.mp4 \
--output verify/final_review_proxy.mp4 \
--manifest verify/final_review_proxy.json \
--markdown verify/final_review_proxy.md
review_proxy.py 不修改 master;它输出最大 720p、24fps、H.264/AAC、+faststart 的轻量 MP4,并在左上角烧入 REVIEW PROXY 和 elapsed timecode。审片意见应引用可见时间码,最终 QA 和发布仍使用 master / platform export。--dry-run 只写可复现命令和 artifact,--no-timecode 可关闭时间码。
6e. 可视化复盘(QA 有 WARN/FAIL 或抽查切点时跑):
python3 scripts/timeline_view.py final.mp4 --at 42.5 --radius 1.5 --output verify/42_5s.png
python3 scripts/timeline_view.py origin/talking.mp4 --cut-list work/jumpcut.json --output-dir verify/cuts --limit 12
python3 scripts/timeline_view.py output/rough_cut.mp4 --rendered-cut-list work/rough_cut.json --output-speed 1.25 --output-offset 1.0 --output-dir verify/rendered_cuts --json verify/rendered_cuts.json
timeline_view.py 会生成 filmstrip + waveform PNG;上半部分看画面连续性,下半部分看人声/静音边界。--cut-list 查看源素材时间轴,--rendered-cut-list 则按 keep_segments 累计时长映射到成片的实际拼接点;有全局变速或片头封面时同步传 --output-speed / --output-offset。JSON 会保留输出切点和前后 source range;无音频视频会自动只输出 filmstrip。
6f. 原片/成片 source-time 对照(结构剪辑复核时跑):
python3 scripts/edit_compare.py \
origin/talking.mp4 final.mp4 \
--cut-list work/rough_cut.json \
--output-speed 1.25 \
--output-offset 2.0 \
--output verify/source_vs_final.mp4 \
--report verify/edit_compare.json \
--markdown verify/edit_compare.md
左栏连续播放原片;右栏把最终交付像素投回同一 source clock,被删除范围显示黑屏。脚本会检查时长、双栏尺寸、source-clock 音轨、删段黑屏和代表性保留段像素。V1 只支持单来源、时间升序、无重叠的 keep_segments 加全局 speed/offset;重排、多来源或非线性变速要回到 NLE/OTIO 时间线复核。详细说明见 docs/prompts/74-edit-compare.md。
6g. 字幕 sidecar 交付(平台需要 SRT/VTT 时跑):
python3 scripts/subtitle_pack.py \
--config render_config.json \
--output-dir output/subtitles \
--basename final_master \
--speed 1.25 \
--offset 2.0 \
--formats srt vtt ass json
subtitle_pack.py 可从 transcript.json 或 render_config.json 生成 SRT/VTT/ASS/JSON。--config 会按最终 clips 顺序串接字幕时间线;--speed 对齐 render_final.py --primary-speed;--offset 对齐片头封面秒数。JSON manifest 保留每条 cue 的来源片段和 over_max_chars 之类校对警告。
播放器需要可开关字幕时,用已审、与最终 MP4 对齐的 SRT 运行 soft_subtitles.py mux final.mp4 output/subtitles/final_master.srt --language zho --output output/final-soft.mp4 --receipt verify/soft_subtitles.json,再运行 soft_subtitles.py verify verify/soft_subtitles.json。脚本仅接受单视频、最多单音频、无其他轨的源片;复制音视频流,加入一条 mov_text 字幕轨,检查 SRT 时间、抽回的字幕内容、源/成片流哈希、完整解码和文件漂移。ready_for_human_review 后仍要在目标播放器以 1× 带声看完,确认字幕开关、中文显示和音画同步。已有烧录字幕的画面不会被此命令移除,交付前应确认是否会出现双层字幕。
长视频需要播放器内可跳转章节时,先用 chapter_markers.py 生成并人工核对 chapters.json,确保末章结束时间与最终 MP4 一致;再运行 chapter_mux.py mux output/master.mp4 output/chapters/chapters.json --output output/master-chapters.mp4 --receipt verify/chapter_mux.json 和 chapter_mux.py verify verify/chapter_mux.json。脚本接受未带章节的单视频、最多单音频 MP4,复制音视频流并核对每章标题/时间、流哈希和完整解码。最终仍需在目标播放器检查章节跳转;上传平台若不读取 MP4 内嵌章节,另交付 chapters-youtube.txt。
网页播放器可将同次导出的 chapters.vtt 作为 <track kind="chapters" src="chapters.vtt" srclang="zh"> 加到与章节时间线一致的 <video>;VTT 使用无重叠章节、毫秒时间码和纯文本标题。浏览器是否呈现章节菜单取决于播放器实现,交付时实际试跳转;片头或重新剪辑改变时间线后需按最终视频时长重新导出。
公开分享 MP4 前可运行 metadata_scrub.py scrub output/master.mp4 --output output/share.mp4 --receipt verify/metadata_scrub.json,再运行 metadata_scrub.py verify verify/metadata_scrub.json。它只保留第一条视频和可选第一条音频,移除容器/流的非结构性标签、章节和字幕/数据等额外轨;核对音视频编码流 SHA-256、时长、完整解码和输出标签。分享版若需要章节或软字幕,应在清理后明确重新封装并复核。该工具只检查 FFprobe 可见的容器/流标签,不扫描画面、音频内容或编码流内部可能携带的信息;仍需正常速度审看分享版。
生成 JSON 后,对最终字幕执行只读发布门禁:
python3 scripts/subtitle_readability_qa.py \
output/subtitles/final_master.json \
--media final.mp4 \
--output verify/subtitle_readability_qa.json \
--markdown verify/subtitle_readability_qa.md \
--strict
subtitle_readability_qa.py 检查 output-timeline 的无效时间、乱序、重叠、极短闪现、CPS、持续时间、行数/行长,并可用 FFprobe 验证 cue 没有超过成片结尾。普通 CPS/排版风险只 WARN,必须看正常速度 master;确定性时间事故和极端阅读速度写入 summary.blocking。它不做 OCR,不替代字体、描边、位置或遮挡人工审片。pipeline_manifest.py --require subtitle_readability_qa --strict 可把报告设为发布必需项。
6g.1 平台画幅处理预览(master 与目标比例不同或画面含受保护信息时跑):
python3 scripts/framing_preview.py create \
--project-dir . --video output/master.mp4 \
--platforms xhs douyin wxch \
--preview-dir verify/framing \
--output work/framing_preview.json \
--markdown work/framing_preview.md \
--require-selection
python3 scripts/framing_preview.py select \
--report work/framing_preview.json --platform xhs --strategy contain
python3 scripts/multi_export.py output/master.mp4 \
--output-dir output --platforms xhs douyin wxch \
--framing-preview work/framing_preview.json
逐平台看真实早/中/晚 JPEG。cover 不能裁掉脸、手、多人关系、可读 UI、logo、产品边缘或文档边界;有风险时选 contain 或 blur。源/预览 bytes、显示方向、平台画布、filter digest 或选择漂移都会在编码前阻断。抽样图不替代完整 1× 平台导出审片;详见 docs/prompts/103-framing-preview.md。
6h. 发布上传包(最终上传前跑):
python3 scripts/publish_package.py \
--project-dir work/day58 \
--platforms xhs douyin wxch \
--output work/day58/publish_package.json \
--markdown work/day58/publish_package.md \
--strict
publish_package.py 不上传、不调用平台 API;它只把 multi_export.py 的平台 MP4、generate_caption.py 的标题/正文/tags、封面、SRT/VTT、章节文本和 pipeline_manifest gate 状态合成 publish_package.v1。如果存在 cover_variants.json 且 selected_cover 文件有效,会优先使用已复核封面;显式 --cover 可覆盖。如果缺少某个平台视频、caption 为空、或 pipeline manifest 已 blocked,--strict 返回 2。需要交给外部发布 connector 时,用这份 JSON 作为 handoff;手工上传时看 Markdown checklist。
6i. 最终审批收据(客户/人工确认后跑):
python3 scripts/approval_receipt.py create \
--project-dir work/day58 \
--artifact output/day58_xhs.mp4 \
--artifact output/day58_douyin.mp4 \
--artifact output/day58_wxch.mp4 \
--artifact output/cover.png \
--artifact output/day58_caption.json \
--artifact verify/render_qa.json \
--approved-by "reviewer label" \
--output verify/approval_receipt.json \
--markdown verify/approval_receipt.md
python3 scripts/publish_package.py \
--project-dir work/day58 \
--require-approval-receipt \
--strict
approval_receipt.py 只绑定显式列出的稳定交付件;不要把每次都会重写的 pipeline manifest、publish package 或 dashboard 放进收据。verify --strict 和 pipeline_manifest.py --require approval_receipt --strict 会重新读取当前文件并比较 SHA-256;任何重渲染、换封面、改文案、删字幕或路径变成 symlink 都让旧审批过期。approved_by 只是本地标签,不是身份认证或数字签名。详细说明见 docs/prompts/77-approval-receipt.md。
6j. 续跑上下文包(跨会话/自动化收尾时跑):
python3 scripts/project_resume.py \
--project-dir work/day58 \
--target-stage publish_ready \
--output work/day58/project_resume.json \
--markdown work/day58/project_resume.md \
--agent-note work/day58/CLAUDE.md \
--strict
project_resume.py 复用 pipeline_manifest.py 的本地 gate,不渲染、不上传、不提交生成任务。它输出 project_resume.v1,包含 phase、recommended_first_action、next_actions[]、最近 artifacts、关键 gate snapshot 和一句可直接交给下一位 agent 的 suggested_prompt。长流程被压缩上下文、自动化结束、或要交给另一位 agent 时,优先把 Markdown/agent note 作为接手入口。
6k. 人工复核面板(最终确认/交接前跑):
python3 scripts/review_dashboard.py \
--project-dir work/day58 \
--target-stage publish_ready \
--output work/day58/review_dashboard.json \
--html work/day58/review_dashboard.html \
--strict
review_dashboard.py 复用 pipeline_manifest.py 的本地 gate,输出 review_dashboard.v1 和一个可直接在浏览器打开的 HTML。它把 blocking/missing/warning gate 放进 review_items[],同时列出 next_actions[]、最新 artifacts 和完整 gate snapshot。适合用户最终确认,也适合自动化结束时留给下一位 agent。
6l. 成片复读 / 口吃门禁:
python3 scripts/extract_audio.py output/final.mp4
python3 scripts/transcribe.py output/final_audio.wav --model auto --language zh --word-timestamps
python3 scripts/speech_continuity_qa.py output/final_transcript.json \
--output verify/speech_continuity_qa.json \
--markdown verify/speech_continuity_qa.md \
--strict
必须对已渲染 master重新转录,不能复用源素材 transcript。speech_continuity_qa.py 会检查相邻 segment 的结尾/开头精确复读、相邻近重复 take 和句内即时口吃;不同 speaker 默认不互判。命中后先按时间码试听 master,再调整源 render_config / cut list,重新渲染并复跑。pipeline_manifest.py --require speech_continuity_qa --strict 可把这份报告设为发布必需项。
6m. PQ/HLG HDR → Rec.709 SDR 交付(HDR master 面向普通社媒/网页时跑):
python3 scripts/hdr_sdr.py plan output/final_hdr.mp4 \
--delivery output/final_sdr.mp4 \
--output work/hdr_sdr_plan.json \
--markdown work/hdr_sdr_plan.md
python3 scripts/hdr_sdr.py apply work/hdr_sdr_plan.json
python3 scripts/hdr_sdr.py verify work/hdr_sdr_plan.json
hdr_sdr.py 只接受 metadata 明确的 smpte2084 PQ 或 arib-std-b67 HLG,并要求 BT.2020 primaries/matrix;未知/矛盾 color tags 会 fail closed。正确转换必须同时有 FFmpeg zscale + tonemap,不允许用裸 tonemap 或只降到 yuv420p 的退化回退。apply 用 linear-light float + Hable 生成 H.264/AAC、yuv420p、BT.709 limited-range MP4,显式验证四项 color tag、时长/尺寸/fps/音轨、hash 和全长解码后才原子提升。Dolby Vision/HDR10+ 动态 metadata 不保留;必须在可信 SDR 屏完整复核肤色、高光、阴影、渐变和饱和色,再对 SDR 文件重跑 QA 和审批。详见 docs/prompts/87-hdr-sdr.md。
6n. 目标大小交付编码(有明确 MB 上限时跑):
python3 scripts/delivery_encode.py plan output/final.mp4 \
--delivery output/final_delivery.mp4 \
--max-size-mib 18 \
--output work/delivery_encode_plan.json \
--markdown work/delivery_encode_plan.md
python3 scripts/delivery_encode.py apply work/delivery_encode_plan.json \
--markdown work/delivery_encode_plan.md
python3 scripts/delivery_encode.py verify work/delivery_encode_plan.json
delivery_encode.py 绑定 master SHA-256,用两遍 libx264 在 6% 容器余量内计算 H.264/AAC 码率;输出超过硬上限、容器/流/尺寸/fps/时长/音频不符或完整 FFmpeg decode 失败都会阻塞。apply 只先写同目录临时 MP4,技术验证通过后才原子晋升,不覆盖源文件。完整解码不是画质批准;若构图/时间线未变,紧接着运行 encode_quality_qa.py,再正常速度看完交付版、跑 render_qa.py 并把最终 SHA-256 放入 approval_receipt.py。详见 docs/prompts/85-delivery-encode.md 与 docs/prompts/107-encode-quality-qa.md。
6o. 字幕文字最终校验:
- 读取最终视频使用的所有 transcript 片段的文字
- 按最终视频的片段顺序,逐条检查以下问题:
- 语音识别残留错误:Phase 2.5 可能遗漏的同音字、专有名词错误
- 口误未清理:说话人的口误(如说反了、重复了)是否仍然保留在最终视频中
- 上下文连贯性:跨视频拼接后,相邻片段之间是否存在语义断裂或逻辑跳跃
- 字幕一致性:同一个词/名称在不同片段中是否拼写一致
- 如发现问题,列出问题清单并展示给用户:
字幕校验结果: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # | 问题类型 | 原文 → 建议修正 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3 | 识别错误 | "检映" → "剪映" 7 | 口误 | "先说了结果" → 建议删除此片段 12 | 名称不一致 | "opencloud" → 统一为 "OpenClaw" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - 用户确认修正后,修改对应的 transcript.json,然后重新执行 Phase 5 渲染
Important Notes(注意事项)
视频质量与编码准则(最重要)
- 单次编码原则:从原始视频到最终输出,只允许一次编码。严禁多次重编码(如先切分编码、再烧字幕编码、再加封面编码),每次重编码都会累积质量损失。使用
render_final.py的select/aselect+between()方案(单视频)或trim/atrim+concat方案(多视频),在一条 ffmpeg 命令中完成裁切、拼接、字幕、封面的全部操作。 - 变速版本也从原始视频直接编码:
--speed 1.25 1.5的变速版本在filter_complex中集成setpts+atempo,直接从原始视频一步到位,不要从已编码的 1x 视频再次压缩。 - 编码参数:使用固定比特率(如
-b:v 12M)而非质量参数(如-q:v)。固定比特率可以精确控制文件大小和质量,避免-q:v在不同编码器上表现不一致。参考原始视频比特率(通常 8-15 Mbps)设定。 - 旧流程脚本仅用于预览:
split_video.py、burn_subtitles.py、merge_clips.py、generate_cover.py、add_chapter_bar.py仍可单独使用,但最终输出必须使用render_final.py。旧脚本适合快速预览单个片段效果。
Rotation 检测
- Rotation 检测:iPhone 等设备录制的竖屏视频,编码尺寸可能是 1920x1080 + rotation=-90 元数据。所有脚本通过
utils.get_video_info()统一检测 rotation 并自动交换宽高,确保获取正确的显示尺寸。检测视频信息时必须首先检查 rotation。
章节时间轴
- 章节数量:建议不超过 4 个章节,章节名 2-4 个字。
- 时间轴不烧入视频:渲染完成后以文本形式输出章节时间轴(含封面偏移),用户手动复制到小红书等平台的视频描述中。
其他
- 多视频处理:如果用户提供多个视频,对每个视频独立执行 Phase 1-2.5,然后在 Phase 3 统一展示所有视频的片段列表,支持跨视频混合选择片段。
- 识别模型选择:中文视频建议使用
large模型,base/small模型中文识别率较低。large模型约需 2.9GB 下载空间。 - 工作目录:所有中间文件(音频、转录)都保存在视频文件所在目录下,便于管理。渲染完成后应清理临时文件(ASS 字幕文件、filter_complex 脚本)。
- 错误处理:如果某一步失败,向用户报告具体错误信息,并建议可能的解决方案。
- 字幕字体:默认使用 LXGW WenKai Medium(霞鹜文楷中粗体),自动下载缓存。ffmpeg 需要编译包含
libass和libfreetype。macOS 可通过brew install ffmpeg获取。 - 竖屏适配:字幕位置和字体大小已针对 9:16 竖屏视频(如小红书、抖音)优化。默认字号 120(= 屏幕宽度 1080 ÷ 9),每个汉字占竖屏宽度的约 1/9。横屏视频同样支持,字号会按实际分辨率自动缩放。
Remotion Voiceover Workflow(语音生成视频)
当用户只有语音(或音频文件)但没有画面时,使用 Remotion 生成配合语音的视频画面。
详细的 Remotion API 参考、模板样式、组件结构见 REMOTION_VOICEOVER.md。
适用场景
- 纯音频口播 — 有录音/TTS 语音,需要生成匹配的画面
- 音频 + 静态图片 — 有语音和图片素材,需要组合成动态视频
- 播客可视化 — 将播客/对话音频转为带字幕和视觉效果的视频
- 解说视频 — 配音 + 文字动画 + 背景图的组合
Remotion Workflow(工作流)
- 音频准备 — 使用
extract_audio.py提取音频,或直接使用用户提供的音频文件 - 语音识别 — 使用
transcribe.py生成 transcript.json(逐句时间戳) - 时间轴生成 — AI Agent 根据 transcript 内容分析语义,生成
timeline.json:- 将多个 segments 按语义分组为 scenes
- 为每个 scene 选择类型(title/content/kinetic/quote 等)
- 选择背景视觉、文字动画、转场效果
- 配置字幕样式(TikTok 逐词高亮 / 底部字幕 / 全屏文字)
- 素材准备 — 收集/生成场景所需的图片素材
- Remotion 渲染 — 使用
npx remotion render根据 timeline.json 渲染最终视频 - 后处理(可选) — 使用
render_final.py与其他视频片段合并
视频模板风格选择
| 风格 | 适用场景 | 视觉效果 |
|---|---|---|
tiktok | 短视频口播、知识分享 | 渐变背景 + 关键词卡片 + TikTok 风格逐词字幕 + 进度条 |
tutorial | 教程、科普、产品介绍 | 图文分栏 + Ken Burns 图片 + 要点逐行淡入 + 底部字幕 |
kinetic | 情感类、激励类、文案 | 全屏大号文字逐行弹入 + 弹性动效 |
podcast | 播客、访谈、对话 | 头像 + 音频波形可视化 + 引用文字 |
news | 新闻播报、行业资讯 | 顶部横幅 + Lower Third 信息条 + 滚动字幕 |
slideshow | 产品介绍、旅行、相册 | 多图 Ken Burns + 转场效果 + 说明文字 |
Remotion 环境要求
# 需要 Node.js 18+ 和 npm
node --version # >= 18.0.0
npm --version
# 安装 Remotion standup 项目依赖
cd remotion-standup
npm install
脱口秀/纯音频视频生成(Standup Comedy Workflow)
当用户有一段脱口秀音频(或任何纯语音内容)但没有画面时,可以生成带文字动效的视频:
Step 1: 语音识别
python3 scripts/transcribe.py audio.wav --model auto --language zh
Step 2: 生成时间轴
# 默认风格
python3 scripts/generate_standup_timeline.py transcript.json \
--audio audio/standup.wav \
--output remotion-standup/public/timeline.json
# 活力风格(更多夸张动效)
python3 scripts/generate_standup_timeline.py transcript.json \
--audio audio/standup.wav \
--style energetic \
--output remotion-standup/public/timeline.json
# 选择特定片段 + 自定义字体
python3 scripts/generate_standup_timeline.py transcript.json \
--audio audio/standup.wav \
--segments 1-10,12,15-20 \
--font "LXGW WenKai, sans-serif" \
--output remotion-standup/public/timeline.json
Step 3: 预览和渲染
cd remotion-standup
# 把音频文件复制到 public 目录
cp /path/to/audio.wav public/audio/standup.wav
# 开发预览
npx remotion studio
# 渲染最终视频
npx remotion render StandupVideo out/standup.mp4 --codec=h264 --crf=18
脚本会自动:
- 检测笑点/短句(感叹号、关键词、短句跟长句的对比)→ 用 slam/shake/bounce 等夸张动效
- 短句放大字号(emphasis 1.3-1.6x),长句缩小避免溢出
- 笑点使用径向渐变 + 醒目配色(红/橙/金/绿)
- 常规句子使用深色渐变背景 + 不同动画循环
- 自动在中文长句中间插入换行
12 种文字动画效果:
| 动画 | 效果 | 适合场景 |
|---|---|---|
fadeIn | 渐显 | 平稳叙述 |
springIn | 弹性入场 | 正常对话 |
scaleUp | 由小放大 | 强调 |
scaleDown | 由大缩小 | 砸入感 |
typewriter | 打字机 | 引述/对话 |
bounce | 弹跳 | 活泼/搞笑 |
shake | 抖动 | 笑点/吐槽 |
slam | 急速砸入 | 重磅笑点 |
wave | 逐字波浪 | 开场/结尾 |
glitch | 故障闪烁 | 意外/反转 |
rotateIn | 旋转入场 | 切换话题 |
splitReveal | 中间展开 | 揭示/揭晓 |
3 种风格预设:
| 风格 | 说明 |
|---|---|
default | 均衡混合所有动画,适合大多数内容 |
calm | 只用平缓动画(fadeIn/springIn/typewriter),适合讲故事/深度内容 |
energetic | 偏重夸张动画(slam/shake/bounce/glitch),适合脱口秀/搞笑内容 |
timeline.json 配置格式
{
"fps": 30,
"width": 1080,
"height": 1920,
"audioSrc": "public/audio/voiceover.wav",
"style": "tiktok",
"font": {
"family": "Noto Sans SC",
"titleWeight": "700",
"bodyWeight": "400",
"titleSize": 72,
"bodySize": 48
},
"colors": {
"background": "#1a1a2e",
"text": "#ffffff",
"highlight": "#FFD700",
"accent": "#e94560"
},
"scenes": [
{
"id": 1,
"startMs": 0,
"endMs": 5000,
"type": "title",
"title": "今天聊一个话题",
"background": { "type": "gradient", "colors": ["#667eea", "#764ba2"] },
"transition": { "type": "fade", "durationMs": 500 }
}
],
"captions": {
"enabled": true,
"style": "tiktok",
"fontSize": 56,
"highlightColor": "#FFD700"
}
}
Font Catalog(字体目录)
项目内置了一套可下载的免费字体目录,覆盖中文和英文视频制作常用字体。
字体管理
# 查看环境报告(包含已缓存字体列表)
python3 scripts/utils.py
# 在 Python 中使用字体 API
python3 -c "
from scripts.utils import list_available_fonts, download_font
# 列出所有可用字体
for f in list_available_fonts():
status = '✓' if f['cached'] else '○'
print(f\"{status} {f['id']:25s} {f['name']:25s} {f['use_case']:8s} {f['description']}\")
# 下载指定字体
download_font('lxgw-wenkai')
download_font('inter')
"
中文字体
| 字体 ID | 名称 | 风格 | 用途 | 许可证 |
|---|---|---|---|---|
noto-sans-sc | Noto Sans SC(思源黑体) | 万能黑体 | 全场景 | SIL OFL |
noto-serif-sc | Noto Serif SC(思源宋体) | 正式宋体 | 文化/古典/深度 | SIL OFL |
lxgw-wenkai | LXGW WenKai(霞鹜文楷) | 手写楷体 | 文艺/文化/情感(~24MB) | SIL OFL |
lxgw-wenkai-lite | LXGW WenKai Lite(轻便版) | 手写楷体 | 同上,体积更小(~13MB) | SIL OFL |
lxgw-wenkai-bold | LXGW WenKai Medium | 手写楷体粗 | 标题 | SIL OFL |
zcool-kuaile | ZCOOL KuaiLe(站酷快乐体) | 圆润可爱 | 轻松/娱乐标题 | SIL OFL |
zcool-qingke-huangyou | ZCOOL QingKe HuangYou(庆科黄油体) | 手写潮流 | 时尚/年轻标题 | SIL OFL |
zcool-xiaowei | ZCOOL XiaoWei(站酷小薇体) | 清秀端正 | 正文/字幕 | SIL OFL |
英文字体
| 字体 ID | 名称 | 风格 | 用途 | 许可证 |
|---|---|---|---|---|
inter | Inter | 现代无衬线 | 全场景 | SIL OFL |
montserrat | Montserrat | 几何无衬线 | 标题 | SIL OFL |
poppins | Poppins | 圆润几何 | 标题 | SIL OFL |
roboto | Roboto | 中性现代 | 全场景 | Apache 2.0 |
oswald | Oswald | 窄体无衬线 | 新闻/头条标题 | SIL OFL |
playfair-display | Playfair Display | 优雅衬线 | 文艺/高端标题 | SIL OFL |
字体选择建议
默认字体:LXGW WenKai Medium(霞鹜文楷中粗体) — 手写楷体风格,兼具美观性和可读性,是口播/Vlog 类视频的最佳选择。如果未缓存,会自动下载。
默认字号:120(竖屏 1080px 宽度 ÷ 9 = 120),即每个汉字占屏幕宽度的约 1/9,在手机竖屏上清晰易读。
| 视频类型 | 推荐中文字体 | 推荐英文字体 |
|---|---|---|
| 口播/Vlog(默认) | LXGW WenKai Medium | Inter / Roboto |
| 科技/教程 | Noto Sans SC | Inter / Roboto |
| 新闻/资讯 | Noto Sans SC | Oswald / Montserrat |
| 文化/深度 | LXGW WenKai / Noto Serif SC | Playfair Display |
| 娱乐/轻松 | ZCOOL KuaiLe | Poppins |
| 时尚/潮流 | ZCOOL QingKe HuangYou | Montserrat |
| 正式/商务 | Noto Sans SC | Inter |
字体在 FFmpeg 中的使用
# 下载字体后,通过 --font-path 参数指定
python3 scripts/render_final.py --config render_config.json --output final.mp4 \
--font-path fonts/LXGWWenKai-Regular.ttf
字体在 Remotion 中的使用
// 方式 1: @remotion/google-fonts(英文字体推荐)
import { loadFont } from "@remotion/google-fonts/Inter";
const { fontFamily } = loadFont();
// 方式 2: @remotion/fonts(本地/CJK 字体推荐)
import { loadFont } from "@remotion/fonts";
loadFont({
family: "LXGW WenKai",
url: staticFile("fonts/LXGWWenKai-Regular.ttf"),
format: "truetype",
});
// 方式 3: @remotion/google-fonts 加载 CJK
import { loadFont } from "@remotion/google-fonts/NotoSansSC";
const { fontFamily } = loadFont("normal", {
weights: ["400", "700"],
subsets: ["chinese-simplified"], // 重要:指定子集减小体积
});
注意事项
- CJK 字体体积大(10-20MB),使用
@remotion/google-fonts时务必指定subsets: ["chinese-simplified"]减小体积 - 字体缓存:下载的字体保存在项目
fonts/目录,.gitignore已排除 - 中国用户:字体下载自动使用 jsDelivr CDN 加速
- 商用安全:目录中所有字体均为 SIL OFL 或 Apache 2.0 许可,可免费商用
FAQ / Troubleshooting(常见问题诊断)
遇到错误时,先运行环境诊断:
python3 scripts/utils.py
Q1: No such filter: 'drawtext' 或 No such filter: 'ass'
原因:ffmpeg 编译时未包含 libfreetype(drawtext 所需)或 libass(字幕所需)。
诊断:
ffmpeg -hide_banner -filters 2>/dev/null | grep -E "drawtext|ass|subtitles"
如果无输出,说明缺少对应滤镜。
解决:
- macOS:标准
brew install ffmpeg可能不包含这些库。使用第三方 tap 安装完整版:
该 tap 默认启用brew tap homebrew-ffmpeg/ffmpeg brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-fdk-aac--enable-libfreetype --enable-libass --enable-libfontconfig。 - Linux/WSL:
apt install ffmpeg通常已包含。如果缺少,安装开发依赖后从源码编译:sudo apt install libfreetype6-dev libfontconfig1-dev libass-dev - 影响范围:缺少 drawtext 时,字幕烧录和封面文字会失败或自动降级。
Q2: Undefined constant or missing '(' in 'iw*0.5-tw/2'
原因:ffmpeg drawtext 的 x 表达式中使用了 tw(text width),但某些 ffmpeg 版本中 tw 在 x 参数的上下文中不可用。
解决:脚本已修复此问题(使用像素值 {pixel_x}-text_w/2 代替 iw*{frac}-tw/2)。如果你修改了脚本并遇到此错误,请使用 text_w 而非 tw,并确保 x 表达式中不包含 iw* 动态计算。
Q3: Invalid alpha value specifier '%{eif:...}' (drawtext fontcolor)
原因:试图在 fontcolor 参数中嵌入 %{eif} 表达式来实现透明度渐变,但 ffmpeg 不支持在颜色值中使用此语法。
解决:使用 drawtext 的 alpha 参数(独立于 fontcolor),而非试图在 fontcolor=white@'%{eif:...}' 中嵌入表达式。正确写法:
drawtext=text='hello':fontcolor=white:alpha='if(lt(t,1),t,1)'
错误写法(会报错):
drawtext=text='hello':fontcolor=white@'%{eif:if(lt(t,1),t,1):d:2}'
Q4: ffmpeg 硬件编码器失败 (h264_videotoolbox / h264_nvenc / h264_qsv 报错)
原因:检测到的硬件编码器不支持当前的视频参数(如特殊分辨率、色彩空间),或驱动版本不兼容。
诊断:
ffmpeg -encoders 2>/dev/null | grep -E "nvenc|videotoolbox|qsv|amf"
解决:在 scripts/utils.py 中临时修改 get_ffmpeg_encoder() 函数,让它直接返回 ("libx264", ["-preset", "fast", "-crf", "18"])。
Q5: 中文字幕显示为方框(豆腐块)
原因:系统中没有可用的中文字体文件。
诊断:
python3 -c "from scripts.utils import find_chinese_font; print(find_chinese_font())"
如果返回 (None, ...),说明未找到中文字体。
解决:
- macOS:系统自带 PingFang SC,一般不会出现此问题。
- Linux/WSL:安装中文字体包:
sudo apt install fonts-noto-cjk - WSL 备选:脚本会自动尝试
/mnt/c/Windows/Fonts/msyh.ttc(微软雅黑),前提是 Windows 已安装该字体。 - 手动指定:使用
--font-path /path/to/your/font.ttf参数。 - 自动下载:脚本首次运行时会尝试从 Google Fonts(中国用户使用 jsDelivr CDN)下载 Noto Sans SC,缓存到
fonts/目录。
Q6: Whisper 模型下载失败 / 超时
原因:网络问题,尤其是中国用户无法访问 HuggingFace。
解决:
- 使用
--mirror参数:python3 scripts/transcribe.py audio.wav --mirror --model auto - 或手动设置环境变量:
export HF_ENDPOINT=https://hf-mirror.com - 使用 faster-whisper 时,模型从 HuggingFace 下载;设置
HF_ENDPOINT后会自动走镜像。 - 使用 openai-whisper 时,模型从 GitHub 下载,中国用户可能需要代理。建议改用 faster-whisper。
Q7: pip install faster-whisper 安装失败 / 超时
解决:中国用户使用清华镜像:
pip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
Q8: WSL 环境下 ffmpeg 找不到或版本过旧
诊断:
which ffmpeg && ffmpeg -version | head -1
解决:
sudo apt update && sudo apt install ffmpeg
如果系统源的 ffmpeg 版本过旧(< 4.0),使用 PPA:
sudo add-apt-repository ppa:savoury1/ffmpeg4
sudo apt update && sudo apt install ffmpeg
Q9: 视频质量差 / 模糊
原因:视频经过了多次重编码,每次编码都有质量损失。
解决:必须使用 render_final.py 单次编码。检查是否在流程中使用了 split_video.py + burn_subtitles.py + merge_clips.py + generate_cover.py + add_chapter_bar.py 的旧流程(会导致 4-5 次重编码)。改用 render_final.py --config 一步到位。
Known Issues & Solutions(已知问题与解决方案)
以下问题在实际视频制作(Day 7-8)中遇到并验证了解决方案。
K1: 混合帧率源素材用 concat copy 导致视频冻结
症状:使用 ffmpeg -f concat -c copy 拼接多段 B-roll 素材后,视频在约 1 分钟处画面冻结。
根因:DJI 素材为 30/1 fps,部分 DJI 和所有 iPhone MOV 文件为 30000/1001 (29.97fps)。-c copy 拼接不会重新编码,帧率不同导致时间戳不连续,播放器在切换点卡死。
解决:用 source-bound clip assembly 在同一条输出编码里统一每段的画布、CFR、SAR、时间戳、像素格式和音频布局:
python3 scripts/clip_assembly.py plan \
origin/clip-a.MOV origin/clip-b.mp4 \
--width 1080 --height 1920 --fps 30 \
--delivery output/assembled.mp4 \
--boundary-proof verify/clip-assembly-boundaries.mp4 \
--project-dir . \
--output work/clip_assembly_plan.json
python3 scripts/clip_assembly.py apply work/clip_assembly_plan.json
完整播放交付件和全部接缝 proof,确认后再运行 confirm / verify --strict。禁止对混合帧率、画布、SAR、time base 或音频布局使用 -c copy concat。
检测方法:clip_assembly.py plan 会读取每条源片的完整 decoded best_effort_timestamp_time、媒体合同和源 hash;只看 r_frame_rate 或 FFmpeg 退出码无法证明拼接结果连续。
K2: 复杂 filter_complex 中音频被截断
症状:音频在视频中途(如 1:55 处)突然消失,画面正常继续播放。
根因:在单个 filter_complex 中同时使用 amix(混合 anullsrc 做静音填充)+ atempo(变速)+ 视频处理,amix 的 duration=longest 与合成的 null 音频源配合不可靠,导致音频流提前结束。
解决:将音频处理拆为独立步骤,不要在一个 filter_complex 中同时做音频填充+变速+视频处理:
adelay添加封面静音段atempo=1.25变速处理apad=whole_dur=X填充到目标时长- 导出为 WAV,然后用
-c:v copy -c:a aac与视频合并
原则:音频填充 + 变速 + 视频处理,三者不要放在同一个 filter_complex 中。
K3: render_final.py select filter 在大量片段时 OOM
症状:使用 render_final.py 渲染 100+ 片段(如语音旁白配 B-roll 场景)时报 "Cannot allocate memory"。
历史根因:早期 _clips_in_temporal_order() 只检查是否所有 clip 来自同一视频且时间顺序递增,不检查是否有 broll 字段。当所有 clip 引用同一个语音视频(配不同 B-roll 画面)时,仍会走 select filter 路径,生成包含 100+ 个 between() 表达式的巨型 select 过滤器,导致 OOM。
解决:
- clip 级
broll已会强制走 trim/concat,不再走 select filter。 - 对于
auto_enrich.py产出的 B-roll cue,优先用render_final.py --enrich-plan work/enrich_plan.json,它会以定时 video overlay 接入,不需要把口播切成大量小片段。 - 如果仍然手工构造 100+ 个 clip 片段,建议使用手动 ffmpeg 管线:
- 将所有 B-roll 片段统一帧率后 concat 拼接
- 单独处理音频(提取、裁切、变速、填充)
- 用
-c:v copy -c:a aac合并视频和音频
- 如果必须使用 render_final.py 的大量 clip 模式,确保片段数量在合理范围内(建议 < 50 个片段)
K4: 中文字幕中英文单词被截断
症状:字幕换行时英文单词(如 "OpenClaw"、"Claude Code")被从中间劈开。
根因:wrap_subtitle_text() 的中文模式按字符数计算行宽,将英文字母视为与汉字等宽的单个字符。在中间位置换行时不感知 ASCII 单词边界,直接截断。
解决:换行函数需要:
- 使用显示宽度计算:CJK 字符 = 1 单位,ASCII 字符约 0.5 单位
- 在查找换行点时,检测 ASCII 单词边界(连续的字母/数字视为一个词),不在英文单词或数字中间断行
- 优先在标点、空格、CJK/ASCII 边界处换行
K5: 封面/结尾卡片不出现
症状:渲染配置中配置了 end_cards,但最终视频中看不到结尾卡片。
根因:B-roll 拼接后的总时长远超所需(如实际需要 215 秒但 B-roll 拼了 431 秒)。将封面+B-roll+结尾卡片 concat 后,用 -t 参数限制总时长时,结尾卡片被截断在时长限制之外。
解决:在拼接封面和结尾卡片之前,必须先将 B-roll 精确裁切到与音频时长匹配:
# 1. 获取音频时长
audio_dur=$(ffprobe -v 0 -show_entries format=duration -of csv=p=0 audio.wav)
# 2. 裁切 B-roll 到音频时长
ffmpeg -i broll_concat.mp4 -t $audio_dur -c copy broll_trimmed.mp4
# 3. 再拼接封面 + 裁切后的 B-roll + 结尾卡片
原则:拼接前确保每个部分的时长是精确已知的,不要依赖 -t 来事后截断。
纯音频播客竖版 Audiogram
只有音频和封面、需要发短视频时,选出有完整语义的短段,准备与该摘录从 0 秒开始对齐的 SRT。若有原生视频,优先剪真实说话画面。需要新封面时优先用 Codex 内置 image_gen(GPT Image 2);已有封面直接使用。
运行 runtime_preflight.py analyze --profile podcast_audiogram --output work/runtime_preflight.json --strict,再运行 podcast_audiogram.py render origin/episode.wav origin/cover.png work/excerpt.srt --start 32 --duration 28 --output output/audiogram.mp4 --receipt verify/podcast_audiogram.json。脚本把音频、封面、字幕、设置和成片绑定,输出 720×1280 H.264/AAC、辅助声波和烧录字幕;单条最长 600 秒。podcast_audiogram.py verify verify/podcast_audiogram.json 会重查哈希、媒体规格和完整解码。ready_for_human_review 只表示技术检查通过,交付前仍须以 1× 带声看完,核对字幕与语音、封面权利与辨识度、波形位置和末尾裁切。修改任一输入后重新渲染并复核。
短动图预览 GIF
需要在聊天或文档中展示已审视频的短动作时,运行 runtime_preflight.py analyze --profile gif_preview --output work/runtime_preflight.json --strict,再运行 gif_preview.py render output/master.mp4 --start 5 --duration 3 --width 480 --fps 12 --output output/preview.gif --receipt verify/gif_preview.json。摘录限 10 秒、宽度 64–640 偶数像素、5–20 fps 和 20 MiB;FFmpeg 在同次任务中生成全片调色板并导出无声 GIF。gif_preview.py verify verify/gif_preview.json 重查源片/GIF 哈希、帧数、尺寸、时长和完整解码。交付前按真实展示尺寸看完整循环,确认动作起止、字幕可读性和色带;GIF 不含声音,视频正式发布仍用已审 MP4。
用户提供有序照片要制作回忆、旅行或产品图集短片时,先运行 runtime_preflight.py analyze --profile photo_montage --output work/runtime_preflight.json --strict,再运行 photo_montage.py render assets/01.jpg assets/02.jpg assets/03.jpg --music assets/music.wav --each 1 --transition 0.3 --zoom 1.08 --output output/montage.mp4 --receipt verify/photo_montage.json,最后运行 photo_montage.py verify verify/photo_montage.json。传入路径顺序就是播放顺序;默认普通叠化,明确需要闪白效果时加 --effect fadewhite。脚本将照片等比放大铺满画布并居中裁切,默认 1080×1920/30 fps;细节、文字或人物靠边的照片应先逐张检查构图。收据核对照片、音乐、输出哈希、精确帧数、时长和完整解码;ready_for_human_review 表示仍需正常速度看听全片,闪白效果还需运行 flash_safety_qa.py 复核。素材若由内置生图工具生成,按图像与视频工作流先处理最终位图,再用于此脚本。
已审成片叠加品牌 Logo
需要给已审 MP4 加固定 PNG Logo 时,运行 runtime_preflight.py analyze --profile logo_overlay --output work/runtime_preflight.json --strict,再运行 logo_overlay.py render output/master.mp4 media/assets/logo.png --corner bottom-right --width-fraction 0.15 --opacity 0.7 --margin 24 --output output/master-logo.mp4 --receipt verify/logo_overlay.json。宽度占画面 5%–40%,可选四角;margin 是输出像素,Logo 须完整落在画面内。脚本重新编码 H.264/yuv420p 视频、复制可选单音轨,验证帧数、时长、画布、完整解码,并用 SHA-256 绑定原片、Logo 与输出。logo_overlay.py verify verify/logo_overlay.json 现场复查;改动任何文件后重新渲染与审看。交付前以 1× 带声看完整片,检查 Logo 位置、透明度、字幕/平台 UI 遮挡和音画同步。
已审成片打包 HLS 点播
网站需要静态 HLS 点播文件时,先确认最终 MP4 已完成带声审片、音频和画质 QA。运行 runtime_preflight.py analyze --profile hls_vod --output work/runtime_preflight.json --strict,再运行 hls_vod.py package output/master.mp4 --output-dir output/hls --receipt verify/hls_vod.json --segment-seconds 6。输入限单视频、最多单 AAC 音轨、H.264/yuv420p、SDR、CFR MP4;HDR、VFR、旋转元数据和额外字幕/章节流先制作合适的 SDR/CFR master。输出目录及收据须为新路径,脚本不覆盖现有文件。
脚本按分片间隔强制关键帧并输出 index.m3u8 与 TS,hls_vod.py verify verify/hls_vod.json 现场核对每个分片首视频包是关键帧、源/输出视频帧数、播放列表时长、所有文件 SHA-256 和整条播放列表解码。它只生成单码率 VOD,未实现自适应码率或上传。部署时连同整个目录上传,配置 .m3u8 与 .ts MIME,并在目标播放器完整带声测试拖动、起止、字幕和同步;转码画质需与已审 MP4 人工 A/B。