ffmpeg Cortar un medio conservando todos los flujos pero también todos los metadatos, códigos de tiempo y todo lo demás

Hoy quería obtener un archivo ts cortado conservando todo, así que probé con este comando:

ffmpeg -i "original.ts" -map 0 -c copy -t 00:30:0.0 -threads 1 "cutted.ts"

El archivo resultante tiene diferentes especificaciones menores que me gustaría hacer coincidir con el original.

original.ts

[mpeg2video @ 00000000030df040] Invalid frame dimensions 0x0.    
    Last message repeated 2 times    
[mp3 @ 00000000030e0420] Header missing    
[mp3 @ 00000000030df940] Header missing    
    Last message repeated 1 times    
[mpegts @ 00000000030dd500] PES packet size mismatch    
    Last message repeated 2 times    
Input #0, mpegts, from 'original.ts':    
  Duration: 01:14:46.92, start: 64563.955900, bitrate: 5367 kb/s    
  Program 1    
    Stream #0:0[0x201]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], max.    
 10000 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc    
    Stream #0:1[0x28b](eng): Audio: mp2 ([4][0][0][0] / 0x0004), 48000 Hz, stereo, s16p, 192 kb/s    
    Stream #0:2[0x2b7](001): Audio: mp2 ([4][0][0][0] / 0x0004), 48000 Hz, mono, s16p, 64 kb/s    
    Stream #0:3[0x2b8](eng): Audio: mp2 ([4][0][0][0] / 0x0004), 48000 Hz, stereo, s16p, 192 kb/s    
    Stream #0:4[0x241](001): Subtitle: dvb_teletext ([6][0][0][0] / 0x0006), 492x250

cortado.ts

[mp3 @ 000000000302fa20] Falta el encabezado
Último mensaje repetido 1 vez
[mp3 @ 000000000030304c0] Falta el encabezado
Entrada #0, mpegts, de 'cutted.ts':
Duración: 00:00:10.08, inicio: 1.400000 , tasa de bits: 4297 kb/s
Programa 1
Metadatos:
service_name: Service01
service_provider: FFmpeg
Stream #0:0[ 0x100 ]: Video: mpeg2video (Principal) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], máx.
10000 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc Transmisión
#0:1[ 0x101 ](eng): Audio: mp2 ( [3][0][0][0] / 0x0003 ), 48000 Hz , estéreo, s16p, 192 kb/s Transmisión
#0:2[ 0x102](001): Audio: mp2 ( [3][0][0][0] / 0x0003 ), 48000 Hz, mono, s16p, 64 kb/s
Stream #0:3[ 0x103 ](eng): Audio: mp2 ( [3][0][0][0] / 0x0003 ), 48000 Hz, estéreo, s16p, 192 kb/s
Stream #0:4[ 0x104 ](001): Subtítulo: dvb_teletext ([6][0 ][0][0] / 0x0006), 492x250

La tasa de bits que se muestra obviamente cambia porque el subconjunto de medios considerado tiene una longitud diferente y esto está bien.

El inicio no se mantiene, siendo parte de un flujo de transporte, me gustaría mantener esa hora de inicio exacta. Aquí https://ffmpeg.org/pipermail/ffmpeg-user/2013-July/016109.html hablan de reset_timestamps y initial_offset pero en lugar de especificarlos, me gustaría que se copiaran automáticamente.

Transmite cambios de identificación, así como algunas especificaciones menores dentro del paréntesis, pero no sé para qué sirven.

¿También es posible obtener un archivo de salida sin los metadatos ffmpeg service_name y service_provider?

PD: El archivo ts original fue creado por Terratec Home Cinema.

PPS: Mi pregunta no incluyó intencionalmente la opción -ss porque se supone que cambia la hora de inicio, sin embargo, también estoy interesado en una solución con -ss que automáticamente (si es posible) compensa la hora de inicio con (hora de inicio de salida = tiempo de inicio de entrada + compensación de comando -ss)

Respuestas (3)

