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

Convierto videos usando FFMPEG. Mi objetivo es convertirlos al formato de contenedor MP4 ( MPEG-4 Parte 14 ) con flujo de audio codificado en AAC y flujo de video codificado en 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 sin duda está 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 sobre 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) de 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í.

Creo que depende de sus códecs de entrada y salida. Los códecs de GOP largos pueden cambiar la duración de la transmisión de video para colocar los fotogramas clave donde deben estar y cerrar los GOP. No debería enfrentar este problema al transcodificar de códecs internos a códecs internos. Si no necesita volver a codificar el video, use la opción 'copia c:v' si el contenedor de destino es compatible con este códec.
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, la cantidad de fotogramas, la velocidad de fotogramas y la duración en segundos siempre se mantienen iguales. (¡a menos que quiera que cambie!).
@audionuma: ningún códec sensato agregará/eliminará fotogramas. mencoder a veces lo hace, debido a la sincronización a/v, ANTES de enviar cuadros al códec de video. Un códec colocará fotogramas clave donde considere oportuno (intervalo fijo o en cortes de escena), y cuando el codificador le diga al códec que este es el último fotograma, cerrará ese último GOP, independientemente de su longitud. ¡Incluso con la colocación de fotogramas clave no adaptables, ningún códec agregará fotogramas adicionales solo para que el último GOP tenga la misma longitud!

Respuestas (1)

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. Sin embargo, dudo que esta sea la razón por la que experimente una brecha de tiempo, ya que el remuestreo no necesariamente influye en la velocidad del reloj de los medios. Por lo tanto, no me preocuparía demasiado por el remuestreo, puede causar alguna variación, pero probablemente muy marginal.

  • Los formatos de contenedor que enumeró son un poco irrelevantes, porque definen cómo se empaqueta la transmisión comprimida, mientras que la fuente de la diferencia de tiempo es la compresión en sí. El .flvarchivo, por ejemplo, puede contener un flujo codificado por el códec Flash Sorenson heredado o el H.264 más nuevo. En el primer caso, estaría transcodificando la transmisión de video, pero en el último es posible que no lo esté, según el 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 le muestra de forma predeterminada 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 presentación, debe tener en cuenta que se trata de metadatos explícitos y no de un valor medido real.

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

  • Solo se me ocurren dos razones que pueden cambiar sustancialmente la duración de sus medios, ninguna aplicable en su caso específico:

    1. Recodificación a una velocidad objetivo diferente. A veces, esto sucede sin querer debido a metadatos incorrectos en el archivo de entrada. Pero no en su caso, que, como se señaló anteriormente, se corresponde con un solo cuadro perdido 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 con el que midió la duración de la transmisión.

Espero que esto ayude.

En realidad, el formato del contenedor probablemente sea relevante. Diferentes contenedores almacenan marcas de tiempo/duraciones de fotogramas de manera diferente. Y las calculadoras de longitud necesitan un código diferente para diferentes formatos de contenedores, y ese código puede comportarse de manera diferente. por ejemplo, contar la duración del último cuadro que se muestra en uno, pero no en otro.
@PeterCordes, ¿qué quiere decir con "longitud" en su comentario? Si quería decir "duración", entonces está equivocado, la duración es siempre el número de cuadros multiplicado por la base de tiempo. Si quiere decir algo más, indique qué quiere decir con "longitud".
Quise decir duración. No todos los videos tienen una velocidad de fotogramas constante. Y la forma en que se almacenan las duraciones de los cuadros (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 y un montaje de mi parte, ya que no he mirado los detalles, pero estoy bastante seguro de que no es tan simple como nos gustaría que fuera.
@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 un término más conciso en su caso es video híbrido (es decir, flujos con diferentes velocidades o bases de tiempo, conservando sus velocidades 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 la represente el contenedor en sus metadatos.