Usa ffmpeg copy codec per combinare i file * .ts in un singolo mp4


47

Ho un sacco di segmenti ts descritti da un singolo file index.m3u8:

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

So che sono tutti codificati allo stesso modo. ffprobe mi dà quanto segue:

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)

Vorrei combinarli in un unico contenitore mp4. Ma quando provo comandi come:

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

dove genera il file filelist.txt dal file index.m3u8, si lamenta di non essere in grado di leggere vari file. Ma la conversione dei file ts stessi sembra funzionare bene. Penso che non sto usando ffmpeg correttamente.

Come posso usare ffmpeg per combinare i file ts descritti da index.m3u8 in un singolo contenitore mp4 usando il codec copia?

Risposte:


58

Non sono sicuro del motivo per cui ffmpeg ti sta dando un errore. Tuttavia ts è uno dei pochi formati che possono essere semplicemente concatenati. Quindi, una volta che hai un singolo ts, trasmetti a mp4.

Sotto windows:

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

Sotto 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

12
Potresti anche aver bisogno -bsf:a aac_adtstoasc.
Camilo Martin,

1
interessante notare che il comando NON è ffmpeg copy ..., è copy ...(sotto Windows)
Ron Royston

25

L'uso di copy o cat per combinare i file come l'attuale risposta principale di szatmary potrebbe lasciarti con un file che viene riprodotto ben oltre il limite e non può cercare insieme ai problemi di riproduzione.

Invece, per combinare correttamente questi file usa ffmpeg come indicato in https://trac.ffmpeg.org/wiki/Concatenate . (Installa ffmpeg qui se non lo hai già https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg .)

Se sei troppo pigro per leggere il mio primo link, fondamentalmente devi creare un file .txt che elenca tutti i file che vuoi combinare in questo modo (che il mio primo link fornisce istruzioni su come fare facilmente) nella cartella in cui ' facendo la concatenazione:

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

Ecco un copia incolla dal mio primo link in un modo per creare un file di testo se hai Windows sulla riga di comando, ad esempio, ma ovviamente puoi creare il file manualmente o come vuoi:

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

Controlla che il tuo file .txt sia in ordine e che sia formattato correttamente!

Successivamente, sulla riga di comando eseguire:

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

dove "mylist.txt" è il file .txt che hai appena creato.

Controlla se il file risultante riproduce correttamente il video. Da qui, puoi trasmettere come al solito mp4 se ti piace:

ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

Non for %i in (*.ts) dofunziona correttamente per i> = 10. A parte questo, tutto funziona, grazie. In effetti, c'erano dei problemi con il file concatenato, per non parlare del fatto che il file creato usando il tuo metodo si è rivelato più piccolo del 16% (avevo 1400 parti per 400kb).
utente

@utente per i numeri per poter scorrere numeri comefor i in {1..10}; do echo file \'$i.ts\' >> list.txt ; done
qwr

8

Risposta 2017

Ma quando provo comandi simili ..., si lamenta di non essere in grado di leggere vari file.

Quando eseguo ffmpeg -i some.ts -c copy some.mp4un determinato video, viene visualizzato questo messaggio di errore:

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

Non sorprende che l'esecuzione lo ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4risolva.


3
Ottieni abbastanza nuovo ffmpege ora lo farà automaticamente.
Llogan,

7

Mettere tutti insieme

Usando la risposta di Juan Aquino (e correggendo il primo comando per essere compatibile con Bash e usando l'ordinamento naturale dei file), oltre alla risposta di 7vujy0f0hy, un semplice script funzionante per una shell Linux Bash è:

#!/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

4

Il modo corretto di concatenare più file video dalla playlist m3u8 è

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


  • la playlist m3u8 può essere sul web o localmente nella directory
    • contiene un elenco di percorsi di file relativi alla playlist
  • -codec copy per evitare la codifica
  • il tipo di contenitore conta:
    • *.mp4 va bene, ma sembra un po 'lento da fondere quando la playlist viene recuperata dal web
    • *.mkvo ha *.tsfunzionato meglio per me

2

Puoi fare la concatenazione semplice in questo modo (con bash):

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

Sostituisci <number>con il numero più alto (ovviamente). Le varianti con ffmpeg non funzionavano correttamente. Il file video di output potrebbe balbettare in modo strano.

Uso il ciclo for per garantire l'ordine corretto dei file. Forse non ne hai bisogno. Forse è anche possibile reindirizzare l'output a ffmpeg e convertirlo al volo in mp4.


1

È possibile utilizzare il pipe di questi file ts in ffmpeg e generare il file mp4.

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

oppure se il nome del tuo file ts non ha ordine,

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


0

Tutte le risposte popolari a questa domanda che inducono i lettori a concatenare i file TS prima di eseguire ffmpeg sono errate. Per garantire che l'audio e il video non vengano sincronizzati durante l'assemblaggio del flusso mp4, è necessario utilizzare la funzione "-f concat" scarsamente documentata ma di 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

Le due righe di codice preparatorie creano semplicemente un file contenente un elenco di file TS in questo formato di riga:

    file 'seg-37-a.ts'

In realtà, quando ho provato questo, c'è stata una leggera "balbuzie" tra i segmenti nel video finale. Quindi, almeno in quel caso, ha aiutato prima a concatenare i file TS.
Sphinxxx
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.