Verbinden Sie mp4-Dateien in Linux

37779
Jose Armando

Ich möchte zwei mp4-Dateien zusammenfügen, um eine einzige zu erstellen. Die Videoströme sind in h264 und das Audio in aac codiert. Ich kann die Videos aus rechnerischen Gründen nicht in ein anderes Format umcodieren. Außerdem kann ich keine GUI-Programme verwenden. Die gesamte Verarbeitung muss mit Linux-Befehlszeilen-Dienstprogrammen ausgeführt werden. FFmpeg kann dies nicht für mpeg4-Dateien tun, daher habe ich MP4Box verwendet:

MP4Box -add video1.mp4 -cat video2.mp4 newvideo.mp4 

Leider wird der Ton durcheinander gebracht. Ich dachte, das Problem war, dass das Audio in aac war, also habe ich es in mp3 transcodiert und MP4Box erneut verwendet. In diesem Fall ist der Ton für die erste Hälfte newvideo.mp4(entsprechend video1.mp4) gut, aber dann ist kein Ton und ich kann auch nicht im Video navigieren.

Mein nächster Gedanke war, dass die Audio- und Video-Streams einige kleine Abweichungen in der Länge hatten, die ich korrigieren sollte. Also habe ich für jedes Eingangsvideo die Video- und Audioströme aufgeteilt und dann mit der Option -shortest in FFmpeg verbunden.

Also für das erste Video lief ich:

 avconv -y -i video1.mp4 -c copy -map 0:0 videostream1.mp4 avconv -y -i video1.mp4 -c copy -map 0:1 audiostream1.m4a avconv -y -i videostream1.mp4 -i audiostream1.m4a -c copy -shortest video1_aligned.mp4 

Ähnlich für das zweite Video und dann MP4Box wie zuvor. Leider hat das auch nicht funktioniert. Der einzige Erfolg, den ich hatte, war, als ich die Videoströme separat (z. B. videostream1.mp4 und videostream2.mp4) und die Audioströme (z. B. audiostream1.m4a und audiostream2.m4a) zusammenbrachte und dann das Video und das Audio in einer endgültigen Datei zusammenbrachte. Die Synchronisierung geht jedoch für die zweite Hälfte des Videos verloren. Konkret gibt es eine Verzögerung von 1 Sekunde für Audio und Video. Anregungen sind herzlich willkommen.

26
"FFmpeg kann dies nicht für mpeg4-Dateien tun, also habe ich MP4Box verwendet" meinst du MP4-Datei? Verwenden beide Audio-Video-Streams die gleichen Codierungsparameter (Breite, Höhe, SPS, PPS, Framerate, Abtastrate, Anzahl der Kanäle)? vor 11 Jahren 0
mit ffprobe sehe ich, dass die Audio-Streams identische Attribute haben. Die Videoströme haben die gleichen Abmessungen, jedoch unterschiedliche Raten. Für das erste Video Video: h264, 720x592, 277 kb / s, PAR 18944: 12915 DAR 512: 287, 24,97 fps, 45 ktb, 90k tbn, 90k tbc während für das zweite Video: h264, 720x592, 226 kb / s, PAR 481: 330 DAR 39:22, 24,91 fps, 45 ktbr, 90k tbn, 90k tbc. Glauben Sie, dass dies die Ursache meiner Probleme ist? vor 11 Jahren 0
Probieren Sie diese http://stackoverflow.com/questions/5415006/ffmpeg-combine-merge-multiple-mp4-videos-not-working aus daya vor 11 Jahren 0
Ihre Frage wurde bereits in den FAQ zu ffmpeg beantwortet: http://www.ffmpeg.org/faq.html#How-can-I-join-video-files_003f Palec vor 10 Jahren 0
MP4 unterstützt das Verbinden von Video / Audio mit unterschiedlichen Eigenschaften, wobei unterschiedliche Spuren für unterschiedliche Videos verwendet werden. Der Player ist jedoch nicht besonders intelligent. rajneesh vor 11 Jahren 0
Ich liebe die migrierten Fragen, die später nicht migrierte Duplikate erhalten haben: http://stackoverflow.com/questions/18552901/how-to-merge-videos-by-avconv Ciro Santilli 新疆改造中心 六四事件 法轮功 vor 8 Jahren 0

