Merge multiple short video clips into one complete video, with support for transition effects and unified processing.
Features
- Sequential merging: Concatenate multiple videos in order
- Transition effects: Add transitions such as fade in/fade out
- Unified format: Ensure the output format is consistent
- Background music: Add unified background music
Usage
合并这些视频: clip1.mp4, clip2.mp4, clip3.mp4
把 ./output/shorts/ 目录下的所有短视频合并成一个
Instructions
Step 1: Prepare the file list
# 创建视频列表文件
mkdir -p ./temp
# 方式1: 指定文件
cat > ./temp/merge_list.txt << 'EOF'
file './output/shorts/clip1.mp4'
file './output/shorts/clip2.mp4'
file './output/shorts/clip3.mp4'
EOF
# 方式2: 自动扫描目录
for f in ./output/shorts/*.mp4; do
echo "file '$f'"
done > ./temp/merge_list.txt
cat ./temp/merge_list.txt
Step 2: Unify the video format
# 确保所有视频格式一致(分辨率、帧率、编码)
mkdir -p ./temp/normalized
while read -r line; do
file=$(echo "$line" | sed "s/file '//;s/'//")
if [ -f "$file" ]; then
basename=$(basename "$file")
ffmpeg -i "$file" \
-vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:-1:-1:color=black" \
-r 30 \
-c:v libx264 -preset fast -crf 23 \
-c:a aac -b:a 128k -ar 44100 \
"./temp/normalized/$basename"
fi
done < ./temp/merge_list.txt
# 更新列表
for f in ./temp/normalized/*.mp4; do
echo "file '$f'"
done > ./temp/normalized_list.txt
Step 3: Simple merge (no transitions)
# 使用 concat demuxer 直接合并
ffmpeg -f concat -safe 0 -i ./temp/normalized_list.txt \
-c copy \
./output/merged/merged_simple.mp4
echo "✅ 简单合并完成"
Step 4: Merge with transition effects
# 淡入淡出转场
# 获取视频数量和时长信息
VIDEO_COUNT=$(wc -l < ./temp/normalized_list.txt)
TRANSITION_DURATION=0.5
# 使用 xfade 滤镜添加转场
# 注意: 需要 FFmpeg 4.3+
# 对于2个视频的简单示例:
VIDEO1="./temp/normalized/clip1.mp4"
VIDEO2="./temp/normalized/clip2.mp4"
VIDEO1_DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$VIDEO1")
OFFSET=$(echo "$VIDEO1_DURATION - $TRANSITION_DURATION" | bc)
ffmpeg -i "$VIDEO1" -i "$VIDEO2" \
-filter_complex "
[0:v][1:v]xfade=transition=fade:duration=${TRANSITION_DURATION}:offset=${OFFSET}[v];
[0:a][1:a]acrossfade=d=${TRANSITION_DURATION}[a]
" \
-map "[v]" -map "[a]" \
-c:v libx264 -preset fast -crf 23 \
-c:a aac -b:a 128k \
./output/merged/merged_fade.mp4
echo "✅ 淡入淡出转场合并完成"
Step 5: Add background music
MERGED_VIDEO="./output/merged/merged_simple.mp4"
BGM_FILE="./assets/bgm.mp3"
OUTPUT="./output/merged/merged_with_bgm.mp4"
if [ -f "$BGM_FILE" ]; then
# 获取视频时长
VIDEO_DURATION=$(ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 "$MERGED_VIDEO")
# 混合音频 (原声 + BGM)
ffmpeg -i "$MERGED_VIDEO" -i "$BGM_FILE" \
-filter_complex "
[1:a]volume=0.15,aloop=loop=-1:size=2e+09[bgm];
[bgm]atrim=0:$VIDEO_DURATION[bgm_trimmed];
[0:a][bgm_trimmed]amix=inputs=2:duration=first:dropout_transition=2[a]
" \
-map 0:v -map "[a]" \
-c:v copy \
-c:a aac -b:a 128k \
"$OUTPUT"
echo "✅ 背景音乐已添加"
else
echo "⚠️ 未找到背景音乐文件: $BGM_FILE"
cp "$MERGED_VIDEO" "$OUTPUT"
fi
Step 6: Add opening and ending
INTRO="./assets/intro.mp4"
OUTRO="./assets/outro.mp4"
MAIN="./output/merged/merged_simple.mp4"
FINAL="./output/merged/final.mp4"
# 创建包含片头、主体、片尾的列表
cat > ./temp/final_list.txt << EOF
file '$INTRO'
file '$MAIN'
file '$OUTRO'
EOF
# 先标准化格式
for f in "$INTRO" "$MAIN" "$OUTRO"; do
if [ -f "$f" ]; then
basename=$(basename "$f")
ffmpeg -i "$f" \
-vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:-1:-1" \
-r 30 -c:v libx264 -preset fast -crf 23 \
-c:a aac -b:a 128k -ar 44100 \
"./temp/final_$basename"
fi
done
# 合并
ffmpeg -f concat -safe 0 -i ./temp/final_list.txt \
-c copy \
"$FINAL"
Available transition effects
Transition types using the xfade filter:
| Effect | Description |
|---|---|
| fade | Fade in/out |
| wipeleft | Wipe left |
| wiperight | Wipe right |
| wipeup | Wipe up |
| wipedown | Wipe down |
| slideleft | Slide left |
| slideright | Slide right |
| slideup | Slide up |
| slidedown | Slide down |
| circlecrop | Circle crop |
| rectcrop | Square crop |
| distance | Distance transform |
| fadeblack | Fade through black |
| fadewhite | Fade through white |
| radial | Radial transition |
| smoothleft | Smooth left shift |
| smoothright | Smooth right shift |
Output
- Simple merge:
./output/merged/merged_simple.mp4 - With transitions:
./output/merged/merged_fade.mp4 - With background music:
./output/merged/merged_with_bgm.mp4 - Final version:
./output/merged/final.mp4
Directory structure
./output/
├── shorts/ # 原始短视频片段
├── merged/ # 合并后的视频
└── thumbnails/ # 封面图
./assets/
├── intro.mp4 # 片头
├── outro.mp4 # 片尾
└── bgm.mp3 # 背景音乐