講解影片全自動剪輯(無剪映路線)
解決什麼問題
用戶錄完講解影片後,把「轉寫→糾錯→去停頓→刪卡殼重複→更正講錯處→出片」整條鏈 全自動化。全程不打開剪映,產物是可直接發布的成片(硬字幕已燒錄 + 頂部黃底更正條)。 改任何參數(字號/剪除段/文案)改完重跑腳本即可,迭代成本一分鐘。
與 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 分析(本 skill 的核心價值,見下)-> 寫 cut_plan.json
Step 3 內容刪減項 AskUserQuestion 讓用戶拍板(一次問完,別擠牙膏)
Step 4 渲染:render.py --plan cut_plan.json -> 成片
Step 5 抽幀質檢(更正條時間點各抽一幀,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 全文後產出四樣東西:
- 字幕糾錯 fixed:逐條改同音錯字/術語誤聽。保持口語原文,只糾錯不潤色 (字幕貼語音,改寫會造成音畫不匹配)。whisper 誤聽規律見 references。
- 內容剪除 content_cuts:整段該刪的(時間碼+理由),類型與判定標準見 references。 詞級重複(句內「發了一篇…發了一篇」)用 words 時間戳精確定位。
- deleted_ids:content_cuts 覆蓋的字幕條 id(這些條不進字幕)。
- 更正條 corrections:講錯事實的段落,畫面頂部黃條。寫成 cut_plan.json。
Step 3 用戶拍板(原則)
- 明確該剪的(卡殼重說/口誤起頭/半句棄說):直接列入方案,彙報時說明即可
- 講錯內容的段落:問用戶「刪掉 / 保留+更正條」,觀點性內容傾向保留+更正
- 更正條文案、事實核查結論(需聯網核實的先 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。逐幀 Read + 視覺檢查:文字完整、不超寬、不與底部字幕打架。
坑檔案(血淚,勿踩)
- aselect 靜默失效:部分 AAC 流上 aselect 一幀不剪且不報錯 → 音訊剪除
必須用
asplit+atrim+concat(render.py 已內置,別改回 aselect) - concat 不能接在單流 select 後當拼接器(pad 數不匹配報錯); select+setpts 本身輸出就連續
- 成片校驗必須分別 ffprobe 影片/音訊兩流:format duration 會被較長流 撐回原時長,掩蓋「根本沒剪」的假象(踩過:渲染「成功」實則音訊全保留)
- subtitles 濾鏡路徑:ass 與渲染 cwd 一致用相對路徑,避免中文路徑轉義坑
- 靜音剪除必須過詞保護區(render.py 內置 strip_guard):whisper 的詞 時間戳與 silencedetect 有出入,輕聲詞(如句首英文術語)可能落在「靜音」裡, 直接按靜音剪會切掉半個詞
- 轉寫腳本對 ffmpeg stderr 做 GBK 容錯(Windows 編碼老坑,忽略該執行緒報錯即可)
迭代成本
改字型大小/改更正文案/增刪剪除段 → 改 cut_plan.json 對應欄位重跑 render.py, 一次 1-2 分鐘。成片覆蓋寫,原片永不動。