6 Antworten auf die Frage

24
evilsoup

Der beste Weg, dies derzeit zu tun, ist der concat Demuxer . Erstellen Sie zunächst eine Datei, inputs.txtdie wie folgt formatiert ist:

file '/path/to/input1.mp4' file '/path/to/input2.mp4' file '/path/to/input3.mp4' 

Dann führe einfach diesen ffmpeg Befehl aus:

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

Siehe auch Verkettung in ffmpegFAQ .


Ich behalte hier Folgendes zum Nutzen aller, die ältere Versionen von ffmpeg verwenden.

Die neuesten Versionen von ffmpeg können dies tun: Sie müssen die Dateien zuerst in mpeg-Transportströme remuxen (ziemlich prozessorleuchtend, da nur das Containerformat geändert wird):

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts 

Wenn dies einen Fehler bezüglich h264 auslöst, müssen Sie möglicherweise Folgendes verwenden:

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts 

Sie müssen dies für jede Eingabedatei separat tun. Um die Dateien miteinander zu verketten, verwenden Sie:

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy output.mp4 

Wenn dies zu einem Fehler bei aac führt, müssen Sie möglicherweise verwenden

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy -absf aac_adtstoasc output.mp4 

Wenn Ihr System Named Pipes unterstützt, können Sie dies tun, ohne Zwischendateien zu erstellen.

mkfifo temp0 temp1 

In drei separaten virtuellen Terminals müssen Sie Folgendes tun:

ffmpeg -i input0.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0 ffmpeg -i input1.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1 ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4 

Wenn output.mp4 bereits vorhanden ist, werden Sie vom dritten ffmpeg gefragt, ob Sie die Datei überschreiben möchten. Dies geschieht jedoch, nachdem die FIFOs aufgerufen wurden. Dadurch werden die ersten ffmpegs geschlossen. Stellen Sie daher sicher, dass Sie einen nicht verwendeten Namen für Ihre Ausgabedatei auswählen.

Dies funktioniert möglicherweise nicht, wenn Ihre Eingabedateien unterschiedlich sind. Ich glaube, die Unterschiede in der Bitrate sind in Ordnung, aber die Bildgröße, die Bildrate usw. müssen übereinstimmen.

