使用 ffmpeg 准确剪切视频(+ 音频)

Pet*_*key 11 audio video codec mp4 ffmpeg

我希望我的网站允许用户根据我提供的源视频准确地创建自己的剪辑。

我有一个源视频文件,我首先想将其转换为适合网站的文件:

Input #0, matroska,webm, from 'source.mkv': 
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s 
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)
Run Code Online (Sandbox Code Playgroud)

我使用 ffmpeg 像这样转换它:

ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4
Run Code Online (Sandbox Code Playgroud)

回看这段视频,它的质量足够好,文件足够小,可以满足我的需要,并且可以在我的网站上加载/播放。

我有一个网页,可让用户选择此视频的起点和终点 - 并创建剪辑。这是我为此使用的 ffmpeg 命令的示例:

-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4
Run Code Online (Sandbox Code Playgroud)

问题是剪辑并不总是足够准确。通常音频足够准确,但视频提前半秒停止。

有什么方法可以使这个准确且同步,比如 0.2 秒?

编辑:添加-force_key_frames 00:00:00.2没有帮助。

编辑:我改变了剪裁来使用,-c:v libx264 -c:a aac -strict experimental而不是-codec:v copy -codec:a copy好的(ish)结果。

该文件可以毫无问题地在外部播放 - 但是当我将它加载到我的 html5 视频元素并播放它时 - 视频的最后一部分(音频很好)冻结。冻结的最后一部分不到一秒钟。

我应该用另一个视频编码器试试吗?libx264 的最佳替代品是什么?请记住,我可能希望将其发布在公共网站上。

但是坚持下去,它可以准确地播放而没有像 MPC 或 Windows Media Player 这样的播放器出现问题的事实表明这是 Google Chrome 或 HTML 视频元素的问题吗?还是我使用了不受支持的编码或其他什么?

llo*_*gan 9

行为的-ss变化取决于它是用作输入还是输出选项,通常速度较慢,但​​在用作输出选项时可以更准确。有关更多详细信息和示例,请参阅ffmpeg 从指定时间段缓慢转换视频的答案。

要更改输出质量以source.mp4使用-crf18-28 之间的值(默认为 23)的选项。有关示例,请参阅FFmpeg 和 x264 编码指南的 CRF 部分。

您的修剪命令可以简化:

ffmpeg -ss 577.92 -i source.mp4 -ss 0 -t 11.98 -c copy -map 0 clip1.mp4
Run Code Online (Sandbox Code Playgroud)

我替换-codec:v copy -codec:a copy-c copy -map 0. 这将复制所有流,而不仅仅是第一个视频和音频流——尽管由于您之前的命令,输入只有两个流。由于您无法在不重新编码的情况下进行缩放,因此与 互斥-codec:v copy,并且由于您的输入已经缩放到设置的大小,因此我删除了过滤器选项。

如果它仍然不够准确,请尝试:

ffmpeg -i source.mp4 -ss 577.92 -t 11.98 -c copy -map 0 clip1.mp4
Run Code Online (Sandbox Code Playgroud)

它会更慢,但可能更准确。请参阅我提供的第一个链接中答案中的链接,以了解这两个示例的差异。

最后,你应该运行source.mp4通过qt-faststart(位于ffmpeg的源tools目录),或使用-movflags faststart选项。这会将一些数据重新定位到文件的开头,以便它可以在完全下载之前开始播放。

  • 使用 `-ss` 作为输出选项而不是输入选项解决了我的问题:输出视频中的第一个视频帧大约为 1s,在此之前只有音频(也由 `ffprobe -show_frames` 确认)。在`-i`之后移动`-ss`使它从第0帧开始输出音频和视频帧。 (4认同)