电影感短片编辑器
将包含原始素材的文件夹和一条音乐轨道制作成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")
在节拍上剪辑(快速段落每拍,慢速段落每2或4拍)。找到音乐掉落点(能量跳变最大处),并将高潮镜头放在那里。
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": "Welcome Home", "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='Welcome Home':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)。保留旧版本以便用户比较。