这里,FFmpeg 中的新增功能。我正在 FFmpeg 的控制台中使用和测试。
我已经完成了 2 个带有交叉淡入淡出的视频连接,并解决了这个问题: 我正在对 5 个视频进行交叉淡入淡出合并,我刚刚完成了 90% 的合并 我只需要管理 setpts=PTS-STARTPTS 请查看这个。
ffmpeg -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i
big_buck.mp4 -filter_complex "[0:v]trim=0:4,setpts=PTS-
STARTPTS,fade=out:st=4:d=1:alpha=1[1]; [1:v]trim=1:4,setpts=PTS-
STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1,fade=out:st=4:d=1:alpha=1[2];
[2:v]trim=1:4,setpts=PTS-
STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1,fade=out:st=4:d=1:alpha=1[3];
[3:v]trim=1:4,setpts=PTS-
STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1,fade=out:st=4:d=1:alpha=1[4];
[4:v]trim=1:4,setpts=PTS-STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1[5];
[1][2]overlay,format=yuv420p[12]; [12][3]overlay,format=yuv420p[123]; [4]
[5]overlay,format=yuv420p[45]; [123][45]concat=n=2 [v]" -map [v] result.mp4
****请注意,每个输入视频 big_buck.mp4 长度均为 5 秒 ****。现在请参阅代码中的 setpts=PTS-STARTPTS 如何在每个视频输入中管理它???
我也在各个论坛上看到过相关内容,但我没有找到! 谢谢你
使用
ffmpeg -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i
big_buck.mp4 -filter_complex \
"[0:v]setpts=PTS-STARTPTS[v1]; \
[1:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(4/TB)[v2];
[2:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(8/TB)[v3];
[3:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(12/TB)[v4];
[4:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(16/TB)[v5];
[v1][v2]overlay[v12]; [v12][v3]overlay[v123]; [v123][v4]overlay[v1234]; [v1234][v5]overlay,format=yuv420p[v]" \
-map [v] result.mp4
必须修改 PTS,以便每个新剪辑在当前剪辑组合结束前 1 秒开始,即第三个剪辑应在 8 秒时开始淡入,因为前两个剪辑的组合为 9 秒(第一个剪辑的 4 秒)剪辑 + 1 秒过渡 + 4 秒第二个剪辑)。
您不需要淡出,因为下一个剪辑会在顶部淡入。仅当您想要剪切时才需要连接。
音频交叉淡入淡出:
ffmpeg -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i
big_buck.mp4 -filter_complex \
"[0:v]setpts=PTS-STARTPTS[v1]; \
[1:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(4/TB)[v2];
[2:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(8/TB)[v3];
[3:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(12/TB)[v4];
[4:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(16/TB)[v5];
[v1][v2]overlay[12]; [12][v3]overlay[123]; [123][v4]overlay[1234]; [1234][v5]overlay,format=yuv420p[v]; \
[1][2]acrossfade=d=1[a12]; [a12][3]acrossfade=d=1[a123]; [a123][4]acrossfade=d=1[a];" \
-map [v] -map [a] result.mp4
基于 Gyan 的 answer,我创建了一个方便的 Bash 脚本
video_crossfade.sh
来交叉淡入淡出任意数量的不同持续时间的视频。
#!/bin/bash
INPUT="$1"
CMD="ffmpeg"
SIZE=$(find . -iname "$INPUT" | wc -l)
if (( SIZE < 2 ))
then
echo "2 or more videos are required"
exit 1
fi
VIDEO=""
OUT=""
i="0"
total_duration="0"
for file in $(find . -iname "$INPUT" | sort)
do
echo $file
CMD="$CMD -i $file"
duration=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of csv=p=0 "$file" | cut -d'.' -f1)
if [[ "$i" == "0" ]]
then
VIDEO="[0:v]setpts=PTS-STARTPTS[v0];"
else
fade_start=$((total_duration-$i))
VIDEO="${VIDEO}[${i}:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(${fade_start}/TB)[v${i}];"
if (( i < SIZE-1 ))
then
if (( i == 1 ))
then
OUT="${OUT}[v0][v1]overlay[outv1];"
else
OUT="${OUT}[outv$((i-1))][v${i}]overlay[outv${i}];"
fi
else
if (( SIZE == 2 ))
then
OUT="${OUT}[v0][v1]overlay,format=yuv420p[outv]"
else
OUT="${OUT}[outv$((i-1))][v${i}]overlay,format=yuv420p[outv]"
fi
fi
fi
total_duration=$((total_duration+duration))
i=$((i+1))
done
CMD="$CMD -filter_complex \"${VIDEO}${OUT}\" -c:v libx264 -map [outv] crossfade.MP4"
echo "$CMD"
bash -c "$CMD"
示例:
./video_crossfade.sh '*.MP4'
结果:
该脚本通过通配符模式获取所有视频形式,并使用
ffprobe
来获取视频时长。
您可以在 FFmpeg 5 视频合并中设置宽度和高度
ffmpeg -i 1699476962.mp4 -i 1699860586.mp4 -i 1699752055.mp4 -i 1699860586.mp4 -i 1699752055.mp4 -filter_complex "[0:v]scale=240:320[v0];[1:v]scale=240:320[v1];[2:v]scale=240:320[v2];[3:v]scale=240:320[v3];[4:v]scale=240:320[v4];[v0][v1][v2][v3][v4]xstack=inputs=5:layout=0_0|w0_0|w0+w1_0|0_h0|w0_h0:fill=black[outv];[0:a][1:a][2:a][3:a][4:a]amix=inputs=5[a]" -map "[outv]" -map "[a]" -ac 2 240x320.mp4