解説動画全自動編集(剪映ルート不使用)
解決する問題
ユーザーが解説動画を録画した後、「書き起こし→訂正→無音除去→つっかえ・繰り返し削除→間違い箇所の訂正→完成品出力」までの全チェーンを自動化します。剪映を開かずに、そのまま公開可能な完成品(ハード字幕焼き込み + 上部黄背景の訂正テロップ付き)を出力。パラメータ(フォントサイズ/削除区間/テロップ文章)を変更したい場合、JSON を編集してスクリプトを再実行するだけで、反復コストは 1 分です。
jianying-subtitle-fixer との役割分担:そちらは剪映の下書きを修正(ユーザーが手動でエクスポートする必要あり)、こちらは ffmpeg で直接完成品を出力。ユーザーが剪映に言及していなければこちらを使用します。
環境依存(ローカル環境で既に準備済み)
- Python:
C:\Users\44162\AppData\Local\Programs\Python\Python312\python.exe(faster-whisper 1.2.1 + torch インストール済み;モデルキャッシュは ~/.cache/huggingface、small モデルあり) - ffmpeg:
D:\ソフトウェア\ffmpeg\bin\ffmpeg.exe(スクリプトが自動検出)
標準ワークフロー(AI はこの順に従う)
Step 0 ffprobe で動画の長さ/解像度を取得(後続のフォントサイズ自動調整用)
Step 1 書き起こし:transcribe.py -> raw.json(文+単語レベルのタイムスタンプ)
Step 2 AI 分析(本スキルの核心価値、下記参照)-> cut_plan.json を生成
Step 3 コンテンツ削除項目について AskUserQuestion でユーザーに確認(一度にすべて質問し、小出しにしない)
Step 4 レンダリング:render.py --plan cut_plan.json -> 完成品
Step 5 フレーム抽出による品質チェック(訂正テロップの時間帯から各1フレーム抽出し、Read+視覚確認で文字が完全かつ画面からはみ出ていないことを確認)
Step 6 納品:何を削除したか、何を訂正したか、ファイルの場所を報告
Step 1 書き起こしコマンド
& "C:\Users\44162\AppData\Local\Programs\Python\Python312\python.exe" "<skill>/scripts/transcribe.py" --video "<動画パス>" --outdir "<作業ディレクトリ>" --prompt "XXX、YYYなどのテーマに関する中国語技術チュートリアル"
--prompt には動画のテーマ+高頻度用語(用語集 ~/.claude/skills/jianying-subtitle-fixer/config/terms.json から取得)を指定すると、固有名詞の認識率が大幅に向上します。作業ディレクトリ推奨:D:\コンテンツ制作システム\編集\workspace\<日付-job>\。
Step 2 AI 分析(人手では代替不可の工程、方法論は references/cut-heuristics.md 参照)
raw.json 全文を読み、以下の 4 項目を出力:
- 字幕修正 fixed:同音異義語や用語の聞き間違いを 1 行ずつ修正。口語の原文はそのまま維持し、誤りのみ訂正(字幕は音声に合わせるため、書き換えると音と画が一致しなくなる)。whisper の誤認識パターンは references 参照。
- コンテンツ削除 content_cuts:丸ごと削除すべき部分(タイムコード+理由)、種類と判定基準は references 参照。 単語レベルの繰り返し(文中「一篇文章を…一篇文章を」など)は words タイムスタンプで正確に特定。
- deleted_ids:content_cuts に含まれる字幕行の ID(これらの行は字幕に出力しない)。
- 訂正テロップ corrections:事実誤認がある段落に対する、動画上部の黄色テロップ。cut_plan.json に書き込む。
Step 3 ユーザー確認(原則)
- 明確に削除すべきもの(つっかえ・言い直し・言い間違いの出だし・途中で言いやめた部分):直接計画に組み込み、報告時に説明するのみ
- 内容に誤りがある段落:ユーザーに確認「削除しますか?/残して訂正テロップを入れますか?」。意見に関する内容は残して訂正テロップを入れる傾向
- 訂正テロップの文章、事実確認の結論(Web で確認が必要な場合は先に WebSearch で原文を探す)はすべてユーザーに確認
- AskUserQuestion で確認すべき項目を一度にすべて質問する
Step 4 レンダリングコマンド
& "C:\Users\44162\AppData\Local\Programs\Python\Python312\python.exe" "<skill>/scripts/render.py" --plan "<作業ディレクトリ>/cut_plan.json"
cut_plan.json の形式(render.py の先頭コメントに完全な説明あり):
{
"video": "C:/元動画.mp4",
"out": "C:/完成品.mp4",
"raw": "raw.json",
"content_cuts": [[213.45, 230.98, "実験の転述が間違い"]],
"deleted_ids": [48, 49, 50],
"fixed": {"1": "修正後テキスト"},
"corrections": [[12.95, 20.14, "訂正:正しい名称はXXです"]],
"silence": {"min_dur": 1.0, "keep": 0.25},
"style": {"sub_size": 64, "cor_size": 48}
}
すべてのタイムコードは元動画のタイムライン基準(スクリプトが自動的に編集後のタイムラインに再マッピング)。silence/style は省略可能。字幕スタイルはデフォルトでモバイル向け大文字(2560 幅基準で 64/48、解像度に応じて自動等比拡大縮小)。ユーザーが「フォントが小さい」と言ったら style の数値を調整して再実行。
Step 5 フレーム抽出による品質チェック
final.ass から訂正テロップの実際の時間(Cor 行)を読み取り、新しいタイムラインでフレーム抽出:
& "D:\ソフトウェア\ffmpeg\bin\ffmpeg.exe" -y -i "<完成品>" -vf "select='eq(n\,<フレーム番号>)',scale=1100:-1" -vsync vfr "<qcディレクトリ>/qc_%d.jpg"
フレーム番号 = 秒 × 20fps。1フレームずつ Read+視覚確認:文字が完全、画面からはみ出していない、下部字幕と重なっていないこと。
ハマりポイント(血と涙の記録、踏まないこと)
- aselect による無音削除の失敗:一部の AAC ストリームで aselect が 1 フレームも削除せずエラーも出さない → 音声削除は必ず
asplit+atrim+concatを使用(render.py に組み込み済み、aselect に戻さないこと) - concat は単一ストリームの select の後にパディング結合器として使用できない(パッド数不一致でエラー);select+setpts はそれ自体が連続出力
- 完成品の検証は必ず ffprobe で映像/音声の両ストリームを個別に確認:format の duration は長い方のストリームに引き伸ばされ、「編集されていない」事実を隠してしまう(実例:レンダリング「成功」だが音声はすべてそのまま)
- subtitles フィルタのパス:ass ファイルはレンダリングのカレントディレクトリからの相対パスを使用し、中国語パスのエスケープ問題を回避
- 無音削除には単語保護区間が必要(render.py に strip_guard として組み込み済み):whisper の単語タイムスタンプと silencedetect の結果にはズレがあり、小さな声の単語(文頭の英単語など)が「無音」と判定されることがあり、そのまま無音削除すると単語の一部が切れる
- 書き起こしスクリプトは ffmpeg stderr に対して GBK エラーハンドリングを実施(Windows のエンコーディング問題、このスレッドのエラーは無視してよい)
反復コスト
フォントサイズ変更/訂正テロップ文章変更/削除区間の追加・削除 → cut_plan.json の該当フィールドを編集して render.py を再実行、1 回 1〜2 分。完成品は上書き保存、元動画は決して変更しません。