Use el códec ffmpeg copy para combinar archivos * .ts en un solo mp4

47

Tengo un montón de segmentos ts descritos por un solo archivo index.m3u8:

index.m3u8        
segment1_0_av.ts  
segment2_0_av.ts  
segment3_0_av.ts  
segment4_0_av.ts  
segment5_0_av.ts

Sé que todos están codificados de la misma manera. ffprobe me da lo siguiente:

Input #0, mpegts, from 'segment1_0_av.ts':
  Duration: 00:00:10.00, start: 0.100511, bitrate: 1251 kb/s
  Program 1 
    Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 960x540 [SAR 1:1 DAR 16:9], 12.50 fps, 25 tbr, 90k tbn, 25 tbc
    Stream #0:1[0x101]: Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 105 kb/s
    Stream #0:2[0x102]: Unknown: none ([21][0][0][0] / 0x0015)

Me gustaría combinarlos en un solo contenedor mp4. Pero cuando intento comandos como:

ffmpeg -f concat -i filelist.txt -c copy output.mp4

donde genera el archivo listlist.txt del archivo index.m3u8, se queja de no poder leer varios archivos. Pero la conversión de los archivos ts en sí parece funcionar bien. Creo que no estoy usando ffmpeg correctamente.

¿Cómo uso ffmpeg para combinar los archivos ts descritos por index.m3u8 en un solo contenedor mp4 usando el códec de copia?

Ana
fuente

Respuestas:

58

No estoy seguro de por qué ffmpeg te está dando un error. Sin embargo, ts es uno de los pocos formatos que simplemente se pueden concatenar. Luego, una vez que tenga un solo ts, transmux a mp4.

Debajo de ventanas:

copy /b segment1_0_av.ts+segment2_0_av.ts+segment3_0_av.ts all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

Bajo GNU / Linux, usando bash:

cat segment1_0_av.ts segment2_0_av.ts segment3_0_av.ts > all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4
szatmary
fuente
12
También puede necesitar -bsf:a aac_adtstoasc.
Camilo Martin
1
Es interesante notar que el comando NO es ffmpeg copy ..., es copy ...(bajo Windows)
Ron Royston
25

Usar copy o cat para combinar los archivos como la respuesta principal actual de szatmary podría dejarlo con un archivo que se reproduce mucho más allá del límite y no puede buscar problemas de reproducción.

En cambio, para combinar estos archivos correctamente, use ffmpeg como se indica en https://trac.ffmpeg.org/wiki/Concatenate . (Instale ffmpeg aquí si aún no lo tiene https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg ).

Si eres demasiado vago para leer mi primer enlace, básicamente tienes que crear un archivo .txt que enumere todos los archivos que deseas combinar de esta manera (que mi primer enlace da instrucciones sobre cómo hacerlo fácilmente) en la carpeta donde estás ' re haciendo la concatenación:

file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

Aquí hay una copia y pego de mi primer enlace en una forma de crear un archivo de texto si tiene Windows en la línea de comandos, por ejemplo, pero obviamente puede hacer el archivo manualmente o como quiera:

(for %i in (*.ts) do @echo file '%i') > mylist.txt

¡Verifique que su archivo .txt se vea bien y esté formateado correctamente!

Después de esto, en la línea de comandos ejecute:

ffmpeg -f concat -i mylist.txt -c copy all.ts

donde 'mylist.txt' es el archivo .txt que acaba de crear.

Verifique si el archivo resultante reproduce el video correctamente. Desde aquí, puede transmux a mp4 como de costumbre si lo desea:

ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4
Juan aquino
fuente
Eso for %i in (*.ts) dono se ordena correctamente para i> = 10. Aparte de eso, todo funciona, gracias. De hecho, hubo problemas con el archivo concatenado, sin mencionar que el archivo creado con su método resultó ser un 16% más pequeño (tenía 1400 partes por 400kb).
usuario
@user para números para poder iterar a través de números comofor i in {1..10}; do echo file \'$i.ts\' >> list.txt ; done
qwr
8

