A taxa de quadros do clipe de fluxo de extração FFmpeg 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 o tempo de duração do vídeo que estou tentando extrair (900 vezes menor).

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

De qualquer forma, 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, surge 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 de duração de 5:59, recebo todo o resto do filme. Então, para testar isso, executei o comando ffmpeg com -t 00:00:01 . O que eu recebi foi exatamente um clipe de 15:00 minutos. Então eu fiz algumas engenharia de caixa preta e decidi escalar minha opção -t calculando qual valor inserir, dado que 1 segundo foi interpretado como 900 s. Para o meu clipe de 359 s, calculei 0,399 s e assim 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 de por que a duração é dimensionada em 900. Investigando mais, cada execução do ffmpeg tem a seguinte linha:

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

45000/25 = 1800. Deve ser 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 clipe resultante.mp4 tem exatamente o mesmo recurso (devido ao codec de vídeo copiado) e, para tirar mais clipes, é necessário o mesmo escalonamento para a opção -t duration. Portanto, disponibilizei para qualquer pessoa que queira verificar isso.

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

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)

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

    
por fideli 09.01.2010 / 22:34

2 respostas

1

Com o ffmpeg, o posicionamento das opções é importante. Com seu exemplo, ele está tentando aplicar -ss e -t à entrada. Usá-lo assim irá aplicar as opções para a 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
    
por 20.12.2012 / 07:06
1

Eu estava com 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 -yi /testmedia/'.$info['filename']. '-ff fps = fps = 1 /'.$ frac.duração.' -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

    
por 23.01.2013 / 18:13