程序 FFmpeg 准确切割视频问题,请大神指教?

2021-11-30 09:58:49 +08:00
 qin20

如题,我在项目开发过程中,使用 FFmpeg 来批量处理视频,但是发现 FFmpeg 剪切的视频并不能按照传参的开始时间和结束时间去切割视频,原因是关键帧的问题,比如我需要切割 5 到 7 秒的视频片段

ffmpeg -i a.mp4 -ss 00:00:05 -to 00:00:07 -c copy -o out.mp4

FFmpeg 会自动寻找5秒和7秒附近的关键帧,并从关键帧的位置去切割,导致视频最终的时间可能是00:00:04 ~ 00:00:06这种,导致切出来的视频有时候声音被切了一半

我知道在切割的时候使用重新编码可以准确切割,但是重新编码遇到几个 G 的视频文件时,切割两秒的视频,就需要处理好几分钟,在批量切割的需求下(几百个视频片段),完全达不到性能要求

我想知道这几个问题:

  1. 有没有一款软件可以替代 FFmpeg 实现准确切割的功能
  2. 如果使用 FFmpeg ,能不能拿到 FFmpeg 它实际切割的关键帧的时间,这样方便我快速重新编码调整切割的误差
8771 次点击
所在节点    FFmpeg
67 条回复
qin20
2021-11-30 14:34:56 +08:00
@xuhaoyangx 最后合成的时候也要进行一次切割的吧,这个时候可以保证精准吗
qin20
2021-11-30 14:37:43 +08:00
@xuhaoyangx 我只了解大概,因为刚接触视频处理一个多月,看了一些文章,GOP 、IDR 和 PTS, DTS 很多概念还是很模糊
xuhaoyangx
2021-11-30 14:38:21 +08:00
@qin20 所以他们合成用的时有损压缩,只不过调用了硬件编码而已
xuhaoyangx
2021-11-30 14:39:46 +08:00
无损切割,只能切 I 帧,但是绝大多数视频,i 帧只占少数部分,P B 才是多数。这就是 copy 为啥不能精确切割的问题,你的时间码,正好可能是 P B 帧。

如果你要做剪影哪一类的软件,那么你现在的思路就是错的
misdake
2021-11-30 14:47:34 +08:00
@qin20 默认不指定 copy 就是重新编码的,而且输出正好是 1 秒钟,共 61 帧数据。
需要把-ss 和-to 放在-i 前面,这样时间修饰的是输入,会跳过前面的编码,只编码制定的区间。
放在-i 后面就变成修饰输出了,不符合你的需求,会导致要全编码一遍然后在输出的地方截断。
qin20
2021-11-30 14:51:41 +08:00
@xuhaoyangx 哦哦,我怀疑有没有一种可能剪影它在视频轨道上显示用图片显示出来的,都是 I 帧,所以用户切的时候,都是在切 I 帧

我现在软件功能都 ok 了,采用的也是类似有损压缩的方式,但是这种方式需要用户提前把视频编码成全部是 I 帧的,比较麻烦,现在就一个难点,就是这个切割时间问题
xuhaoyangx
2021-11-30 15:00:53 +08:00
@qin20 所有的剪辑软件,都不会再编辑时期,去操作原视频,只是记录用户对视频文件的操作,最终导出,才会操作
zzfer
2021-11-30 15:04:48 +08:00
研究过,除非重新编码切割,不然无法做到完全精准,这样做就是慢,但是是和切割的视频时长有关,如果只要三分钟的话,也没太慢。或者网上有人说用 openCV 切割视频,FFmpeg 切割音频,然后合并,但没试过。
mxalbert1996
2021-11-30 15:08:47 +08:00
https://trac.ffmpeg.org/wiki/Seeking
建议读一下这个了解一下 Input Seeking 和 Output Seeking 的区别。
Sasasu
2021-11-30 15:38:42 +08:00
-i 前后各加一个 -ss
q197
2021-11-30 15:42:39 +08:00
@anzu 越后面越慢是 ffmpeg 使用的经典错误,-ss 要放在-i 前面,否则意思是处理视频直到-ss 处才开始输出,而正确的意思是从-ss 处开始处理且输出
qin20
2021-11-30 17:44:50 +08:00
@misdake 作为输入参数会跳过开始片段,作为输出参数就会重新编码全部,但是这两种做法,都无法做到精确切割,我都尝试过了
qin20
2021-11-30 17:45:40 +08:00
@Sasasu 还有这种骚操作?
qin20
2021-11-30 17:48:21 +08:00
@xuhaoyangx 是的,我也想到了不应该频繁的去操作原视频,只是我的功能比较特殊,需要实时的预览,涉及到字幕、声音、图片等都要同步,所以索性直接当场合成了,现在用户用的反馈还算可以
qin20
2021-11-30 17:50:29 +08:00
@coderluan 我发现我做的软件竟然和这个有点类似,卧槽了。。。
digimoon
2021-11-30 18:38:04 +08:00
粗切,精确切重编码头尾,再将头尾和中间大段拼起来
mxalbert1996
2021-11-30 18:51:12 +08:00
摘录我上面发的链接里的一句话:
As of FFmpeg 2.1, when transcoding with ffmpeg (i.e. not just stream copying), -ss is now also "frame-accurate" even when used as an input option.
如果楼主发现实际行为不是这样的话(可能性很小,这么常用的功能有 BUG 的话应该早修了),请去提一个 BUG 。
wudicgi
2021-11-30 19:38:12 +08:00
lossless-cut 我试过好几次了,很早的时候试过,几个月前也试过,就没有真正可用过

现在自己试下来,唯一能用的是 Bandicut, 需要付费购买
不过对我来说它的最大问题是没有命令行支持
所以为了自动化,我最终是写了个 AutoHotkey 脚本自动操作它的 GUI 来完成批量工作的
wudicgi
2021-11-30 19:39:30 +08:00
对了,Bandicut 快速模式只有头尾需要进行一些操作,中间部分不要重编码,所以很快
royzxq
2021-11-30 19:56:09 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/818943

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX