这似乎是一个常见的问题,但我找到的答案似乎并不适用于我的情况。
我正在将 6 个视频(其中一个是循环播放的短背景)合并为 1 个输出视频,音频和视频略有偏差(可能相差四分之一秒)。这是我的命令行:
ffmpeg -y
-ss 0.2 -i "One.MOV"
-ss 3.2 -i "Two.MOV"
-i "Three.mp4"
-ss 1.9 -i "Four.mp4"
-ss 1.9 -i "Five.MOV"
-stream_loop 180 -i "Background.mp4"
-filter_complex "
nullsrc=size=1920x1080 [back];
[5:v] scale=1920x1080 [fred];
[back][fred] overlay=shortest=1:x=0:y=0 [base];
[0:v] crop=1312:1080:290:0,scale=576x474 [clip0];
[0:a]volume=1.7[aud0];
[1:v] crop=1080:1056:0:864,scale=497x486 [clip1];
[1:a]volume=4.8,aresample=async=1:first_pts=0[aud1];
[2:v] scale=576x324 [clip2];
[2:a]volume=2.0,aresample=async=1:first_pts=0[aud2];
[3:v] crop=673:720:322:0,scale=454x486 [clip3];
[3:a]volume=6.9,aresample=async=1:first_pts=0[aud3];
[4:v] crop=720:921:0:359,scale=380x486 [clip4];
[4:a]volume=4.9,aresample=async=1:first_pts=0[aud4];
[base][clip0] overlay=shortest=1:x=32:y=83 [tmp0];
[tmp0][clip1] overlay=shortest=1:x=711:y=27 [tmp1];
[tmp1][clip2] overlay=shortest=1:x=1312:y=158 [tmp2];
[tmp2][clip3] overlay=shortest=1:x=93:y=567 [tmp3];
[tmp3][clip4] overlay=shortest=1:x=770:y=567 [tmp4];
[aud0][aud1][aud2][aud3][aud4]amix=inputs=5[a]
" -map "[tmp4]" -map "[a]" -c:v libx264 "Output.mp4"
我猜这与 aresample 和 first_pts 有关,但我一直在阅读文档,却无法弄清楚我需要做些什么不同的事情。
我如何才能使音频和视频同步?
编辑
注:“Three.mp4”为钢琴伴奏;其他曲目均为个人歌手,在钢琴伴奏下加入自己的声音。
答案1
我建议制作一个脚本,以便您可以逐个包含文件,以找出哪个文件有故障。
在新文件夹中创建文件,结构如下:test1.mov test1.ss test1.filterv test1.filtera 等等。
test1.ss 带有“0.2”
test1.filterv 带有“crop=1312:1080:290:0,scale=576x474”
test1.filtera 的“volume=1.7”
ETC...
#!/bin/bash
SUM="$(ls test*.mov test*.mp4 | wc -l)"
echo inputs = $SUM
BOX=1
while [ "$((BOX*BOX))" -lt "$SUM" ]; do ((BOX=BOX+1)); done
echo boxsize = "${BOX}x${BOX}"
WID=640
HEI=360
POX=0
POY=0
INP=()
FCT=-1
FSC=""
FLV=""
FLA=""
AUD=""
BAK="bg"
IFS=$'\n'
for f in $(ls test*.mov test*.mp4); do
echo $f
SSI="${f%.*}.ss"
echo $SSI
if [[ -f "$SSI" ]]; then
INP+=("-ss")
INP+=($(<"${SSI}"))
fi
INP+=("-i")
INP+=("$f")
((FCT+=1))
if [ "$POX" -ge "$BOX" ]; then
POX=0
((POY+=1))
fi
((x=POX*WID))
((y=POY*HEI))
((POX+=1))
SSI="${f%.*}.filterv"
echo $SSI
if [[ -f "$SSI" ]]; then
FIL=($(<"${SSI}"))
else
FIL=""
fi
if [ "$FIL" != "" ]; then
FSC+="[${FCT}:v:0]${FIL}"
SC1="${FCT}sca"
FSC+="[${SC1}]; "
else
SC1="${FCT}:v:0"
fi
FLV+="[${BAK}][${SC1}]overlay=x=${x}:y=${y}"
if [ "$FCT" -eq 0 ]; then
FLV+=":eof_action=endall"
fi
BAK="${FCT}v0"
FLV+="[${BAK}]; "
SSI="${f%.*}.filtera"
echo $SSI
if [[ -f "$SSI" ]]; then
FIL=$(<"${SSI}")","
else
FIL=""
fi
FLA+="[${FCT}:a:0]${FIL}aresample=async=1:first_pts=0[${FCT}a0]; "
AUD+="[${FCT}a0]"
done
((FCT+=1))
((POX=BOX*WID))
((POY=POY*HEI+HEI))
ffmpeg "${INP[@]}" -filter_complex "color=size=${POX}x${POY}[bg]; ${FSC} ${FLV} ${FLA} ${AUD} amix=inputs=${FCT}[a]" -map "[${BAK}]" -map [a] -c:v h264_nvenc -cq 20 -c:a aac -q:a 4 -y output.mkv
逐个添加文件。
答案2
我建议您使用一些具有舒适 GUI 的程序。
这是因为你似乎并不完全确定你的输出何时开始不同步。具有图形界面的程序,例如大胆,应该可以帮助您有效地解决问题。
关于您的具体问题,请注意:您是否考虑过可能存在不同的驱动程序和每秒帧数编码问题?如果这是原因,您很少能排除问题,方法是首先尝试使用相同的音频/视频编码(包括每秒帧数)转换它们,检查同步,然后将它们合并在一起...