使用 ffmpeg 分割 mkv 但丢失了几秒钟的视频(在关键帧之间切换而不重新编码?)

使用 ffmpeg 分割 mkv 但丢失了几秒钟的视频(在关键帧之间切换而不重新编码?)

我正在使用 ffmpeg(来自 FFmpeg 的真正版本,而不是来自 Libav 的假版本)来分割一些 mkv 文件:

ffmpeg -i input.mkv -ss 00:01:00 -to 00:02:00 -codec copy output.mkv

但是,当我使用 VLC 打开 output.mkv 时,前几秒没有视频,只有音频。几秒钟后,我可以看到视频和音频。有趣的是,当我在 -ss 参数后尝试不同的时间戳时,“仅音频”部分的持续时间从 1 秒到 4 秒甚至更长不等。

我尝试使用mkvmerge--split "timecodes:00:01:00,00:02:00"输出文件运行良好,开头没有“仅音频”部分。

我尝试了不同的 mkv 容器并使用不同的视频/音频编码,但结果相同。

我认为我遗漏了 ffmpeg 的一些选项。我应该在 ffmpeg 命令行中添加什么来避免出现几秒钟的“仅音频”部分?

更新 1

完整的输出如下:

$ ffmpeg -i 21.mkv -ss 00:00:58 -to 00:02:00 -codec 复制剪辑.mkv
ffmpeg 版本 2.2.2 版权所有 (c) 2000-2014 FFmpeg 开发人员
  于 2014 年 5 月 7 日 13:08:45 使用 gcc 4.8.2 (GCC) 20140206 (预发布) 构建
  配置:--prefix=/usr --disable-debug --disable-static --enable-avresample --enable-dxva2 --enable-fontconfig --enable-gnutls --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libv4l2 --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-pic --enable-postproc --enable-runtime-cpudetect --enable-shared--enable-swresample--enable-vdpau--enable-version3--enable-x11grab
  libavutil 52. 66.100 / 52. 66.100
  libavcodec 55. 52.102 / 55. 52.102
  libavformat 55. 33.100 / 55. 33.100
  libavdevice 55. 10.100 / 55. 10.100
  libavfilter 4. 2.100 / 4. 2.100
  libavresample 1.2.0 / 1.2.0
  libswscale 2. 5.102 / 2. 5.102
  libswresample 0. 18.100 / 0. 18.100
  libpostproc 52. 3.100 / 52. 3.100
输入 #0, matroska,webm, 来自‘21.mkv’:
  元数据:
    编码器:libebml v1.3.0 + libmatroska v1.4.0
    创作时间:2014-05-07 01:47:41
  时长:00:42:50.78,开始:0.000000,比特率:2833 kb/s
    流 #0:0(eng):视频:h264(高)、yuv420p(tv、bt709)、1280x720、SAR 1:1 DAR 16:9、23.98 fps、23.98 tbr、1k tbn、47.95 tbc(默认)
    流 #0:1:音频:ac3、48000 Hz、5.1(侧面)、fltp、384 kb/s(默认)
输出 #0,matroska,至‘clip.mkv’:
  元数据:
    编码器:Lavf55.33.100
    流#0:0(eng):视频:h264(H264 / 0x34363248),yuv420p,1280x720 [SAR 1:1 DAR 16:9],q=2-31,23.98 fps,1k tbn,1k tbc(默认)
    流 #0:1:音频:ac3 ([0] [0][0] / 0x2000),48000 Hz,5.1(侧面),384 kb/s(默认)
流映射:
  流 #0:0 -> #0:0 (复制)
  流 #0:1 -> #0:1 (复制)
按 [q] 停止,按 [?] 获取帮助
帧=1414 fps=0.0 q=-1.0 Lsize=18275kB 时间=00:01:02.00 比特率=2414.6kbits/s    
视频:15344kB 音频:2906kB 字幕:0 数据:0 全局标头:0kB 多路复用开销 0.134916%

更新 2

可能与“关键帧”有关,让 ffmpeg 重新编码视频流不会导致几秒钟的空白视频。但是,由于 mkvmerge 可以剪切同一个文件之间关键帧没有重新编码,我想知道是否有办法让 ffmpeg 做同样的工作。例如,稍微“重新定义”关键帧等等。

答案1

为了在关键帧(或称为 GOP)之间进行切换,您需要对视频进行重新编码。(音频也是如此,但“帧”要小得多,通常为 1024 个样本)。

对于您的情况,您可以改为-codec copy-acodec copy -vcodec webmffmpeg 重新编码您的流。这显然会花费更长时间,并且会损失质量(如果您做得正确,这种损失不会很明显,但还是会有一些)。

相关内容