Clip de extracto de FFmpeg: la velocidad de fotogramas de la transmisión difiere de la velocidad de fotogramas del contenedor (x264, aac)

8

Resumen El
video H.264 parece tener una velocidad de cuadro realmente alta que requiere un factor de escala para el aplicado a la duración del video que estoy tratando de extraer (900x menor).

Cuerpo
Estoy tratando de extraer un clip de una película que tengo en formato MP4 (creado con Handbrake ). Después de probar mencoder y VLC, decidí darle una oportunidad a FFmpeg, ya que era el menos problemático a la hora de copiar los códecs. Es decir, en comparación con mencoder y VLC, el archivo resultante todavía se podía reproducir en QuickTime (sé sobre Perian, etc., solo estoy tratando de aprender cómo funciona todo esto).

De todos modos, mi comando fue el siguiente:

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

Durante la copia, aparece lo siguiente:

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
…

En lugar de un clip de duración de 5:59, obtengo el resto de la película. Entonces, para probar esto, ejecuté el comando ffmpeg con -t 00:00:01. Lo que obtuve fue exactamente un clip de 15:00 minutos. Así que hice un poco de ingeniería de caja negra y decidí escalar mi -topción calculando qué valor ingresar dado que 1 segundo se interpretó como 900 s. Para mi clip de 359 s deseado, calculé 0.399 sy mi comando ffmpeg se convirtió en:

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

Esto funciona, pero no tengo idea de por qué la duración se escala en 900. Investigando más, cada ejecución de ffmpeg tiene la línea:

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

45000/25 = 1800. Debe ser una relación en alguna parte. De alguna manera, la velocidad de cuadro obscenamente alta está causando problemas con el tiempo. ¿Cómo es esa velocidad de fotogramas tan alta? La mejor parte de esto es que el clip.mp4 resultante tiene exactamente la misma función (debido al códec de video copiado), y tomar más clips de esto necesita la misma escala para la -topción de duración. Por lo tanto, lo he puesto a disposición de cualquiera que esté dispuesto a revisar esto.

Apéndice
El preámbulo de ffmpeg en mi sistema (creado utilizando el puerto ffmpeg de 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
No estoy seguro de si fue un error o no, pero parece estar solucionado ahora en mi versión actual de ffmpeg, al menos para este video (versión 0.6.1 de MacPorts).

fideli
fuente
Volver a codificar no es una solución, y hacer una descodificación equivalente a unas horas por cinco minutos de contenido no es razonable y probablemente no resolvería el problema subyacente. Gran investigación inicial por cierto. Es probable que tenga razón al suponer que la raíz de su problema es la detección de fps ffmpeg. Parece que una versión posterior de ffmpeg solucionó su problema, pero haré un comentario. Hubiera recomendado hacer una copia -c a un formato de contenedor diferente. Esto puede tener una variedad de efectos, pero este habría sido un buen próximo paso para experimentar.
dstob

Respuestas:

1

Con ffmpeg, el posicionamiento de las opciones es importante. Con su ejemplo, está tratando de aplicar -ss y -t a la entrada. Úselo así aplicará las opciones a la salida en su lugar:

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

Con ffmpeg actual, la sintaxis correcta sería:

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

Estaba teniendo el mismo problema y mi solución fue la siguiente:

        $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);

Esto me da 10 imágenes para todo el video sin importar la duración del video

Gus
fuente