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 -t
opçã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 -t
opçã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).
Respostas:
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:
Com o ffmpeg atual, a sintaxe correta seria:
fonte
Eu estava tendo o mesmo problema e minha solução foi a seguinte:
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
fonte