El video convertido por FFMPEG tiene una duración diferente, ¿por qué?

9

Convierto videos usando FFMPEG. Mi objetivo es convertirlos al formato contenedor MP4 ( MPEG-4 Parte 14 ) con transmisión de audio codificada AAC y transmisión de video codificada MPEG-4 parte 10 .

Yo uso la siguiente línea para convertir los videos:

ffmpeg -y -i "{inputFile}" "{outputFile}"

El video convertido se ve bien, sin embargo, la duración de las transmisiones en el archivo convertido y el archivo de entrada no siempre coinciden.

He hecho algunos experimentos y la diferencia en la duración está indudablemente ahí, sin embargo, no es tanto, de todos modos estoy probando con videos pequeños. Aquí están mis resultados:

| InputFile  | InputAudio | InputVideo | OutputAudio | OutputVideo  |
|------------|------------|------------|-------------|--------------|
| h.avi      | 3s 631ms   | 3s 567ms   | 3s 668ms    | 3s 567ms     |
| h.flv      | 3s 631ms   | 3s 558ms   | 3s 668ms    | 3s 567ms     |
| h.mov      | 3s 532ms   | 3s 533ms   | 3s 682ms    | 3s 534ms     |
| h.mp4      | 3s 605ms   | 3s 534ms   | 3s 682ms    | 3s 567ms     |
| h.mpg      | 3s 605ms   | 3s 533ms   | 3s 563ms    | 3s 534ms     |
| h.wmv      | 3s 620ms   | 3s 633ms   | 3s 659ms    | 3s 567ms     |

Dado que construiría un software en la parte superior de FFMPEG, sería más feliz si al menos pudiera entender la razón de esta diferencia. ¿Es por alguna transcodificación innecesaria?

En este caso, ¿puedo desactivar esta transcodificación para evitar que FFMPEG vuelva a muestrear mi archivo de video de entrada?

Si no puedo apagarlo, ¿cómo puedo estar seguro (además de probar) que esta diferencia no es proporcional al tamaño del video?

Si convierto, por ejemplo, un video de 10 horas, una diferencia de varios segundos o incluso minutos no es adecuada para mí.

Zsolt
fuente
1
Creo que depende de sus códecs de entrada y salida. Los códecs largos de GOP pueden cambiar la duración de la transmisión de video para colocar fotogramas clave donde sea necesario y cerrar los GOP. No debería enfrentar este problema al transcodificar de códecs intra a códecs intra. Si no necesita volver a codificar el video, use la opción 'c: v copy' si el contenedor de destino admite este códec.
audionuma
Espero que las diferencias de duración no empeoren con videos más largos. Es más probable que sea un problema de inicio / fin, no una deriva de velocidad o algo así. Cuando codifico cosas con ffmpeg, el número de fotogramas, la velocidad de fotogramas y la longitud en segundos siempre se mantiene igual. (¡a menos que quiera que cambie!).
Peter Cordes
@audionuma: ningún códec cuerdo agregará / eliminará marcos. mencoder a veces lo hace, debido a una sincronización de v /, ANTES de alimentar cuadros al códec de video. Un códec colocará los fotogramas clave donde mejor le parezca (intervalo fijo o en cortes de escena), y cuando el codificador le dice al códec que este es el último fotograma, cerrará el último GOP, por mucho tiempo que sea. Incluso con la colocación de fotogramas clave no adaptativos, ¡ningún códec agregará fotogramas adicionales solo para hacer que el último GOP tenga la misma longitud!
Peter Cordes

Respuestas:

7

