Verwenden Sie den Kopiercodec ffmpeg, um * .ts-Dateien zu einer einzigen mp4-Datei zu kombinieren

47

Ich habe ein paar ts-Segmente, die durch eine einzige index.m3u8-Datei beschrieben werden:

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

Ich weiß, dass sie alle auf die gleiche Weise codiert sind. ffprobe gibt mir Folgendes:

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)

Ich möchte sie in einem einzigen mp4-Container kombinieren. Aber wenn ich Befehle ausprobiere wie:

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

Wenn die Datei filelist.txt aus der Datei index.m3u8 generiert wird, wird beanstandet, dass verschiedene Dateien nicht gelesen werden können. Aber das Konvertieren der ts-Dateien selbst scheint gut zu funktionieren. Ich glaube, ich benutze ffmpeg nicht richtig.

Wie verwende ich ffmpeg, um die von index.m3u8 beschriebenen ts-Dateien mit dem Kopiercodec in einem einzigen mp4-Container zu kombinieren?

Ana
quelle

Antworten:

58

Ich bin mir nicht sicher, warum ffmpeg einen Fehler ausgibt. Es ist jedoch eines der wenigen Formate, die einfach verkettet werden können. Sobald Sie ein einziges ts haben, wechseln Sie zu mp4.

Unter Fenstern:

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

Unter GNU / Linux mit 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
quelle
12
Möglicherweise müssen Sie auch -bsf:a aac_adtstoasc.
Camilo Martin
1
Interessant zu bemerken, dass der Befehl NICHT ist ffmpeg copy ..., es ist copy ...(unter Windows)
Ron Royston
25

Durch die Verwendung von copy oder cat zum Kombinieren der Dateien, wie z. B. der aktuellen Top-Antwort von szatmary, erhalten Sie möglicherweise eine Datei, die weit über das Limit hinaus abgespielt wird und bei Wiedergabeproblemen nicht mitgesucht werden kann.

Verwenden Sie stattdessen ffmpeg, um diese Dateien ordnungsgemäß zu kombinieren, wie in https://trac.ffmpeg.org/wiki/Concatenate beschrieben . (Installieren Sie ffmpeg hier, falls Sie es noch nicht haben: https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg .)

Wenn Sie zu faul sind, um meinen ersten Link zu lesen, müssen Sie im Grunde genommen eine TXT-Datei erstellen, in der alle zu kombinierenden Dateien in dem Ordner aufgeführt sind, in dem Sie sich befinden. Wiederholen Sie die Verkettung:

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

Hier ist ein Kopieren und Einfügen von meinem ersten Link, um eine Textdatei zu erstellen, wenn Sie zum Beispiel Windows in der Befehlszeile haben, aber natürlich können Sie die Datei manuell erstellen oder wie Sie möchten:

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

Stellen Sie sicher, dass Ihre TXT-Datei gut aussieht und korrekt formatiert ist!

Danach auf der Kommandozeile ausführen:

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

Dabei steht 'mylist.txt' für die soeben erstellte TXT-Datei.

Überprüfen Sie, ob die resultierende Datei das Video korrekt wiedergibt. Von hier aus können Sie wie gewohnt auf mp4 umsteigen, wenn Sie möchten:

ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4
Juan Aquino
quelle
Das for %i in (*.ts) dosortiert nicht korrekt für i> = 10. Abgesehen davon , dass alles funktioniert, danke. In der Tat gab es Probleme mit der verketteten Datei, ganz zu schweigen davon, dass sich herausgestellt hat, dass die mit Ihrer Methode erstellte Datei 16% kleiner ist (ich hatte 1400 Teile auf 400 KB).
Benutzer
@user für Zahlen, damit Sie durch Zahlen wiefor i in {1..10}; do echo file \'$i.ts\' >> list.txt ; done
qwr
8

2017 antworten

Aber wenn ich Befehle wie probiere ..., beklagt es sich, dass ich verschiedene Dateien nicht lesen kann.

Beim Ausführen ffmpeg -i some.ts -c copy some.mp4eines bestimmten Videos erhalte ich folgende Fehlermeldung:

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

Es ist nicht überraschend, dass die Ausführung dies ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4behebt.

7vujy0f0hy
quelle
3
Holen Sie sich ein neues genug ffmpegund es wird dies jetzt automatisch tun.
11.
7

Alles zusammen

Ausgehend von der Antwort von Juan Aquino (und der Korrektur des ersten Befehls, der mit Bash kompatibel ist, und der natürlichen Reihenfolge der Dateien) sowie der Antwort von 7vujy0f0hy lautet ein einfaches Arbeitsskript für eine Linux-Bash-Shell:

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

Die richtige Möglichkeit, mehrere Videodateien aus der m3u8-Wiedergabeliste zu verknüpfen, ist

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


  • Die m3u8-Wiedergabeliste kann sich im Web oder lokal im Verzeichnis befinden
    • Es enthält eine Liste der Dateipfade in Bezug auf die Wiedergabeliste
  • -codec copy Codierung zu vermeiden
  • Containerart ist wichtig:
    • *.mp4 ist in Ordnung, aber es scheint etwas langsam zu muxen, wenn die Wiedergabeliste aus dem Web abgerufen wird
    • *.mkvoder am *.tsbesten für mich gearbeitet
Vlastimil Ovčáčík
quelle
2

Du kannst das Verketten einfach so machen (mit bash):

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

Ersetzen Sie <number>mit der höchsten Zahl (offensichtlich). Die Varianten mit ffmpeg haben nicht richtig funktioniert. Die ausgegebene Videodatei würde merkwürdig ruckeln.

Ich benutze die for-Schleife, um die richtige Reihenfolge der Dateien sicherzustellen. Vielleicht brauchst du es nicht. Vielleicht ist es sogar möglich, die Ausgabe direkt in ffmpeg zu leiten und in mp4 umzuwandeln.

Ragnarsson
quelle
1

Sie können diese ts-Dateien per Pipe in ffmpeg einfügen und die mp4-Datei ausgeben.

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

oder Wenn Sie den Dateinamen nicht bestellt haben,

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

Kris Roofe
quelle
0

Alle gängigen Antworten auf diese Frage, die Leser dazu verleiten, die TS-Dateien zu verketten, bevor ffmpeg ausgeführt wird, sind falsch. Um sicherzustellen, dass Audio und Video während der Zusammenstellung des mp4-Streams nicht aus dem Takt geraten, sollte die schlecht dokumentierte, aber wichtige Funktion "-f concat" von ffmpeg verwendet werden.

    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

Die beiden vorbereitenden Codezeilen erstellen lediglich eine Datei mit einer Liste von TS-Dateien in diesem Zeilenformat:

    file 'seg-37-a.ts'
Douglas Daseeco
quelle
Als ich das versuchte, gab es tatsächlich ein leichtes "Stottern" zwischen den Segmenten im endgültigen Video. Zumindest in diesem einen Fall half es also, zuerst die TS-Dateien zu verketten.
Sphinxxx