叠帧 · 數字序列圖像 → 封面影片
概述
掃描資料夾,僅保留檔名為純數字的檔案(01.jpg、200.jpg),依數字順序播放,並編碼為 H.264 MP4。圖片之間可使用硬切(--transition none)或淡入淡出(--transition fade,預設值)。非數字命名的圖片(如 logo、discord……)及既有的影片檔會被忽略。
流程
- 先檢查資料夾內容。列出檔案,並用 ffprobe 探測其中一張圖片的尺寸。記錄有多少張數字序列的靜態圖片,以及畫面寬高比是否混合。
- 備份既有的輸出檔案。如果
<資料夾>/cover.mp4已存在,在渲染前將其重新命名為cover.prev-YYYYMMDD.mp4。切勿靜默覆蓋使用者先前的渲染結果。 - 使用內建指令稿進行渲染:
python "<技能目錄>/scripts/imgseq2mp4.py" --dir "<資料夾>" --out cover.mp4
預設值:每張圖片 0.8 秒,搭配 0.2 秒的 fade 淡入淡出,30 fps,1920×1080,letterbox 填充,CRF 18,無音訊,+faststart。
- 驗證,而非假設。探測長度/影格數,確認無黑畫面,並提取最後一個影格與最後一張來源圖片比對:
ffprobe -v error -show_entries format=duration -show_entries stream=nb_frames -of default=nw=1 cover.mp4
ffmpeg -i cover.mp4 -vf blackdetect=d=0.05:pix_th=0.10 -an -f null -
ffmpeg -y -sseof -0.05 -i cover.mp4 -frames:v 1 frame_last.png
啟用轉場時,也應抓取第一個轉場視窗內的影格,確認其為混合狀態(比硬切更接近第二張圖片,但仍與兩張來源圖片有明顯差異)。
- 報告影像張數、被忽略的圖片、總時長、輸出路徑與檔案大小。
節奏
總長度 = n × 秒數 − (n−1) × 轉場秒數。每張圖片的螢幕停留時間為 秒數 − 轉場秒數;這個停留時間,而不是 --seconds,才是使用者實際感受的節奏。
| 每張圖片停留時間 | 指令 | 20 張 | 44 張 | 200 張 |
|---|---|---|---|---|
| 0.35 秒 | --seconds 0.5 --transition-seconds 0.15 | ~8 秒 | ~18 秒 | ~75 秒 |
| 0.45 秒 | --seconds 0.65 --transition-seconds 0.2 | ~9 秒 | ~22 秒 | ~95 秒 |
| 0.60 秒 (預設) | --seconds 0.8 --transition-seconds 0.2 | ~12 秒 | ~27 秒 | ~120 秒 |
| 0.80 秒 | --seconds 1.0 --transition-seconds 0.2 | ~16 秒 | ~34 秒 | ~150 秒 |
硬切使用 --transition none --seconds <停留時間>。
當使用者要求加快或減慢時,一次移動一個列。將 --transition-seconds 保持在 0.15–0.2 秒之間;更長的時間會讓影片感覺像幻燈片,而非淡入淡出。
規則
- 僅使用交叉淡出(淡入淡出)。不要使用滑動、掃描或其他推壓轉場——這些已被拒絕。
- 以正則表達式
^\d+\.(jpe?g|png|webp)$進行選取——檔名必須僅包含數字。這會排除logo.jpg、discord.jpg、cover.jpg。 - 依整數值排序,而非字典序(
2.jpg應在10.jpg之前,99.jpg應在100.jpg之前)。編號中有間隔是正常的;缺少數字並非錯誤。 - 使用
--fit pad(預設值)以保持整個畫面可見。僅當使用者明確要求邊到邊裁剪時,才使用--fit fill。 - 輸出無音軌。除非使用者提供音軌,否則不要添加音樂。
- 保持色彩不變。JPEG 為全色域;若將其編碼為未標記的全色域 H.264,大多數解碼器會以有限色域解碼,導致畫面看起來更亮且褪色(+10 階)。該指令稿會轉換為有限色域 BT.709 並加上標記——請不要「簡化」這個處理鏈。
- 該指令稿在未使用
--force的情況下拒絕覆蓋--out;請透過備份來解決,而非直接強制覆蓋。
機器注意事項
- ffmpeg 不在 PATH 中。該指令稿偏好使用真正的
ffmpeg.exe(~/.dsh/tools/ffmpeg/**/ffmpeg.exe,其次在C:/或D:/ffmpeg下的副本),而非任何.cmd替身,因為替身會經由 cmd.exe 路由,並將命令列長度限制在約 8k 字符。可透過FFMPEG=/path/to/ffmpeg覆蓋。 - 此建置缺少
-filter_complex_script;需透過-filter_complex內聯傳遞 xfade 圖(該指令稿已這樣做)。 - 轉場以
--chunk(預設 6)為一組進行渲染,然後合併,因此最多同時開啟 6 個解碼器。單次 44 輸入的 xfade 傳遞在 16 GB 的機器上消耗了所有 RAM(約剩 2.4 GB)並因Cannot allocate memory而失敗;請勿在此環境下將--chunk提高到約 8 以上。分組會遞迴進行,因此 200 張圖片會在三個階段內合併,不會超出記憶體。 - 中間階段檔案以 CRF 14 / veryfast 編碼並被丟棄;只有最終傳遞使用
--crf/ medium。 - 中間檔案需要一個可寫入的目錄。
tempfile.mkdtemp()的結果在受限沙盒中可能無法存取(在 Windows + DSH 上觀察到:ffmpeg 出現Permission denied,os.listdir引發WinError 5)。因此該指令稿會建立一個普通目錄,確認其可寫入,並依序回退至$IMGSEQ_WORKDIR→ 系統暫存 →<輸出目錄>/.imgseq-work。
資源
scripts/imgseq2mp4.py— 選取、數字排序、硬切或淡入淡出渲染、便於驗證的摘要。