今天遇到了ffmpeg截取的音频时间不正常的问题,明明只截取了10秒钟音频,但是总时长是全视频的24分钟显示出来。实际上是因为metadata没有跟着裁剪修改的原因。
我当时执行的命令是这样的
ffmpeg -i input.mkv -ss 10 -to 20 -vn -acodec copy out.flac
结果生成的flac时间是整个视频的时间,说明metadata是照搬视频的时长
ss 在i前面和在i后面的区别
在ffmpeg,seek要用到的参数是-ss
,设置起始时间。
-ss
放在-i
的前面和后面的效果是不一样的。
因为和ffmpeg的运行机制有关,放在i前面的部分,会在加载视频文件之前进行,这个seek运用了关键帧快速定位,因此可能会有几秒的误差,
如果在i前面seek,相当于把视频先删除ss前面的部分。此时如果在后面再进行截取0的时间戳就是前面ss的点。
ffmpeg -ss 00:23:00 -i Mononoke.Hime.mkv -frames:v 1 out1.jpg
当我i们把时间戳放在i后面,此时会逐帧读取视频,这个过程非常慢,但是会更精确一点。
ffmpeg -i Mononoke.Hime.mkv -ss 00:23:00 -frames:v 1 out2.jpg
上面两种都是截取20:00的帧为图片
我们也可以把两种位置的ss结合起来
下面的表示先把视频 22:30前的部分切掉,然后把这个切掉的点 作为0,接着往后截图。
ffmpeg -ss 00:22:30 -i Mononoke.Hime.mkv -ss 00:00:30 -frames:v 1 out3.jpg
解决方法
我发现问题主要还是flac容器的问题,这个容器的裁切没有写metadata。
但是mka作为一个通用的音频容器他是会帮你写的,所以我选在ss写在i后面,这个时候to用来表示结束的时间,因为在导入之后的查找还是比较精确的。
如果ss在i前,你最适合的还是用t来表示延续的时长,因为在前表示在导入前就裁切了。
另外还有一些选项:
-
-copyts
这个选项会保留原来的时间戳。 -
-avoid_negative_ts 1
当你对直播流视频进行裁剪的时候,可以用这个选项。
所以ss写在i的后面(增加精度)。用mka容器是一个不错的方法。
网友评论