Recorte la transmisión de audio a la longitud de la transmisión de video

Tengo un archivo mp4 (convertido de un archivo mkv) que tiene una transmisión de audio más larga que la de video. Este archivo no se reproduce bien en mi aplicación de transmisión de medios (o MPC-HC) cuando llego al final del archivo.

Ejemplo de salida de mp4info:

File:
  major brand:      mp42
  minor version:    200
  compatible brand: isom
  compatible brand: iso2
  compatible brand: avc1
  compatible brand: mp41
  fast start:       yes

Movie:
  duration:   1553152 ms
  time scale: 1000
  fragments:  no

Found 3 Tracks
Track 1:
  flags:        3 ENABLED IN-MOVIE
  id:           1
  type:         Video
  duration: 1524398 ms
  language: und
  media:
    sample count: 36549
    timescale:    90000
    duration:     137195807 (media timescale units)
    duration:     1524398 (ms)
    bitrate (computed): 8508.739 Kbps
  display width:  1444.000000
  display height: 1080.000000
  frame rate (computed): 23.976
  Sample Description 0
    Coding:      avc1 (H.264)
    Width:       1444
    Height:      1080
    Depth:       24
    AVC Profile:          77 (Main)
    AVC Profile Compat:   40
    AVC Level:            40
    AVC NALU Length Size: 4
    AVC SPS: [674d4028eca02d8113cf2e02d404040500000300010002bf200f183196]
    AVC PPS: [68cb8132c8]
    Codecs String: avc1.4D4028
Track 2:
  flags:        3 ENABLED IN-MOVIE
  id:           2
  type:         Audio
  duration: 1553152 ms
  language: eng
  media:
    sample count: 72804
    timescale:    48000
    duration:     74551296 (media timescale units)
    duration:     1553152 (ms)
    bitrate (computed): 125.679 Kbps
  Sample Description 0
    Coding:      mp4a (MPEG-4 Audio)
    Stream Type: Audio
    Object Type: MPEG-4 Audio
    Max Bitrate: 125678
    Avg Bitrate: 125678
    Buffer Size: 0
    Codecs String: mp4a.40.2
    MPEG-4 Audio Object Type: 2 (AAC Low Complexity)
    MPEG-4 Audio Decoder Config:
      Sampling Frequency: 48000
      Channels: 1
      Extension:
        Object Type: Spectral Band Replication
        SBR Present: no
        PS Present:  no
        Sampling Frequency: 0
    Sample Rate: 48000
    Sample Size: 16
    Channels:    2
Track 3:
  flags:        2 IN-MOVIE
  id:           3
  type:         Text
  duration: 1524356 ms
  language: ```
  media:
    sample count: 5
    timescale:    1000
    duration:     1524356 (media timescale units)
    duration:     1524356 (ms)
    bitrate (computed): 0.001 Kbps
  Sample Description 0
    Coding:      text

En concreto, la duración de la "Película" es de 1553152 ms (25:53,152), que es demasiado larga. La duración de la transmisión de video es 1524398ms (25:24.398), lo cual es correcto. La duración de la transmisión de audio es de 1553152 ms (25:53,152) y parece estar impulsando la duración de la "Película".

Quiero establecer la duración de "Película" en el valor de duración del video sin volver a codificar . Parece que esto sería algo fácil de hacer, pero no puedo encontrar ninguna solución.

He intentado:

  • ffmpeg -i file.mp4 -shortest -codec copy out.mp4- no tiene ningún efecto (aparte de eliminar el inicio rápido de mp4, que quiero conservar).
  • mp4box -add file.mp4 -new out.mp4- Tampoco fija la duración.
  • Remezclando el archivo mkv original usando MkvToolnix.

ffmpegcon la -topción puede funcionar, pero tengo algunos miles de archivos para revisar y no quiero escribir manualmente un comando diferente para cada uno.


Más detalles:

Tengo un montón de BluRays que extraje hace un par de años con MakeMKV 1.10.4. Los propios archivos MKV tienen el mismo problema: la duración del segmento es 25:53.088, con una etiqueta de DURACIÓN de la película de la pista 1 de 25:24.397875. La etiqueta DURATION de la película de la pista 2 (audio) es 25:53.14133333. Volver a copiar los BluRays es una solución aceptable, si este problema se solucionó (no saqué los BluRays del almacenamiento ni lo probé).

Convertí estos archivos MakeMKV mkv usando HandBrake en archivos h265 mkv. Estos archivos también tienen una discrepancia entre la etiqueta DURACIÓN de la película y la duración del segmento.

Al reproducir los archivos MKV, mi aplicación de transmisión de medios (y MPC-HC) determinan correctamente la duración del archivo a partir de la etiqueta de DURACIÓN de la película. No hay problema allí, aunque las duraciones del archivo mkv son incorrectas.

Lo que quiero hacer es habilitar varios reproductores antiguos codificando a h264 mp4s con faststart. Creo que mi aplicación de transmisión de medios podrá servir los archivos directamente en lugar de volver a codificarlos en h264 o remuxing (dependiendo del cliente, siempre hace uno u otro en este momento).

Tengo HandBrake configurado con mi nueva configuración de h264/mp4 y me gustaría seguir usando esa aplicación para volver a codificar los archivos fuente de MakeMKV.

Una solución ideal sería corregir la duración del segmento mkv en los archivos fuente de MakeMKV. Arreglar los archivos mp4 después del hecho también sería aceptable, pero en ese momento no quiero volver a codificarlos.

Las versiones están actualizadas en todo, excepto en MakeMkv, ya que las extraje hace un par de años:

ffmpeg 4.1.4
mp4info 1.3.4 (Bento4 1.5.1.0)
MKVToolNix 35.0.0
MP4Box 0.8.0-rev47-gbafe4cd3-master
MakeMKV 1.10.4

Respuestas (1)

Se debe usar la bandera de la biblioteca avformat para dejar de multiplexar con el flujo más corto.

ffmpeg -i file.mp4 -map 0 -c copy -fflags +shortest -max_interleave_delta 1G -movflags +faststart out.mp4
Esto terminó haciendo algún tipo de truncamiento parcial en el archivo mp4. No estoy seguro de lo que estaba pasando. Sin embargo, este enfoque funcionó para corregir el archivo mkv, por lo que tengo una fuente adecuada para codificar mi mp4. ¡Muchas gracias! Última línea de comando:ffmpeg -i file.mkv -map 0 -c copy -fflags +shortest -max_interleave_delta 0 out.mkv
@StephenCleary: De manera molesta, la shortestlógica también se aplica a las pistas de subtítulos, que generalmente son más cortas que el video y el audio :( Tuve que quitar los subtítulos en el re-mux de acortamiento inicial: luego ffmpeg -i original.mkv -c copy -sn -fflags +shortest -max_interleave_delta 0 trimmed-no-subs.mkvpegar los subtítulos nuevamente:ffmpeg -i trimmed-no-subs.mkv -i original.mkv -map 0 -map 1:s -c copy trimmed.mkv