Respuesta 2017

Pero cuando intento comandos como ..., se queja de no poder leer varios archivos.

Cuando ejecuto ffmpeg -i some.ts -c copy some.mp4un video determinado, aparece este mensaje de error:

Malformed AAC bitstream detected: use the audio bitstream filter 
'aac_adtstoasc' to fix it ('-bsf:a aac_adtstoasc' option with ffmpeg)

av_interleaved_write_frame(): Operation not permitted

No es sorprendente que la ejecución lo ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4corrija.

7vujy0f0hy
fuente
3
Obtenga una nueva ffmpegy ahora lo hará automáticamente.
llogan
7

Poniendo todo junto

Usando la respuesta de Juan Aquino (y corrigiendo el primer comando para que sea compatible con Bash y usando el orden natural de los archivos), más la respuesta de 7vujy0f0hy, un script de trabajo simple para un shell de Linux Bash es:

#!/bin/bash
for i in `ls *.ts | sort -V`; do echo "file $i"; done >> mylist.txt
ffmpeg -f concat -i mylist.txt -c copy -bsf:a aac_adtstoasc video.mp4
Francesco Galgani
fuente
4

La forma correcta de concatenar múltiples archivos de video de la lista de reproducción m3u8 es

ffmpeg -i "index.m3u8" -codec copy output.mp4


  • la lista de reproducción m3u8 puede estar en la web o localmente en el directorio
    • contiene una lista de rutas de archivos relativas a la lista de reproducción
  • -codec copy para evitar la codificación
  • el tipo de contenedor importa:
    • *.mp4 está bien, pero parece un poco lento para mux cuando la lista de reproducción se obtiene de la web
    • *.mkvo *.tsfuncionó mejor para mí
Vlastimil Ovčáčík
fuente
2

Puede hacer la concatenación simple de esta manera (con bash):

for f in ./{0..<number>}.ts; do cat $f >> out.ts; done

Reemplazar <number>con el número más alto (obviamente). Las variantes con ffmpeg no funcionaron correctamente. El archivo de video de salida tartamudearía de manera extraña.

Utilizo el bucle for para garantizar el orden correcto de los archivos. Quizás no lo necesites. Tal vez incluso sea posible canalizar la salida a ffmpeg y convertirla a mp4 sobre la marcha.

ragnarsson
fuente
1

Puede utilizar la canalización de estos archivos ts para ffmpeg y generar el archivo mp4.

cat *.ts | ffmpeg -i pipe: -c:a copy -c:v copy output.mp4

o Si su nombre de archivo no tiene orden,

grep .*.ts index.m3u8 | xargs cat | ffmpeg -i pipe: -c:a copy -c:v copy output.mp4

Kris Roofe
fuente
0

Todas las respuestas populares a esta pregunta que inducen a error a los lectores a concatenar los archivos TS antes de ejecutar ffmpeg son incorrectas. Para asegurarse de que el audio y el video no se desincronicen durante el ensamblaje de la transmisión mp4, se debe utilizar la característica "f concat" mal documentada pero importante de ffmpeg.

    delimiterBeforeFileNumber="-"
    ls |egrep '[.]ts$' \
        |sort "-t$delimiterBeforeFileNumber" -k2,2n \
        |sed -r "s/(.*)/file '\1'/" >ts.files.txt

    ffmpeg -f concat -i ts.files.txt -c copy tsw.014.ts.mp4

Las dos líneas de código preparatorias simplemente crean un archivo que contiene una lista de archivos TS en este formato de línea:

    file 'seg-37-a.ts'
Douglas Daseeco
fuente
En realidad, cuando probé esto, hubo un ligero "tartamudeo" entre los segmentos en el video final. Entonces, al menos en ese caso, ayudó a concatenar los archivos TS primero.
Sphinxxx