FFmpeg分割视频并合并回


8

我正在尝试使用FFmpeg根据某些视频start_timeend_time输入分割视频,并用其他视频文件替换这些视频。例如,对于输入,10 15我需要将EXACT秒替换10 to 15为另一个视频。

好。我想到的是:

  1. 首先分割视频(在这种情况下,为0-10、10-15和15端)
  2. 将10-15替换为其他视频
  3. 合并所有子视频

第一个问题:这是最好,最快的解决方案吗?我们是否有更简单的命令或其他工具将视频中的特定时间段替换为另一个视频?

第二个问题:假设FFmpeg是可行的解决方案,当我仅使用命令时ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4,我的视频处理代码无法读取和处理文件。我使用mediainfo工具比较了两个文件,并注意到在所有与视频编解码器相关的内容相同的情况下,标头大小有所不同。我注意到HEADER SIZE不同,这显然是导致问题的原因。有什么方法可以强制标头大小(除了编解码器)相同?

更新:这是原始.mp4文件,可以在模拟器中正常工作。


首先,我们必须处理您在第二个问题中提到的问题。请显示您正在使用的确切命令以及从ffmpeg获得的完整,未剪切的命令行输出。还显示读取文件时遇到的任何实际错误-最好确切地知道您的“处理代码”是什么。
slhck

@slhck视频处理代码是一个巨大的代码库。我不能分享。只是出于某种原因,原始文件被读取,但是重新生成的文件却未被读取。但是,.mp4如果需要,我可以共享原始文件。
Ariana

我使用mediainfo工具比较了两个文件,并注意到标头大小和内容有所不同
Ariana

拥有原始版本会有所帮助,但是恐怕我们无法解决为什么无法读取它的问题,如果那是一些内部代码。
slhck

@slhck我上传了文件。我的问题已更新
Ariana

Answers:


9

使用trimconcat–源文件使用不同的编解码器

为此,请确保您的单个文件具有相同的分辨率,理想情况下应具有相同的帧率和色度二次采样等。这将防止在连接期间出现错误或毛刺。

使用trimconcat过滤器,您可以一次性完成所有操作而无需拆分文件:

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

在这里,trim用于指定的输入视频流(的各个部分0:v1:v),您以后想连接。这些部件被命名为v0通过v2。(setpts过滤器将这些各个部分的时间戳重置为0,这是串联所必需的)。稍后,我们将这三个部分串联起来。

如果要从某个时间戳记修剪到结尾,请使用trim=start=15而不是指定范围。

如果文件中有音频,则必须分别修剪这些流:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

请注意,在这种情况下,视频和音频将被重新编码–确保指定适当的输出质量目标(例如,-crf针对x264,x265或libvpx-vp9)。您可以在FFmpeg Wiki上阅读有关此内容的更多信息,例如VP9H.264

使用个别区隔

如果要拆分片段,然后再重新组装它们:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

如果文件有音频,请使用与上述相同的方法:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

这将再次重新编码视频流。它稍微简单一点,但其他方面应等同于上述方法。

使用解concat复用器

原则上,您也可以使用concat多路分配器尝试连接比特流,而无需重新编码。创建一个名为的文件concat.txt并添加以下条目(对应于上面创建的视频剪辑):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

然后串联这些单独的文件:

ffmpeg -f concat -i concat.txt -c copy output.avi

但是,这要求您的剪辑具有相同的编解码器,分辨率,帧速率等–因此,它不适用于所有种类的异构源。

使用concat协议

上述类型的文件级串联也可以使用该concat协议来实现,并且具有与上述相同的约束(相同的编解码器,分辨率等):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

有关串联的更多信息,请阅读相应的FFmpeg Wiki页面


这看起来很完整!谢谢。我会尝试的!
阿里亚纳

idk为什么使用该concat方法会引发错误:[concat @ 00000000025c2560] Line 1: unknown keyword 'part1.mp4 \\ text.txt: Invalid data found when processing input
Ariana

对于“使用单个段”,我看到了停顿并小幅切出了输出。有什么办法可以解决这个问题?
Ariana

方法1完美工作。一件事:我们如何在不说明特定数字(而不是30秒)的情况下指定“直到结束”
Ariana

1
抱歉,犯了一个错误。对于解concat复用器,语法是不同的。立即修复。要使用到最后,请使用trim=start=15,请参阅修剪过滤器文档:ffmpeg.org/ffmpeg-filters.html#trim-关于计时问题,这实际上取决于您的原始资料。虽然与您上传的剪辑连接时没有问题。
slhck
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.