快速准确的视频 trim 就像使用 FFmpeg 的 Instagram Android

Fast accurate video trim like Instagram using FFmpeg Android

我知道之前有人问过这个问题,但我还找不到快速准确的解决方案,我想要 trim 最长 15 秒的视频。到目前为止,这是我尝试过的方法,我正在使用此视频作为示例:http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_30mb.mp4

最快的方式

这是迄今为止最快的方法,因为它不需要重新编码视频,但在这个视频中非常不准确,因为关键帧每隔 5-10 秒:

ffmpeg -i SampleVideo_1280x720_30mb.mp4 -ss 30 -to 50 -c copy -y out.mp4

以下是我检查此视频中关键帧的方法:

ffprobe -select_streams v -show_frames -show_entries frame=pict_type -of csv SampleVideo_1280x720_30mb.mp4 | grep -n I | cut -d ':' -f 1

通过这个命令,我发现第二个关键帧在第 211 帧,这意味着第一个关键帧和第二个关键帧之间有 210 帧,知道这是一个 25fps 视频,关键帧之间大约有 8 秒,因此 1-8 秒之间的任何剪辑都会落入其中一帧,这对于 15 秒的视频来说是一个巨大的差异。

正确的方法

这种方式是准确的,但需要重新编码视频:

ffmpeg -i SampleVideo_1280x720_30mb.mp4 -ss 30 -to 50 -preset ultrafast -y out.mp4

问题是这个命令需要超过 20 秒才能完成使用超快预设,在 samsung galaxy s6 edge plus 中,这在其他设备中可能会更多。

然而,如果我在 Instagram 中打开 SampleVideo_1280x720_30mb.mp4 并且 trim 他们会在不到 2 秒内得到准确的 trim。

我也尝试过每秒强制关键帧,但它也需要重新编码视频并且影响视频质量:

ffmpeg -i SampleVideo_1280x720_30mb.mp4 -force_key_frames "expr:gte(t,n_forced*1)" out.mp4

有谁知道 Instagram trim 视频或使用 FFMpeg 快速准确 trim 的方法吗?

我明白了 Instagram 的作用,基本上没有办法更快地准确地 trim 视频。所以为了向用户展示预览,我做了以下操作:

  • 当用户移动拇指以设置新的剪切位置时,我将视频播放器显示的当前图像截屏。

  • 用旋转器在其上面放置一个与视频播放器大小相同的 ImageView,这样视频播放器就不再可见了。

  • 将视频播放器静音并在用户所需位置之前寻找最近的关键帧。

  • 从关键帧开始播放视频,并计算从关键帧到所需位置的时间。

  • 隐藏 ImageView 并取消视频静音。

所以在我用作示例的视频中,第一个关键帧在第 0 秒,第二个关键帧在第 8 秒。假设用户想在第 3 秒进行剪辑,那么我在第二个 0 寻找关键帧并等待 3 秒,然后取消静音并显示视频。这样用户只需要等待 3 秒就可以看到预览。

真正的 trim 稍后在后台进程中创建,当用户接受预览时。