开源或活跃的开发者社区经常需要在线发布大型视频片段。 (聚会视频、露营、技术讲座...)由于我是一名开发人员而不是摄像师,我不想在高级 Vimeo 帐户上花费额外的费用。那么如何将 12.5 GB (1:20:00) MPEG 技术讲座视频分割成 00:10:00 片段以便轻松上传到视频共享网站?
答案1
ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment output%03d.mp4
请注意,这不会为您提供准确的分割,但应该适合您的需求。相反,它将在 后指定的时间后的第一帧处剪切segment_time
,在上面的代码中它将在 20 分钟标记之后。
如果您发现只有第一个块可以播放,请尝试-reset_timestamps 1
按照评论中所述添加。
ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment -reset_timestamps 1 output%03d.mp4
答案2
$ ffmpeg -i source-file.foo -ss 0 -t 600 first-10-min.m4v
$ ffmpeg -i source-file.foo -ss 600 -t 600 second-10-min.m4v
$ ffmpeg -i source-file.foo -ss 1200 -t 600 third-10-min.m4v
...
将其包装到脚本中以循环执行并不困难。
请注意,如果您尝试根据调用的持续时间输出来计算迭代次数,ffprobe
则这是估计的除非您给出参数,否则会根据剪辑开头的平均比特率和剪辑的文件大小来计算-count_frames
,这会大大减慢其操作速度。
-ss
另一件需要注意的事情是命令行上选项的位置事情。我现在的速度很慢但很准确。链接的文章描述了快速但不准确和较慢但仍然准确的替代公式。您为后者付出了一定的复杂性。
抛开这些不谈,我不认为你真的希望每个剪辑都精确地剪辑 10 分钟。这会在句子甚至单词的中间进行剪切。我认为您应该使用视频编辑器或播放器来查找间隔不到 10 分钟的自然切换点。
假设您的文件采用 YouTube 可以直接接受的格式,则无需重新编码即可获取片段。只需将自然剪切点偏移传递给ffmpeg
,告诉它使用“复制”编解码器将编码的 A/V 不受影响地传递:
$ ffmpeg -i source.m4v -ss 0 -t 593.3 -c copy part1.m4v
$ ffmpeg -i source.m4v -ss 593.3 -t 551.64 -c copy part2.m4v
$ ffmpeg -i source.m4v -ss 1144.94 -t 581.25 -c copy part3.m4v
...
该-c copy
参数告诉它将所有输入流(音频、视频和可能的其他流,例如字幕)按原样复制到输出中。对于简单的 A/V 程序,它相当于更详细的标志-c:v copy -c:a copy
或旧式标志-vcodec copy -acodec copy
。当您只想复制其中一个流但重新编码另一个流时,您可以使用更详细的样式。例如,许多年前,QuickTime 文件的常见做法是使用 H.264 视频压缩视频,但将音频保留为未压缩的PCM;如果您今天遇到这样的文件,您可以对其进行现代化改造,-c:v copy -c:a aac
仅重新处理音频流,而使视频保持不变。
第一个命令之后的每个命令的起点是前一个命令的起点加上前一个命令的持续时间。
答案3
只需使用 ffmpeg 内置的内容即可完成此操作。
ffmpeg -i invid.mp4 -threads 3 \
-vcodec copy -f segment -segment_time 10:00 \
-reset_timestamps 1 \
cam_out_h264_%02d.mp4
这会将其分割成大约 10 分钟的块,在相关关键帧处分割,并将输出到文件
cam_out_h264_01.mp4
、cam_out_h264_02.mp4
等。
答案4
如果你想创建真正相同的块,必须强制 ffmpeg 在每个块的第一帧上创建 i-frame,这样你就可以使用此命令创建 0.5 秒的块。
ffmpeg -hide_banner -err_detect ignore_err -i input.mp4 -r 24 -codec:v libx264 -vsync 1 -codec:a aac -ac 2 -ar 48k -f segment -preset fast -segment_format mpegts -segment_time 0.5 -force_key_frames "expr: gte(t, n_forced * 0.5)" out%d.mkv