内容来源于 Stack Overflow,遵循 CC BY-SA 4.0 许可协议进行翻译与使用。IT领域专用引擎提供翻译支持
腾讯云小微IT领域专用引擎提供翻译支持
我需要合并多个视频文件(包括音频)为一个单一的视频。我注意到xfade最近发布并使用了它,但我遇到了音频同步问题。
对于视频和音频,所有视频都是相同的格式/分辨率/名气和比特率/等等。
这是我用来合并0.5个交叉淡入淡出过渡的5个不同持续时间的视频:
ffmpeg \ -i v0.mp4 \ -i v1.mp4 \ -i v2.mp4 \ -i v3.mp4 \ -i v4.mp4 \ -filter_complex \ "[0][1]xfade=transition=fade:duration=0.5:offset=3.5[V01]; \ [V01][2]xfade=transition=fade:duration=0.5:offset=32.75[V02]; \ [V02][3]xfade=transition=fade:duration=0.5:offset=67.75[V03]; \ [V03][4]xfade=transition=fade:duration=0.5:offset=98.75[video]; \ [0:a][1:a]acrossfade=d=0.5:c1=tri:c2=tri[A01]; \ [A01][2:a]acrossfade=d=0.5:c1=tri:c2=tri[A02]; \ [A02][3:a]acrossfade=d=0.5:c1=tri:c2=tri[A03]; \ [A03][4:a]acrossfade=d=0.5:c1=tri:c2=tri[audio]" \ -vsync 0 -map "[video]" -map "[audio]" out.mp4
上面的代码生成了一个带有音频的视频。第一段和第二段与音频对齐,但从第二个过渡开始,声音未对齐。
自动化该过程将有助于处理计算偏移量时的错误。我创建了一个Python脚本来进行计算,并为任意大小的输入视频列表构建图形: https://gist.github.com/royshil/369e175960718b5a03e40f279b131788 它将检查视频文件的长度(使用 ffprobe )来计算正确的偏移量。问题的关键是构建过滤器图并计算偏移量:
ffprobe
# Prepare the filter graph video_fades = "" audio_fades = "" last_fade_output = "0:v" last_audio_output = "0:a" video_length = 0 for i in range(len(segments) - 1): # Video graph: chain the xfade operator together video_length += file_lengths[i] next_fade_output = "v%d%d" % (i, i + 1) video_fades += "[%s][%d:v]xfade=duration=0.5:offset=%.3f[%s]; " % \ (last_fade_output, i + 1, video_length - 1, next_fade_output) last_fade_output = next_fade_output # Audio graph: next_audio_output = "a%d%d" % (i, i + 1) audio_fades += "[%s][%d:a]acrossfade=d=1[%s]%s " % \ (last_audio_output, i + 1, next_audio_output, ";" if (i+1) < len(segments)-1 else "") last_audio_output = next_audio_output
它可以生成一个过滤器图,例如
[0:v][1:v]xfade=duration=0.5:offset=42.511[v01]; [v01][2:v]xfade=duration=0.5:offset=908.517[v12]; [v12][3:v]xfade=duration=0.5:offset=1098.523[v23]; [v23][4:v]xfade=duration=0.5:offset=1234.523[v34]; [v34][5:v]xfade=duration=0.5:offset=2375.523[v45]; [v45][6:v]xfade=duration=0.5:offset=2472.526[v56]; [v56][7:v]xfade=duration=0.5:offset=2659.693[v67]; [0:a][1:a]acrossfade=d=1[a01];