Wie füge ich mehrere (mehr als zwei) Videos unter Ubuntu zusammen?

38

Ich möchte Videos in einer Stapelgröße von jeweils zwanzig (20) zusammenführen. Ich verwende eine Linux-Maschine. Die Videos sind im mp4-Format und mäßiger Qualität. Bei einigen fehlt sogar der Audiostream. Bisher habe ich versucht ffmpeg, mencoder, cvlc/vlcund MP4Box. Ich möchte ein Befehlszeilenskript schreiben, um dies zu erreichen, da ich die Stapelverarbeitung durchführe.

Das Hauptproblem ist, dass einige der Lösungen, die ich ausprobiert habe, für zwei Videos gut funktionieren, einige für Videos mit Audiostream und wieder andere für eine andere Teilmenge meines Videosets. Für diese Aufgabe konnte ich jedoch keine umfassende Lösung finden.

Dhruv Singal
quelle
2
Bitte fragen Sie nicht gleiche Frage in mehreren SE - Sites: superuser.com/questions/928548/...
Maythux
Könnten Sie genau das posten, was Sie bisher versucht haben?
Ohaal
1
@ohaal Ich habe versucht, verschiedene in angegebene Verkettungsmethoden zu verwenden ffmpeg, einschließlich Filter und Dateiprotokolle . Ich habe auch versucht, die concatFunktion von zu verwenden cvlc/vlc. Ich habe auch die concatFunktion von ausprobiert mencoder. All dies funktionierte teilweise. Dies half mir schließlich, die Angelegenheit zu lösen.
Dhruv Singal
Ja, Sie haben die Tools bereits erwähnt. Was ich damit meinte, waren die tatsächlichen Befehle, die Sie ausgeführt haben. Es wäre auch großartig, wenn Sie den Befehl, der letztendlich für Sie gelöst wurde (in Ihre Antwort), für zukünftige Besucher aufnehmen könnten.
Ohaal
Aah, ich verstehe deinen Standpunkt. Leider kann ich die Befehle aufgrund der bloßen Nummer nicht auflisten. Der Befehl, der mein Problem löste, war diesermelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal

Antworten:

41

Ich verwende mkvmerge, um mehrere MP4-Dateien zu einer einzigen zu verbinden:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4
Szabolcs Spindler
quelle
3
Es ist besser, die Erweiterung .mkvfür die Ausgabedatei zu verwenden, da es sich um einen Matroska-Container handelt, unabhängig davon, welche Erweiterung Sie angeben.
Haridsv
So installieren Sie mkvmerge: tipsonubuntu.com
Morgoth
Nur dieser Befehl mkvmerge funktioniert. Alle ffmpeg-Dateien schlagen mindestens mit verschobenem Audio fehl.
22.
25

Sie können es tun mit ffmpeg:

ffmpeg -i concat:"input1.mp4|input2.mp4" output.mp4

Referenz und weitere Infos

Maythux
quelle
2
Ich habe es versucht. Das Problem dabei ist, dass es kein richtiges Out gibt. 1. Die Audiospuren sind durcheinander. 2. Es liegt eine Störung in der Videospur vor.
Dhruv Singal
Ich habe es für mehr als Probe verwendet, das Ergebnis ist hohe Qualität, vielleicht ist Ihre Quellvideoqualität das Problem?
Maythux
Du hast vermutlich recht. Dies löste das Problem: askubuntu.com/a/637179/420614
Dhruv Singal
2
Verwenden Sie nicht das concat-Protokoll, um MP4 zu verketten. Es funktioniert nur mit bestimmten Formaten, denen die meisten allgemeinen Benutzer nicht begegnen. Verwenden Sie stattdessen Concat Demuxer oder Concat Filter .
Logan
Ich habe versucht, ffmpeg mit 2 mp4-Dateien von jeweils 30 Minuten. Ich habe eine Ausgabedatei mit einer Länge von 7 Stunden erhalten.
Guus
7

Dies löste die Angelegenheit: https://stackoverflow.com/a/22324018/5014767

meltist ein großartiges Kommandozeilen-Dienstprogramm. Hier ist die Seite

