Usando o ffmpeg para dividir mkv mas perder alguns segundos de vídeo (cortar entre quadros-chave sem recodificar?)

4

Estou usando o ffmpeg (o verdadeiro do FFmpeg, não o falso do Libav) para dividir alguns arquivos mkv:

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

No entanto, quando abro o output.mkv com o VLC, os primeiros segundos não têm vídeo, mas apenas áudio. E segundos depois, consigo ver o vídeo e o áudio. A parte interessante é que, quando eu tento timestamps diferentes após o parâmetro -ss, a duração da parte "somente áudio" varia de 1 segundo a 4 segundos ou mais.

Eu tento usar mkvmerge com --split "timecodes:00:01:00,00:02:00" , e o arquivo de saída funciona bem, sem nenhuma parte "somente de áudio" no começo.

Eu tentei diferente contêiner mkv com codificação de vídeo / áudio diferente neles, mas os resultados são os mesmos.

Acho que estou perdendo algumas opções com o ffmpeg. O que devo adicionar à linha de comando do ffmpeg para evitar os vários segundos da parte "somente áudio"?

Atualização 1

Aqui está a saída completa:

$ ffmpeg -i 21.mkv -ss 00:00:58 -to 00:02:00 -codec copy clip.mkv
ffmpeg version 2.2.2 Copyright (c) 2000-2014 the FFmpeg developers
  built on May  7 2014 13:08:45 with gcc 4.8.2 (GCC) 20140206 (prerelease)
  configuration: --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
Input #0, matroska,webm, from '21.mkv':
  Metadata:
    encoder         : libebml v1.3.0 + libmatroska v1.4.0
    creation_time   : 2014-05-07 01:47:41
  Duration: 00:42:50.78, start: 0.000000, bitrate: 2833 kb/s
    Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709), 1280x720, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
    Stream #0:1: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s (default)
Output #0, matroska, to 'clip.mkv':
  Metadata:
    encoder         : Lavf55.33.100
    Stream #0:0(eng): Video: h264 (H264 / 0x34363248), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 1k tbn, 1k tbc (default)
    Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 384 kb/s (default)
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1414 fps=0.0 q=-1.0 Lsize=   18275kB time=00:01:02.00 bitrate=2414.6kbits/s    
video:15344kB audio:2906kB subtitle:0 data:0 global headers:0kB muxing overhead 0.134916%

Atualização 2

Pode haver algo a ver com as coisas "keyframe" e permitir que o ffmpeg recodifique o fluxo de vídeo não levará a alguns segundos de vídeo em branco. No entanto, como o mkvmerge pode cortar o mesmo arquivo entre quadros-chave sem re-codificação, estou querendo saber se existe uma maneira de fazer o ffmpeg fazer o mesmo trabalho. Por exemplo, um pouco "redefinir" o quadro-chave, et cetra.

    
por Zhuoyun Wei 10.05.2014 / 05:04

1 resposta

0

Para cortar entre keyframes (ou GOPs, como são chamados), você precisa recodificar o vídeo. (o mesmo vale para o áudio, mas os "quadros" são muito menores, normalmente 1024 amostras).

No seu caso, você pode alterar -codec copy para -acodec copy -vcodec webm para que o ffmpeg recodifique seu fluxo. Obviamente, isso levará mais tempo e você perderá qualidade (se fizer isso corretamente, essa perda não será perceptível, mas haverá alguns).

    
por 13.05.2014 / 15:35