我认为问题在于问题和其他回答将“-ss”用作输出文件的选项,而不是输入文件的选项。 大多数ffmpeg选项不是全局的,而是仅适用于它们之前的文件。 通常不清楚选项应该放在哪里,因此有时需要尝试和错误。
如果正确使用,放在输入文件之前,“-ss”和“-t”对我来说很好用。 当在输出中包含音频时,我必须将“-shortest”用作输出文件的选项,否则我会得到2分钟的音频和2秒的视频。
ffmpeg版本N-67413-g2a88c74(基本上是从2014年12月14日的git源)。
这是我最近用于制作剪辑的命令行。 (实际上进行了调整,以便更好地说明,因为我为此保留了音频,并且没有将其减速。)
ffmpeg -ss 120.2 -t 0.75 -i ../mcdeint.60p.lossless264.slow.mkv -c:a libopus -shortest -aspect 16:9 -preset veryslow -x264-params nr = 250:ref = 6 -crf 22 -movflags + faststart clip2.mkv
使用“-c:a copy”(源具有AC3音频),播放开始时mplayer会出现问题。 它可能从包含开始的音频帧的开头获取音频,然后必须在容器中使用a / v偏移量。 在启动时,音频需要花费一小部分时间才能超过该偏移量的视频,并且在此之前,视频以非常低的FPS播放。 因此,我对音频进行了编码。 Opus和pcm_s16le都不能进入mp4,因此我在此示例中使用了mkv容器。
源是从NTSC DVD(可能来自DV相机)的BFF交错视频的非常慢的yadif = 3:1,mcdeint = 3:1:10的输出(“-qp 0”)的无损x264编码。 它不是全部I帧,而是具有正常关键帧间隔的P帧。
将-ss调整0.2秒正好达到了我所希望的效果,因此ffmpeg必须处理解码到所需点。 不仅仅是想要一个I帧的巧合。 也许“-accurate_seek”是默认值? 当我使用ffvhuff无损源作为输入时,我也获得了相同的结果(字节对字节相同的gif输出)。 (但它运行得更快,因为它不必解码到请求的点。)
另一个可能相关的选项是
-seek2any
,但它说“在 demuxer 级别上搜索到非关键帧”,听起来好像允许你以会产生损坏输出的方式进行搜索。 (即,在实际生成当前帧所需的参考帧之前开始解码,只使用全灰色?)
我没有尝试使用
-c:v copy
,因为我正在剪切一个非常短的循环片段,因此我知道不会有需要关键帧的
I
帧。
这是我实际使用的命令行,用于制作没有声音的短慢动作片段。
ffmpeg -ss 120.2 -t 0.75 -i ../vid.yadif3.1,mcdeint3.1.10.ffvhuff.mkv -an -shortest -aspect 16:9 -c:v libx264 -preset veryslow -x264-params nr=250:ref=6 -crf 22 -filter:v "setpts=3.0*PTS" -movflags +faststart -r 20 clip.mp4
请注意,
-r 20
非常重要,因为与 mkv 不同,ffmpeg 的 MP4 输出仅限于恒定帧速率(编辑:因为 mp4 复用器的默认值不是
-vsync vfr
)。如果不告诉它不同,它将设置输出 FPS = 输入 FPS,并在需要时复制帧以实现这一点。x264 和动态 gif(具有透明度)都可以非常有效地编码重复帧,但这仍然很愚蠢。
在将其烹制为示例之前,我已经分成了两步,首先输出到 mkv,然后使用
ffmpeg -i clip.mkv -c:v copy -movflags +faststart -r 20 clip.mp4
进行重新复用。顺便说一句,在复用时可以更改视频的帧率,而无需进行 xcoding,只是不能使用 ffmpeg。(
链接)。但无论如何,当制作 mkv 时,ffmpeg 只向 libx264 发送了 45 帧,即使它认为自己正在制作一个 60fps 的 2.2 秒视频。不要使用 ffmpeg 与 mp4 一起处理可变 FPS 的内容。
编辑:原来 ffmpeg 对 mkv 输出默认为
-vsync vfr
,但对 mp4 不是。使用
-vsync vfr
,ffmpeg 可以很好地将 VFR 写入 mp4 输出。
如果决定不使用 HTML5 视频放置 gif 输出,则再次运行上述命令。
ffmpeg -ss 120.2 -t 0.75 -i ../vid.yadif3.1,mcdeint3.1.10.ffvhuff.mkv -an -shortest -aspect 16:9 -filter:v "setpts=3.0*PTS,scale=854x480" -r 20 clip.gif
由于gif容器不存储宽高比,因此在播放时无法自动缩放,所以我必须使用scale=
。我的720x480像素的16:9视频在播放时被缩放为854x480。实际上应该是853.333,但这会被四舍五入,然后ffmpeg将853x480存储在mkv容器中,因此始终使用- aspect 16:9,这样我的mp4将存储正确的宽高比[SAR 32:27 DAR 16:9]
,而不是[SAR 186:157 DAR 279:157]
。