Bearbeiten von Kommentaren: Der Befehl, der mein Problem löste, war dieser melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264

Dhruv Singal
quelle
4

Ich habe ein kleines Shell-Skript geschrieben, um MP4-Dateien ohne Umcodierung mit ffmpeg zu komprimieren.

for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

Dadurch werden Zwischendateien in einem MPEG-Container erstellt und dann zu einem MP4 verkettet.

RawwrBag
quelle
Es ist wichtig zu beachten, dass dieses Skript fehlschlägt, wenn einer der Dateinamen Leerzeichen oder in einigen Fällen Sonderzeichen enthält. Für die Schleife ist es wesentlich besser, nur for f in *.MP4ohne zu verwenden ls. (Die Verwendung lsin Skripten sollte aus mehreren wichtigen Gründen vermieden werden. Es gibt bessere Optionen.) Verwenden Sie auch Anführungszeichen für Variablen, es sei denn, Sie sind sicher, dass keine Leerzeichen oder andere Sonderzeichen vorhanden sind, also "${f}"(oder nur "$f") anstelle von Anführungszeichen $f.
Paddy Landau
CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")funktioniert nicht gut mit Dateinamen, die 1, 2, 3 ... 10 ... 20 sind. Sie werden dann als 1, 10 ... 2, 20 ... usw. analysiert. Ich schlage vor, dass CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")dies die Reihenfolge sicherstellt .
Tisaconundrum
2

Erstellen Sie eine Datei files.txt mit allen Dateien, die Sie verketten möchten, in der folgenden Form (Zeilen, die mit einem # beginnen, werden ignoriert):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

Beachten Sie, dass dies entweder relative oder absolute Pfade sein können. Dann können Sie Ihre Dateien streamen, kopieren oder neu codieren:

ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
ShaDeRzz
quelle
0

Mein Drehbuch, rein in bashund ffmpeg. Kodiert in einer Befehlszeile angegebene Dateien neu in eine.

Erfordert, dass die Dateien dieselbe Auflösung haben. Akzeptiert verschiedene Metadatenrotationen, was ffmpeg concat:nicht der Fall ist.

rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"
Victor Sergienko
quelle
0

Ich habe ein Python-Skript erstellt , das mit moviepy auch Untersegmente verketten kann (nützlich, wenn Sie beispielsweise einige Teile aus einem Video entfernen möchten).

Verwenden Sie es mit:

vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>
Antonello
quelle
-1

Zusätzlich zu Maythuxs Antwort von :

Einige Multimedia-Container (MPEG-1, MPEG-2 PS, DV) ermöglichen die Verkettung von Videos, indem lediglich die Dateien verkettet werden, die diese enthalten.

Dh die zu verkettenden Videos verwenden einen der oben genannten Videocontainer (zu denen ich aus persönlichen Gründen MPEG-4 Part 14 hinzufüge). Sie können einfach:

cat video1.ext video2.ext video3.ext > video4.ext
kos
quelle
1
Ich habe es versucht, aber es wird nur das erste Video als Ausgabe zurückgegeben. Ich habe irgendwo gelesen, dass es nicht funktioniert, obwohl ich mich nicht an die Gründe dafür erinnere.
Dhruv Singal
@DhruvSingal Ja, das kann ich bestätigen, ich habe dies an zwei MP4-Videos mit genau der gleichen Video- / Audiokodierung versucht und da konnte ich nur das erste Video durchsuchen. Was vernünftig erscheint, aber ich bin mir ziemlich sicher, dass ich das schon einmal mit ein paar MP4-Videos gemacht habe. Vielleicht funktioniert das Gedächtnis hier nicht gut, oder es gibt andere Voraussetzungen dafür. Ich möchte darüber recherchieren, da ich auch interessiert bin. Wenn ich etwas finde, aktualisiere ich die Antwort und schreibe dir einen Kommentar
kos
Irgendwie müssen wir die Metadaten zu Beginn des ersten Videos ändern, um die gesamte Länge des kombinierten Films zu erfassen, und wahrscheinlich auch andere Dinge. Nur ein paar mpeg4-Dateien lassen mich die Metadaten sehen.
Ken Mollerup