Determinar automáticamente el desfase de audio en un fichero MKV (II)

En Determinar automáticamente el desfase de audio en un fichero MKV explico cómo determinar automáticamente el desajuste de audio en un archivo multimedia cuando el audio está desfasado. ¿Qué ocurre cuando lo que está desfasado es el vídeo?

En Sincronización de sonido cuando la tasa de refresco de vídeo es irregular explico cómo extraer las marcas temporales de cada fotograma del archivo. Si el desajuste es constante a lo largo de todo el fichero multimedia, lo que nos interesa es conocer el desajuste de los primeros fotogramas. Para ello podemos hacer algo como:

$ ffmpeg -i FUENTE.mkv -vf "showinfo" -map 0:0 -y -f mjpeg -frames:v 10 /dev/null

Este comando muestra las marcas temporales de lo que deberían ser los primeros diez fotogramas. Pueden verse menos fotogramas si hay huecos.

El formato es el siguiente:

[Parsed_showinfo_0 @ 48de80] n:   0 pts:      0 pts_time:0       pos:    36548 fmt:yuv420p sar:1/1 s:704x396 i:P iskey:1 type:I checksum:20E663EC plane_checksum:[05BA13FC 11DA27F8 11DA27F8] mean:[16 128 128] stdev:[0.0 0.0 0.0]
[Parsed_showinfo_0 @ 48de80] n:   1 pts:     29 pts_time:1.16    pos:    92290 fmt:yuv420p sar:1/1 s:704x396 i:P iskey:1 type:I checksum:4301B6F1 plane_checksum:[FD725E04 8FF5BDC6 D5CD9B18] mean:[46 128 127] stdev:[27.5 6.4 4.4]
[Parsed_showinfo_0 @ 48de80] n:   2 pts:     30 pts_time:1.2     pos:   138134 fmt:yuv420p sar:1/1 s:704x396 i:P iskey:0 type:P checksum:AB8B0229 plane_checksum:[70EAA986 18D3BD05 23D59B80] mean:[46 128 127] stdev:[27.5 6.4 4.4]

El campo n indica el número de fotograma físico en el archivo, mientras que pts muestra un contador lógico. El campo pts_time muestra en segundos el momento en que debe mostrarse cada fotograma.

En este caso concreto vemos que el primer fotograma aparece en el segundo 0, pero el segundo fotograma aparece a los 1.16 segundos. Es decir, el primer fotograma permanece fijo en la pantalla durante 1.16 segundos, reemplazando 29 fotogramas.

Si suponemos que a partir de ahí todo los fotogramas aparecen escrupulosamente en su lugar, lo que tenemos es que el segundo fotograma del vídeo aparece a los 1.16 segundos. Como la fuente original tiene 25 fotogramas por segundo, cada uno de ellos dura cuarenta milisegundos [1]. Al transcodificar el vídeo, tendremos una tasa de refresco de 40 milisegundos, así que el desplazamiento que hay que aplicar al sonido es de 1.16-0.040 = 1.120 segundos.

[1] Si estamos hablando de un único fotograma, importa poco si la tasa de refresco real es de 23.976, 25 o 29.97 fotogramas por segundo. La diferencia es inapreciable a la vista y al oído.

Tal y como se describe en Cómo corregir la desincronización de audio en un fichero Matroska, tendríamos que ejecutar este comando:

$ mkvmerge -o DESTINO.mkv -y 1:1120 -y 2:1120 ORIGEN.mkv

Existen casos más difíciles. Por ejemplo, tenemos este fichero multimedia:

...
[Parsed_showinfo_0 @ 48de80] n: 439 pts:  17640 pts_time:17.64   pos:  3588554 fmt:yuv420p sar:1/1 s:960x540 i:P iskey:0 type:P checksum:49DAC4B0 plane_checksum:[5E763648 D75739DD BCDF548B] mean:[57 120 135] stdev:[37.7 19.0 18.5]
[Parsed_showinfo_0 @ 48de80] n: 440 pts:  18246 pts_time:18.246  pos:  3598714 fmt:yuv420p sar:1/1 s:960x540 i:P iskey:1 type:I checksum:8805D66E plane_checksum:[45867114 CB2D4803 5FE91D57] mean:[16 128 128] stdev:[5.9 0.5 0.7]
...

Aquí he tenido que examinar casi 500 fotogramas. Si debemos tener un fotograma cada 40 milisegundos, tras el fotograma mostrado a los 17.64 segundos, tendría que haber otro a los 17.68 segundos. En cambio, está a los 18.246 segundos. Un desplazamiento de 0.566 segundos.

Si permitimos un desajuste de 0.566 segundos durante esos primeros 17.68 segundos a cambio de tener bien sincronizado el resto del archivo, hacemos:

$ mkvmerge -o DESTINO.mkv -y 1:566 ORIGEN.mkv

Si queremos que todo el vídeo esté bien sincronizado, entonces habrá que trocear el archivo, procesar los trozos por separado y luego juntarlos de nuevo. Los detalles se describen en Resincronizar audio cuando el vídeo se congela un momento.