Esto parece funcionar:

ffmpeg -ss N -i input.ts -c copy -copyts -muxdelay 0 -max_delay 0 output.ts

Puedes agregar un

-map_metadata 0

para preservar cualquier metadato que ffmpeg pueda. Pero esto no parece transferir todos los metadatos.

Lo probé pero parece que no funciona para mí :( si uso la -copytsopción da una salida de 0 kB y una alerta. Si agrego todas las demás opciones, la hora de inicio vuelve a cero y las ID de las transmisiones permanecen intactas como en mi ejemplo anterior.
¿Puedes subir una pequeña porción - 10 segundos?

La siguiente es mi solución, para un archivo de video .mp4 , usando ffmpeg en Windows 7. Este comando, ejecutado en un archivo por lotes .bat , copiará una sección del archivo de entrada (es decir, lo extraerá como archivo de salida), a partir del 30 segundos en el archivo de entrada, con el extracto teniendo una duración de 60 segundos, y sin volver a codificar ninguna de las secuencias.

Esto se puede modificar para un tipo de video diferente, como un flujo .ts (flujo de transporte), según sea necesario. Pero no altere los comandos de mapeo en la línea 2 ya que esa línea es la clave para mantener la sincronización de audio (la opción itsoffset ).

Los comandos de mapeo preservan la sincronización del flujo de audio con el flujo de video, evitando cualquier cambio en el desplazamiento entre ellos.

Los metadatos del archivo de entrada se copian en el archivo de salida, también sin modificaciones.

Los comandos flags son necesarios para escribir el archivo de salida, ya que mp4 es un formato contenedor. Los comandos flags recrean el formato mp4 del archivo de entrada (es decir, el contenedor dentro del cual se alojan y sincronizan los flujos de audio y video).

Las últimas dos líneas mostrarán datos clave de los archivos de entrada y salida en la pantalla, después de la operación, para que pueda compararlos y estar seguro de que se ha logrado lo que pretendía lograr.

SET file=movie.mp4

SET mapping=-i "%file%" -itsoffset 0 -i "%file%" -map 0:v -map 1:a -copyts

SET flags=-flags global_header -movflags faststart

ffmpeg %mapping% -c:v copy -c:a copy -map_metadata 0 -ss 30 -t 60 %flags% out.mp4

echo. & echo. ffmpeg  -i "%file%" -f nul
echo. & echo. ffmpeg  -i out.mp4  -f nul

No soy un experto en el formato .ts, pero no es un formato de video confiable. No proporciona los datos de archivo globales que proporcionan los formatos de video .mp4 y .mkv, por lo que un archivo .ts no es fácil de buscar, es lento para comenzar a reproducirse y es posible que no informe con precisión algunos datos del archivo (como la duración total del vídeo). Por lo tanto, es una mejor táctica convertir de .ts a .mp4 o .mkv porque esos formatos no tienen las deficiencias del formato .ts.

Para convertir de video .ts a .mp4, simplemente elimine la línea 1 en mi script por lotes anterior y sustitúyalo por este: SET file=movie.ts

.

ffmpeg sobrescribe service_namey service_providercon valores predeterminados:

Service01y FFmpeg.

Puede sobrescribirlo con los metadatos originales, pero primero debe recuperarlo:

i="input.ts"

# get service_name with ffprobe and store it in a variable
svc_name=$(ffprobe -hide_banner -v error -show_entries program_tags=service_name -of default=nw=1:nk=1 "${i}");\

# get service_provider with ffprobe and store it in a variable
svc_provider=$(ffprobe -hide_banner -v error -show_entries program_tags=service_provider -of default=nw=1:nk=1 "${i}");\

# add service_name and service_provider to new TS
ffmpeg -i "${i}" -c copy -copyts -muxdelay 0 -max_delay 0 -map_metadata 0 -metadata service_name="${svc_name}" -metadata service_provider="${svc_provider}" output.ts

Desafortunadamente, ffprobe program_tags=no funciona con service_type.