在关键帧之间剪切视频而不使用ffmpeg重新编码完整视频?

Posted

技术标签:

【中文标题】在关键帧之间剪切视频而不使用ffmpeg重新编码完整视频?【英文标题】:Cut a video in between key frames without re-encoding the full video using ffpmeg? 【发布时间】:2020-12-12 07:49:06 【问题描述】:

我想在任何特定时间戳的开头剪切视频,并且它需要精确,因此最近的关键帧不够好。

此外,这些视频相当长 - 一个小时或更长时间 - 所以我想尽可能避免重新编码,否则只重新编码总时长的一小部分.于是,想最大限度地利用-vcodec copy

如何使用ffmpeg 完成此操作?

注意:请参阅场景,以及我自己对以下可能解决方案的粗略想法。


场景:

原创视频 1:00:00 的长度 每 10 秒有一个关键帧 所需切割: 从 0:01:35 到结束 尝试 #1: 使用-ss 0:01:35 -i blah.mp4 -vcodec copy,结果是一个文件,其中: 音频从 0:01:30 开始 视频也从 0:01:30 开始 这太早了启动音频和视频 使用-i blah.mp4 -ss 0:01:35 -vcodec copy,结果是一个文件,其中: 音频从 0:01:35 开始, 但视频在前 5 秒内为空白/黑色, 直到 0:01:40,视频开始时 这会准时启动音频, 但视频开始太晚了

粗略的想法

(1) 将 0:01:30 剪切到 0:01:40 重新编码以获得新的关键帧, 包括一个在目标时间 0:01:35 然后剪掉它以获得从 0:01:35 到 0:01:40 的 5 秒 (2) 将 0:01:40 切到最后 无需重新编码,使用-vcodec copy (3)ffmpeg concat第一个短片(第5个第二个) 与第二个长剪辑

我知道/可以计算出 (2) 和 (3) 的命令,但不确定 (1) 需要哪些命令。

【问题讨论】:

请注意,在我的情况下,使用带有 mp4 容器的编辑列表不是一个选项,因为目标视频播放器以及我在后处理此视频时的后续步骤 这可以帮助 - ***.com/questions/18444194/… 要指定关键帧间隔(GOP 大小),请使用 -g 标志。 trac.ffmpeg.org/wiki/EncodingForStreamingSites 【参考方案1】:

列出关键帧的时间戳:

ffprobe -v error -select_streams v:0 -skip_frame nokey -show_entries frame=pkt_pts_time -of csv=p=0 input.mp4

它会输出如下内容:

0.000000
2.502000
3.795000
6.131000
10.344000
12.554000
16.266000
...

假设您要删除时间戳 0 到 5,然后删除 stream copy 其余部分。紧随其后的关键帧是 6.131。

将 5 重新编码为 6.131。确保输入和输出匹配属性和格式。对于 MP4 的默认设置应该完成大部分工作,假设 H.264/AAC,但您可能必须manually match the profile。

ffmpeg -i input.mp4 -ss 5 -to 6.131 trimmed.mp4

input.txt 设为concat demuxer:

file 'trimmed.mp4'
file 'input.mp4'
inpoint 6.131

连接:

ffmpeg -f concat -i input.mp4 -c copy output.mp4

【讨论】:

这看起来符合我的要求。我按照链接在您的答案中匹配个人资料,但无法弄清楚如何使用它。执行此操作时,您输出修剪文件的ffmpeg 命令会是什么。可能是-v:profile copy 之类的? @bguiz 使用 ffmpeg 查看输入并查找 Video: h264 (High)() 可能包含 Baseline 或 Main 而不是 High。如果是这种情况,请添加 -profile:v main-profile:v baseline。如果它是高,你不需要做任何额外的事情。或者使用 ffprobe 查找配置文件:ffprobe -v error -select_streams v -show_entries stream=profile -of csv=p=0 input.mp4。并非所有格式都有配置文件。【参考方案2】:

试试

ffmpeg -i src.mp4 -vcodec copy -reset_timestamps 1 -map 0 out.mp4

ffmpeg -i src.mp4 -vcodec copy -reset_timestamps 1 -map 0 src_.m3u8

生成 hls 播放列表

【讨论】:

以上是关于在关键帧之间剪切视频而不使用ffmpeg重新编码完整视频?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制ffmpeg编码时输出一个关键帧

在特定时间准确剪切视频而不会降低质量

在特定时间准确剪切视频而不会降低质量

使用 FFMPEG 以最少的重新编码添加覆盖

使用ffmpeg编码时,如何设置恒定码率,并控制好关键帧I帧间隔

视频精准剪切总结