我正在尝试从视频文件中删除一个片段 (00:26:00 - 00:32:30) input.mp4
。
由于没有办法直接使用 ffmpeg 来做到这一点(据我所知),所以我改为剪切输出中想要的片段,然后将它们连接起来。
经过一番搜索,我发现有两种方法可以做到这一点:
不幸的是,这两种方法对我来说都失败了。
我将解释我在这两种方法中执行的步骤:
1.使用trim
:
编辑:此方法现在有效;跳至第二种方法。
使用的命令:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]trim=duration=00:26:00[a]; \
[0:v]trim=start=00:32:30,setpts=PTS-STARTPTS[b]; \
[a][b]concat[c]" -map [c] out.mp4
命令输出:关联
输出文件长度不到 1 分钟,大小仅为 6.8 MB,而输入文件则为 900 MB。
2. 使用seek
使用的命令:
# Cut first wanted segment
ffmpeg -ss 00:00:00 -i input.mp4 -t 00:26:00 -c copy -avoid_negative_ts 1 first.mp4
# Cut second wanted segment
ffmpeg -ss 00:32:30 -i input.mp4 -c copy -avoid_negative_ts 1 second.mp4
# Combine all the wanted segments
ffmpeg -f concat -i input.txt -c copy output.mp4
其中input.txt
包含:
file first.mp4
file second.mp4
命令输出:关联(第 90 行提到错误input.txt: Invalid argument
:)
在这种情况下我得到的输出文件只有大约 500 MB(输入文件为 900 MB),并且包含第一个视频 + 第二个视频的前几分钟。
我的系统详细信息:
Ubuntu 14.04
ffmpeg 版本:关联
编辑:
方法 1trim
现在可以使用,这要感谢 @Mulvya 关于将秒作为时间单位而不是 HH:MM:SS 符号的评论破碎的。
新命令:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]trim=duration=1500[av]; \
[0:a]atrim=duration=1500[aa];\
[0:v]trim=start=1980,setpts=PTS-STARTPTS[bv]; \
[0:a]atrim=start=1980,asetpts=PTS-STARTPTS[ba];\
[av][bv]concat[outv]; [aa][ba]concat=v=0:a=1[outa]" \
-map [outv] -map [outa] out.mp4
但是,我还是想知道第二种方法有什么问题。
答案1
修剪过滤器不适用于 HH:MM:SS现在。以秒为单位指定。此方法会重新编码视频,因此质量会降低。您可以指定 CRF 值,例如,-crf 20
用于控制质量。较低的值会产生更好的质量,但文件会更大。18 到 28 是一个不错的尝试范围。
至于第二种方法,请尝试在文本文件中指定切点,即
file 'input.mp4'
duration 1560
file 'input.mp4'
inpoint 1980
然后运行
ffmpeg -f concat -i input.txt -c copy -fflags +genpts -avoid_negative_ts make_zero output.mp4
文本文件的相关选项是如下:
duration
inpoint
outpoint