背景:
我有一个 HSBS 3D 视频,它在某些点损坏了,即在某些特定时间点,缺少一些帧。现在我想以一种我将要解释的方式修复它(至少让它看起来更好)。我获得了一个完整的相同视频的 2D 版本。我的计划是将 3D 视频的损坏部分移到最近的关键帧,并在水平堆叠后用 2D 版本的相应部分替换它们(我在这里称之为“补丁”)。由于我不想重新编码整个 100 分钟的 3D 视频,因此需要对补丁进行类似于 3D 部分的编码,然后将其与它们连接起来而无需重新编码。
2D 视频的分辨率、视频比特率和音频比特率将更改为与 3D 相似(1920x1080,v:2113kbps 和 a:95kbps)。其他属性相似。
我一直使用的代码如下:
ffmpeg -i 2D.mp4 -filter_complex "[0:v]trim=start=60:end=62,setpts=PTS-STARTPTS,scale=960:1080,split[v0a][v0b];
[0:a]atrim=start=60:end=62,asetpts=PTS-STARTPTS[a0];[v0a][v0b]hstack[stv]" -map "[stv]" -map "[a0]"
-vcodec libx264 -preset slower -tune animation -b:v 2100k -acodec aac -b:a 95k patch.mp4
ffmpeg -i "concat:3Dpart1.mp4|patch.mp4|3Dpart2.mp4" -c copy fixed.mp4
上述代码运行良好,但由于寻找剪切流的精确时刻的过程需要对 2D 和 3D 视频进行大量的反复试验,因此我更喜欢在一行中运行所有试验。因此,我的问题如下:
问题:
是否可以在过滤器复合体的中间对上述“补丁”进行编码,以便我可以用单个命令包装整个过程?像这样:
ffmpeg -i "2D.mp4" -i "3Dpart1.mp4" -i "3Dpart2.mp4"
-filter_complex "[0:v]trim=start=60:end=62,setpts=PTS-STARTPTS,scale=960:1080,split[v0a][v0b];
[v0a][v0b]hstack,>>>BITRATE_CONTROL<<<[patchv];
[0:a]atrim=start=60:end=62,asetpts=PTS-STARTPTS,>>>BITRATE_CONTROL<<<[patcha];
[1:v][1:a][patchv][patcha][2:v][2:a]concat=n=3:v=1:a=1[v][a]" -map "[v]" -map "[a]" fixed.mp4
滤波器复合体省略了 3D 视频的修剪,以消除不必要的复杂性。
答案1
不。比特率是一个编码参数,与过滤无关,过滤仅对未压缩的帧起作用。(此外,您提议的命令也是对 3D 部分进行重新编码。)
似乎最好使用段复用器使用 将 3D 和 2D 视频分割成一系列 MPEG-TS 片段,-c copy
同时保留时间戳-copyts
。识别 3D 系列中损坏部分的片段。识别 2D 系列中的对应部分,然后修剪、过滤并重新编码它们。编解码器、像素格式和分辨率应该相同,比特率不必相同。然后将旧的 3D + 新的 2D MPEG-TS 片段连接成 MP4。跳过这些步骤中的音频(-an
)。最终拼接视频准备就绪后,将整个旧 3D 音频混编到拼接文件中。