viele thx-kumpel, funktionierten wie ein reiz Jose Armando vor 11 Jahren 0
@DaveJarvis Nicht so; Dies ist eine Nachricht, die das libav-Team bewusst und böswillig verbreitet hat. Es handelt sich dabei um eine Reihe von Entwicklern, die sich vom ffmpeg-Projekt getrennt haben, um avconv zu entwickeln (und den Namen geändert haben, weil sie das Copyright für den ffmpeg-Namen nicht sichern konnten). Siehe [Wer kann mir den Unterschied und die Beziehung zwischen ffmpeg, libav und avconv erklären?] (Http://stackoverflow.com/questions/9477115/who-can-tell-me-the-difference-and-relation-ween- ffmpeg-libav-and-avconv) für ein bisschen mehr Informationen. evilsoup vor 10 Jahren 2
Dieses Programm dient nur der Kompatibilität und wird in einer zukünftigen Version entfernt. Bitte verwenden Sie stattdessen avconv.` ist eine Nachricht, die jetzt beim Ausführen von `ffmpeg` angezeigt wird Lord Loh. vor 10 Jahren 2
@LordLoh. Siehe den Link in meinem vorherigen Kommentar. evilsoup vor 10 Jahren 0
Diese Antwort gibt keine Antwort - wie man mp4 mit `avconv` verkettet Lord Loh. vor 10 Jahren 1
Komprimiertes ffmpeg 2.2 wie in diesem Video: http://youtu.be/MRrGNIuLJ40 und dann funktioniert alles perfekt mit den Optionen "-f concat -i inputfiles". +1 qed vor 9 Jahren 0
Dies funktioniert auch für MKV-Dateien. colton7909 vor 7 Jahren 0
7
Philippe Gachoud

Für mp4 war die einzige funktionierende Lösung, die ich gefunden habe, mit MP4Box von gpac package

#!/bin/bash filesList="" for file in $(ls *.mp4|sort -n);do filesList="$filesList -cat $file" done MP4Box $filesList -new merged_files_$(date +%Y%m%d_%H%M%S).mp4 

oder Befehl ist

MP4Box -cat file1.mp4 -cat file2.mp4 -new mergedFile.mp4 

mit mencoder und avconv könnte ich es nicht schaffen :-(

2
Mark

Danke für das Skript dvo. Es war ein großartiger Ausgangspunkt für mich. Ich hatte kein Problem mit Named Pipes, also passte ich das Skript an, um sie stattdessen zu verwenden. Außerdem habe ich es korrigiert, mit Dateinamen mit Leerzeichen zu arbeiten. Die Ausgabe an Named Pipes "geht" nicht, bis Sie mit dem Lesen beginnen. Daher müssen Sie die anfänglichen Remux-Tasks mit einem & vor dem endgültigen Aufruf von avconv hinterlegen. Vergessen Sie nicht, -c copy zu verwenden. Andernfalls müssen Sie die gesamte Partie neu codieren.

#!/bin/bash for FILE in "$@"; do TAG=$(echo "$FILE" | sed -e s/[^A-Za-z0-9.]/_/g) mkfifo $TAG.mp4concatpipe avconv -loglevel "quiet" -i "$FILE" -f mpegts -c copy -bsf h264_mp4toannexb -y $TAG.mp4concatpipe & IN=$IN\|$TAG.fifo done  IN=$ avconv -i concat:$IN -c copy out.mp4 rm *.mp4concatpipe 
Aus irgendeinem Grund gibt es einen "concat: first.m4v.fifo | second.m4v.fifo: Keine solche Datei oder ein solches Verzeichnis", selbst wenn die Anführungszeichen (-i concat: "$ IN" oder -i "concat: $ IN "). Die in der anderen Antwort unten vorgeschlagene MP4Box funktioniert jedoch großartig! vorburger vor 9 Jahren 0
2
Robert Cole

Auf einem Mac (macOS 10.13 High Sierra) habe ich mit Erfolg Folgendes verwendet:

for f in *.m4a; do echo "file '$f'" >> mylist.txt; done 

Falls erforderlich, die Reihenfolge wie oben ähnlich ändern (beachten Sie, dass ./ entfernt wurde - der Pfad hat dazu geführt, dass ffmpeg den unsicheren Dateinamenfehler ausgelöst hat).

Dann musste ich den für den Standard-MacPorts ffmpeg angegebenen Codec und die Bitrate entfernen, um ihn zu mögen:

ffmpeg -f concat -i mylist.txt output.m4a 
Willkommen bei Super User !, Bitte lesen Sie die Frage noch einmal sorgfältig. Ihre Antwort beantwortet nicht die ursprüngliche Frage zu Linux. Wenn Sie der Meinung sind, dass es unter Linux funktionieren wird, fügen Sie bitte hinzu, dass zukünftige Leser ein klares Verständnis haben. Ansonsten können Sie sich auch bei Superuser und vielen Dank für Ihre Beiträge entscheiden. Bitte nehmen Sie sich ein paar Minuten und lesen Sie: - http://superuser.com/help .Answering: http://superuser.com/help/how-to-answer. mic84 vor 6 Jahren 0
1
dvo

Thanks evilsoup; here is a little script to automate the process, using the more recent avconv.
BTW, named pipes did not work for me (output to them got stuck).

 #!/bin/bash for FILE in $@; do avconv -i $FILE -map 0 -f mpegts -bsf h264_mp4toannexb -c:v copy -y $FILE.tmp IN=$IN\|$FILE.tmp done IN=$ avconv -i concat:"$IN" out.mp4 for FILE in $@; do rm $FILE.tmp done 
0
Benjamin

Habe großen Erfolg mit gehabt

for f in ./*.m4a; do echo "file '$f'" >> mylist.txt; done 

Sie müssen mylist.txt möglicherweise leicht neu ordnen

ffmpeg -f concat -i mylist.txt -c:a libfdk_aac -b:a 128k output.m4a 

ffmpeg Version 2.2.3