電影風格短片編輯器
將一個原始素材資料夾加一首音樂曲目,轉換為長度 15–45 秒、格式 9:16、與節拍同步的電影風格短片。所有編輯皆透過命令列中的 FFmpeg 完成。剪輯計劃儲存在可編輯的編輯清單 (edl.json) 中,因此任何變更都可以重新渲染,無需從頭開始。
0. 硬性規則
- 絕對不要修改或刪除
raw/中的任何內容。所有輸出都寫入work/和out/。 - 音樂必須由使用者提供(已授權 / 免版稅)。如果
music/是空的,請要求一首曲目 — 不要下載受版權保護的音樂。 - 向使用者展示鏡頭計劃(第 4 步)並在最終渲染前獲得許可。
- 偏好硬切在節拍上。節省地使用轉場(每個短片最多 2–3 個)。
1. 檢查先決條件
ffmpeg -version && ffprobe -version
python3 -c "import librosa, numpy" || pip install librosa numpy soundfile
如果缺少 FFmpeg,請告知使用者安裝它(Windows:winget install ffmpeg,Mac:brew install ffmpeg,Linux:sudo apt install ffmpeg)並停止。
2. 資料夾結構
project/
raw/ # 相機素材(唯讀)
music/ # 一首音樂曲目
luts/ # 選用,用於調色的 .cube LUT
work/ # 縮圖、片段、edl.json、beats.json
out/ # 最終渲染(reel_v1.mp4, reel_v2.mp4 ...)
3. 盤點與檢視素材
對於每個素材,記錄其時長、解析度、幀率和方向:
ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate,codec_type -of json raw/CLIP.mp4
為每個素材製作一張聯絡表(每 2 秒一幀)並使用讀取工具檢視,以便您知道每個鏡頭中有什麼:
ffmpeg -y -i raw/CLIP.mp4 -vf "fps=1/2,scale=320:-1,tile=4x3" -frames:v 1 work/thumbs/CLIP.jpg
標記每個可用時刻:鏡頭類型(廣角 / 中景 / 特寫 / 細節)、主題、動作、品質(清晰、穩定、光線充足),以及是否能做慢動作(來源幀率 ≥ 50 fps)。
4. 建構故事(鏡頭計劃)
將每個短片結構化:
- 鉤子 (0–2 秒) — 最引人注目的鏡頭。不要有 Logo 或文字開場。
- 鋪陳 — 細節與期待(特寫、慢動作)。
- 英雄時刻 — 在最強的節拍 / 音樂高潮處。
- 情感 / 回報 — 反應、人物、慶祝。
- 結尾 (最後 2–3 秒) — 乾淨的廣角鏡頭,可選文字或 Logo,音樂淡出。
汽車交車模板(根據素材調整):外觀廣角 → Logo 特寫 → 輪胎/車燈細節 → 家庭走進來(慢動作)→ 揭幕(在高潮處)→ 鑰匙交接 → 反應/微笑 → 內裝 + 方向盤 → 蛋糕 / 花環 / 祈禱 → 開車離開(廣角,結尾)。
規則:變化鏡頭尺寸(切勿連續兩個廣角),每個鏡頭保持 0.5–2.5 秒,僅在情感或揭示鏡頭使用慢動作,盡量在動作處剪輯。
5. 節拍偵測
# work/beats.py
import librosa, json, sys
y, sr = librosa.load(sys.argv[1])
tempo, frames = librosa.beat.beat_track(y=y, sr=sr)
beats = librosa.frames_to_time(frames, sr=sr).tolist()
onset = librosa.onset.onset_strength(y=y, sr=sr)
json.dump({"tempo": float(tempo), "beats": beats}, open("work/beats.json", "w"), indent=1)
print(f"tempo {float(tempo):.1f} BPM, {len(beats)} beats")
在節拍上剪輯(快速部分在每個節拍,慢速部分在每隔一個或每四個節拍)。找到音樂高潮(能量躍升最大處)並將英雄鏡頭放在那裡。
6. 撰寫編輯清單 work/edl.json
{
"output": {"w": 1080, "h": 1920, "fps": 30},
"music": {"file": "music/track.mp3", "start": 12.0, "fade_out": 1.5},
"grade": {"lut": "luts/teal_orange.cube", "vignette": true},
"shots": [
{"id": 1, "src": "raw/C0001.mp4", "in": 4.20, "dur": 1.40, "speed": 1.0, "crop_x": "center", "note": "鉤子 – 車輛廣角"},
{"id": 2, "src": "raw/C0007.mp4", "in": 10.0, "dur": 1.00, "speed": 0.5, "crop_x": "center", "note": "輪胎慢動作"}
],
"transitions": [{"after_shot": 4, "type": "fade", "dur": 0.3}],
"text": [{"text": "歡迎回家", "start": 18.0, "end": 21.0}]
}
dur 是時間軸上的長度。當 speed 為 0.5 時,使用的來源範圍是 dur × speed 秒。在渲染前,以簡潔的表格(鏡頭、時間、描述)向使用者展示此計劃。
7. 將每個鏡頭渲染為統一的片段
每個片段必須具有相同的解析度、幀率、像素格式且無音訊,以便它們能乾淨地拼接:
# 橫向來源 → 9:16 裁切、調整速度、調色
ffmpeg -y -ss IN -t SRC_DUR -i raw/CLIP.mp4 -an -vf "\
setpts=PTS/SPEED,\
scale=-2:1920,crop=1080:1920,\
fps=30,\
lut3d=luts/teal_orange.cube,\
eq=contrast=1.06:saturation=1.10,\
vignette=PI/5,\
format=yuv420p" \
-c:v libx264 -crf 16 -preset medium work/seg_01.mp4
SRC_DUR = dur × speed。對於慢動作,使用高幀率來源;除非被要求,否則避免使用minterpolate(緩慢且有工件)。- 直向來源:使用
scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920。 - 無可用 LUT:使用
eq=contrast=1.08:saturation=1.15:gamma=0.98加上curves=preset=increase_contrast以獲得電影感外觀。 - 在 9:16 短片中不使用電影風格黑邊。
8. 拼接片段
無轉場 — 使用 concat demuxer:
printf "file 'seg_%02d.mp4'\n" 1 2 3 ... > work/list.txt
ffmpeg -y -f concat -safe 0 -i work/list.txt -c copy work/video.mp4
在兩個片段之間有轉場時,使用 xfade(偏移量 = 第一個片段的長度 − 轉場時長):
ffmpeg -y -i work/seg_04.mp4 -i work/seg_05.mp4 -filter_complex \
"[0][1]xfade=transition=fade:duration=0.3:offset=1.2,format=yuv420p" work/seg_04_05.mp4
每個轉場會縮短時間軸其持續時間 — 重新檢查節拍對齊。
9. 音樂、文字、最終匯出
ffmpeg -y -i work/video.mp4 -ss MUSIC_START -i music/track.mp3 -filter_complex \
"[1:a]afade=t=in:d=0.3,afade=t=out:st=FADE_START:d=1.5,loudnorm=I=-14:TP=-1:LRA=11[a];\
[0:v]drawtext=fontfile=FONT.ttf:text='歡迎回家':fontsize=72:fontcolor=white:\
x=(w-text_w)/2:y=h*0.72:enable='between(t,18,21)':alpha='if(lt(t,18.4),(t-18)/0.4,1)'[v]" \
-map "[v]" -map "[a]" -shortest \
-c:v libx264 -crf 18 -preset slow -profile:v high -pix_fmt yuv420p -r 30 \
-c:a aac -b:a 192k -movflags +faststart out/reel_v1.mp4
在機器上找到一個字型檔案用於 drawtext(或詢問使用者)。文字保持簡潔,位於安全區域內(避開頂部 15% 和底部 25%,那是 Instagram 介面所在位置)。
10. 品質檢查(務必執行)
ffprobe out/reel_vN.mp4→ 1080×1920,30 fps,H.264,AAC,時長如計劃。- 最終短片的聯絡表(
fps=2,scale=270:-1,tile=6x5)並檢視:無黑幀、無錯誤裁切(頭部被切掉)、色彩一致。 - 檢查音量以及英雄鏡頭是否在音樂高潮處。
- 向使用者報告:時長、鏡頭數量、檔案路徑,以及任何您不確定的部分。
11. 修訂
永遠不要從頭開始。編輯 work/edl.json(更換一個鏡頭、更改 in/dur、速度、文字、調色),僅重新渲染已更改的片段,重新拼接並匯出為下一個版本(reel_v2.mp4)。保留舊版本,以便使用者可以比較。