加入片頭與片尾 是做什麼的?
片頭和片尾是短小的 MP4 檔案,各自附帶專屬的音效,並按照影片方向分成配對,列在偏好設定中。此技能會將所有內容標準化為統一格式,將片頭、主影片和片尾以短暫的淡入淡出(視訊和音訊)連接起來,並輸出最終結果。
偏好設定
remote-video-editing/preferences.json(查詢順序與 clean-voice-sidon 相同):
| 鍵 (Key) | 值 (Value) |
|---|---|
stings | {"intro_16x9": url, "outro_16x9": url, "intro_9x16": url, "outro_9x16": url};URL 或本機路徑 |
sting_fade_s | 交叉淡入淡出長度,預設值 0.5 |
render_notes | 去哪執行長時間編碼(例如在伺服器而非筆電上)。請遵循這些指示。 |
如果 stings 未設定,請詢問使用者提供檔案。此外掛程式不附帶任何品牌資產。
方向
讀取顯示的方向,而非編碼的尺寸:手機錄製的直式影片通常儲存為 1920x1080,並帶有旋轉標籤。請使用以下指令檢查:
ffprobe -v error -select_streams v:0 -show_entries stream=width,height:stream_side_data=rotation -of compact IN。
旋轉角度為 90 或 -90 時,會交換寬度和高度。ffmpeg 在解碼時會自動套用旋轉。
- 直式 (9:16) 影片:使用
intro_9x16/outro_9x16,畫布為 1080x1920。 - 橫向 (Landscape) 影片:使用 16:9 配對,畫布為 1920x1080。
- 直式影片的 16:9 裁切版(適用於 YouTube 主要動態消息):畫布為 1920x1080,主影片高度縮放至 1080 並置中,覆蓋在經過模糊、變暗、縮放的自身副本之上;使用 16:9 的片頭片尾。下方的
[v1]鏈變成:
請先用一個 8 秒的片段進行測試([1:v]fps=30,split[a][b]; [a]scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080,scale=480:270,boxblur=20:2,scale=1920:1080,eq=brightness=-0.06:saturation=0.9[bg]; [b]scale=-2:1080[fg];[bg][fg]overlay=(W-w)/2:0,setsar=1,format=yuv420p[v1]-ss 60 -t 8),並在渲染整個影片前先顯示一個畫面。
渲染
W:H 是畫布尺寸,F 是淡入淡出長度 (0.5),DI 是片頭持續時間,DV 是主影片持續時間(使用 ffprobe 的 format=duration)。
偏移量:第一次淡入淡出位於 DI-F;第二次位於 DI+DV-2*F。
ffmpeg -y -i intro.mp4 -i main.mp4 -i outro.mp4 -filter_complex "
[0:v]fps=30,scale=W:H,setsar=1,format=yuv420p[v0];
[1:v]fps=30,scale=W:H:force_original_aspect_ratio=decrease,pad=W:H:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p[v1];
[2:v]fps=30,scale=W:H,setsar=1,format=yuv420p[v2];
[0:a]aresample=48000,aformat=channel_layouts=stereo[a0];
[1:a]aresample=48000,aformat=channel_layouts=stereo[a1];
[2:a]aresample=48000,aformat=channel_layouts=stereo[a2];
[v0][v1]xfade=transition=fade:duration=F:offset=DI-F[v01];
[v01][v2]xfade=transition=fade:duration=F:offset=DI+DV-2*F[v];
[a0][a1]acrossfade=d=F[a01];[a01][a2]acrossfade=d=F[a]" \
-map "[v]" -map "[a]" -c:v libx264 -preset medium -crf 20 -maxrate 10M -bufsize 20M -c:a aac -b:a 192k -movflags +faststart out.mp4
- 多個來源片段:請先將它們合併(使用相同濾鏡模式,或如果它們共用編碼格式,則使用
concat分離器),然後將結果視為main.mp4。 - 這是完整的重新編碼:處理一個 10 分鐘的 1080p 影片會耗費數分鐘的所有核心運算。請在 Modal 上執行,不要在本機或家用伺服器上執行:將輸入後面的引數(從
-filter_complex到+faststart)逐行放入render.args,然後執行$MODAL run "${CLAUDE_PLUGIN_ROOT}/scripts/ffmpeg_modal.py" --inputs intro.mp4,main.mp4,outro.mp4 --args-file render.args --out out.mp4(偏好設定中的modal_command和run_notes會指定 Modal 的執行位置)。在同一個圖形(使用concat濾鏡)中合併多個片段,不要分成獨立步驟。完成後,刪除video-editing-work磁碟區中該工作的資料夾。 xfade需要兩個輸入使用相同的時間基準:請在每個視訊分支上加上fps=30,settb=1/30(包括concat之後),否則 ffmpeg 會失敗並顯示「First input link main timebase (1/30) do not match」。- 位元率:保持上限(
-crf 20 -maxrate 10M -bufsize 20M)。對雜訊較多的手機影片使用純 CRF 18 會產生約 24 Mbps 的位元率,11 分鐘的影片約為 2 GB(2026-11-13)。YouTube 無論如何都會重新編碼,並建議 1080p 上傳使用 8-12 Mbps。 - 驗證:輸出時長約為
DI + DV + DO - 2*F,並檢查DI-F/2(淡入淡出中間點)、影片中間和結尾的畫面。
手持拍攝畫面:在同一個渲染中進行穩定
手持拍攝的手機影片受益於輕度穩定(使用者回饋,2026-11-13,在第一次 Hebrish 週末更新發布後發現缺少此功能)。使用 ffmpeg 的 vid.stab(libvidstab;Debian 的 ffmpeg,也就是 Modal 映像中安裝的版本,包含此功能;使用 ffmpeg -filters | grep vidstab 檢查)。雙通道,皆在 Modal 上執行:
- 偵測 (Detect)(快速,僅分析,寫入一個轉換檔案),每個來源片段:
ffmpeg -i main.mp4 -vf vidstabdetect=shakiness=5:accuracy=15:result=main.trf -f null -將其作為獨立的ffmpeg_modal.py任務執行(引數-vf/vidstabdetect=...:result=/work/<job>/main.trf/-f/null,輸出-),或在腳本中加入偵測步驟。.trf檔案必須與輸入檔案放在同一磁碟區中。 - 轉換 (Transform) 在主渲染中執行,對應影片分支的最先處理項目,在調整和縮放之前:
vidstabtransform=input=main.trf:smoothing=20:zoom=2:optzoom=0,unsharp=5:5:0.4smoothing設為 15-30 幀可以保留自然動態;使用固定的zoom=2(百分比)來隱藏移動邊框,避免optzoom=1在拍攝頭部講話時造成的跳動感。輕度unsharp可以補償重新取樣造成的柔化。
先以一個 8 秒的片段進行測試,並在完整渲染前,與使用者一起比較靜態畫面與短片段。如果缺少 libvidstab,deshake 是一個單通道的備選方案(效果較弱)。此用途不需要 AI 穩定器。
製作片頭片尾
目前使用的片頭片尾是透過一個小型 Pillow 腳本加上產生的音效,從品牌 SVG 渲染而來。請使用 find-script(標籤為 logo、sting、intro)尋找該腳本,不要使用影片模型重新生成標誌:影片模型會扭曲字型形狀。