Clipe de extração FFmpeg - a taxa de quadros do fluxo difere da taxa de quadros do contêiner (x264, aac)

8

Resumo O
vídeo H.264 parece ter uma taxa de quadros realmente alta que requer um fator de escala para a duração aplicada ao vídeo que estou tentando extrair (900x mais baixo).

Corpo
Estou tentando extrair um clipe de um filme que possuo no formato MP4 (criado usando o Handbrake ). Depois de experimentar o mencoder e o VLC, decidi testar o FFmpeg, pois era o menos problemático quando se tratava de copiar os codecs. Ou seja, comparado ao mencoder e ao VLC, o arquivo resultante ainda era reproduzível no QuickTime (eu sei sobre o Perian etc., estou apenas tentando aprender como tudo isso funciona).

Enfim, meu comando foi o seguinte:

ffmpeg -ss 01:15:51 -t 00:05:59 -i outofsight.mp4 \ 
-acodec copy -vcodec copy clip.mp4

Durante a cópia, é exibido o seguinte:

Seems stream 0 codec frame rate differs from container frame rate: 45000.00 (45000/1) -> 25.00 (25/1)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from outofsight.mp4':
  Duration: 01:57:42.10, start: 0.000000, bitrate: 830 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 720x384, 25 tbr, 22500 tbn, 45k tbc
    Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16
Output #0, mp4, to 'out.mp4':
    Stream #0.0(und): Video: libx264, yuv420p, 720x384, q=2-31, 90k tbn, 22500 tbc
    Stream #0.1(eng): Audio: libfaac, 48000 Hz, stereo, s16
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 2591 fps=2349 q=-1.0 size=    8144kB time=101.60 bitrate= 656.7kbits/s
…

Em vez de um clipe com duração de 5:59, recebo o resto do filme. Então, para testar isso, executei o comando ffmpeg com -t 00:00:01. O que recebi foi exatamente um clipe de 15:00 minutos. Então, eu fiz alguma engenharia de caixa preta e decidi dimensionar minha -topção calculando qual valor inserir, dado que 1 segundo foi interpretado como 900 s. Para o clipe desejado de 359 s, calculei 0,399 se meu comando ffmpeg se tornou:

ffmpeg -ss 01:15.51 -t 00:00:00.399 -i outofsight.mp4 \ 
-acodec copy -vcodec copy clip.mp4

Isso funciona, mas não tenho idéia do porquê da duração ser escalada em 900. Investigando ainda mais, cada execução do ffmpeg tem a linha:

Seems stream 0 codec frame rate differs from container frame rate: 45000.00 (45000/1) -> 25.00 (25/1)

45000/25 = 1800. Deve haver uma relação em algum lugar. De alguma forma, a taxa de quadros obscenamente alta está causando problemas com o tempo. Como essa taxa de quadros é tão alta? A melhor parte disso é que o clip.mp4 resultante possui exatamente o mesmo recurso (devido ao codec de vídeo copiado), e a captura de outros clipes disso precisa da mesma escala para a -topção de duração. Portanto, disponibilizei-o para qualquer pessoa disposta a verificar isso.

Apêndice
O preâmbulo do ffmpeg no meu sistema (construído usando a porta MacPorts ffmpeg):

FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --prefix=/opt/local --disable-vhook --enable-gpl --enable-postproc --enable-swscale --enable-avfilter --enable-avfilter-lavf --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libdirac --enable-libschroedinger --enable-libfaac --enable-libfaad --enable-libxvid --enable-libx264 --mandir=/opt/local/share/man --enable-shared --enable-pthreads --cc=/usr/bin/gcc-4.2 --arch=x86_64
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat   52.31. 0 / 52.31. 0
  libavdevice   52. 1. 0 / 52. 1. 0
  libavfilter    1. 4. 0 /  1. 4. 0
  libswscale     1. 7. 1 /  1. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jan  4 2010 21:51:51, gcc: 4.2.1 (Apple Inc. build 5646) (dot 1)

EDIT
Não tenho certeza se foi um bug ou não, mas parece estar corrigido agora na minha versão atual do ffmpeg, pelo menos para este vídeo (versão 0.6.1 do MacPorts).

fideli
fonte
A recodificação não é uma solução, e decodificar horas por cinco minutos de conteúdo não é razoável e provavelmente não resolveria o problema subjacente. Grande pesquisa inicial entre. Você provavelmente está correto ao supor que o fps ffmpeg estava detectando é a raiz do seu problema. Parece que uma versão posterior do ffmpeg corrigiu seu problema, mas farei um comentário. Eu recomendaria fazer uma cópia -c em um formato de contêiner diferente. Isso pode ter vários efeitos, mas seria um bom próximo passo para experimentar.
dstob

Respostas:

1

Com ffmpeg, o posicionamento das opções é importante. Com o seu exemplo, ele está tentando aplicar -ss e -t à entrada. Use-o assim, aplicará as opções à saída:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -acodec copy -vcodec copy clip.mp4

Com o ffmpeg atual, a sintaxe correta seria:

ffmpeg -i outofsight.mp4 -ss 01:15:51 -t 00:05:59 -c copy clip.mp4
evilsoup
fonte
1

Eu estava tendo o mesmo problema e minha solução foi a seguinte:

        $ffmpegout = array();           
        //10 is the number of images you want from video
        $fracduration = ($info['duration']/10);             

exec ('ffmpeg -y -i /testmedia/'.$info['filename']. '-vf fps = fps = 1 /'.$ fracduration.' -f image2 /testmedia/images/output%03d.jpg 2 > & 1 ', $ ffmpegout); // print_r ($ ffmpegout);

Isso me dá 10 imagens para todo o vídeo, independentemente da duração do vídeo

Gus
fonte