Espero que esta explicación sea lo que estás buscando:

  • Cuando transcodifica a una codificación como H.264 (MPEG-4 parte 10), necesariamente también vuelve a muestrear el video, eso es parte de la técnica de compresión H.264. No obstante, dudo si esta es la razón por la que experimenta una brecha de tiempo ya que el muestreo no influye necesariamente en la frecuencia de reloj de los medios. Por lo tanto, no me preocuparía demasiado el remuestreo, puede causar alguna variación, pero probablemente sea muy marginal.

  • Los formatos de contenedor que enumeró son irrelevantes, porque definen cómo se empaqueta la secuencia comprimida, mientras que la fuente de la diferencia de tiempo es la compresión en sí. El .flvarchivo, por ejemplo, puede contener una secuencia codificada por el códec heredado Flash Sorenson o el nuevo H.264. En el primer caso, estaría transcodificando la transmisión de video, pero en el último es posible que no lo esté, dependiendo del códec de audio utilizado. Los contenedores .aviy .wmvson independientes del códec, por lo que no hay forma de adivinar la codificación de su contenido.

  • No mencionaste cómo se probó la duración. Tenga en cuenta que ffmpeg por defecto le muestra la duración que aparece en los metadatos del archivo y no un valor calculado. Si su lista se basa en los datos que ffmpeg vuelca como parte de sus avisos de bienvenida, entonces debe tener en cuenta que esto es explícitamente metadatos y no un valor medido real.

  • El delta en las duraciones que presentó está dentro del rango de uno o dos cuadros en un rango de 25 o 30 fps. Es razonable que los códecs rellenen o eliminen secuencias de cuadros en blanco de acuerdo con su algoritmo (o el orden del desarrollador ...). No debería influir en la marca de tiempo cuando concatena correctamente las secuencias.

  • Solo hay dos razones por las que puedo pensar que pueden cambiar sustancialmente la duración de sus medios, ninguna aplicable en su caso específico:

    1. Vuelva a codificar a una velocidad objetivo diferente. A veces esto sucede involuntariamente debido a metadatos incorrectos en el archivo de entrada. Pero no en su caso, que, como se señaló anteriormente, corresponde con un solo cuadro caído o ganado.

    2. Cuando aplica un códec que recrea cualquiera de las secuencias. Los ejemplos incluyen eliminación de anuncios, detección de silencio, limpieza de ruido, etc.

En pocas palabras, si le preocupa lo que sucederá con un video de 10 horas, simplemente realice una prueba real. Si tiene problemas y busca ayuda, recuerde publicar los detalles del códec del archivo de entrada y el método que midió la duración de la transmisión.

Espero que esto ayude.

avnr
fuente
En realidad, el formato del contenedor es probablemente relevante. Diferentes contenedores almacenan marcas de tiempo / duraciones de cuadros de manera diferente Y las calculadoras de longitud necesitan un código diferente para diferentes formatos de contenedor, y ese código podría comportarse de manera diferente. por ejemplo, contar la duración para la que se muestra el último cuadro en uno, pero no en otro.
Peter Cordes
@PeterCordes, ¿qué quieres decir con "longitud" en tu comentario? Si quería decir "duración", entonces está equivocado, la duración es siempre el número de fotogramas multiplicado por la base de tiempo. Si quiere decir algo más, indique qué quiere decir con "longitud".
avnr
Me refería a la duración. No todo el video tiene una velocidad de fotogramas constante. Y la forma en que se almacenan las duraciones de los fotogramas (como una fracción o lo que sea, generalmente múltiplos de una base de tiempo) es diferente para diferentes contenedores. Esto es un poco ondulado a mano por mi parte, ya que no he mirado los detalles, pero estoy bastante seguro de que no es tan simple como desearíamos que fuera.
Peter Cordes
@PeterCordes, está bien, pero esto es muy raro y realmente no pertenece aquí, se usa solo en algunos casos extremos como grabación de pantalla, presentaciones de diapositivas, etc. Hay un mal uso del término Velocidad de fotogramas variable en el software de edición, pero el El término más conciso en su caso es video híbrido (es decir, transmisiones con diferentes tasas o bases de tiempo, conservando sus tasas constantes originales cuando se mezclan). En el caso de una "película normal", casi siempre hay una velocidad de fotogramas conocida, independientemente de cómo el contenedor lo represente en sus metadatos.
avnr