Videodateien interaktiv verketten


9

Wie können mehrere MP4-Videodateien interaktiv zu einer Datei verknüpft werden?

Es gibt viele Programme, die dies für zwei Dateien über die Befehlszeile tun. Zum Beispiel:

  • ffmpeg
  • avconv
  • MP4Box

Dafür benötigen wir jedoch häufig eine Lösung.


1
Können Sie beschreiben, was Sie unter interaktiv verstehen?
slm

@slm Ich meine ein Programm, das den Benutzer auffordert, die Eingabedateien einzeln einzugeben und dann die Ausgabedatei zu erstellen. und dann die Verkettung machen.
Slyx

Ich habe noch nie ein Programm gesehen, das dies direkt ausführt. Es ist so, wie Sie es erstellt haben, ein Shell-Skript, das die Informationen sammelt und dann die Befehlszeile zusammenstellt. Suchen Sie nach Verbesserungen gegenüber dem, was Sie haben?
slm

@slm Ich habe dies gepostet, weil es ein häufiges Bedürfnis für Multimedia-Benutzer wie mich ist. Also hoffe ich, dass es jemand anderem hilft. Verbesserungen sind natürlich mehr als willkommen!
Slyx

1
@gold Ich habe eine Bearbeitung in die Warteschlange gestellt. ffmpegist in der Tat keineswegs tot oder veraltet: Das letzte gitCommit masterwar vor 15 Minuten und ich benutze es täglich.
Anko

Antworten:


8

Ich habe diese Methode in letzter Zeit nicht ausprobiert, verstehe aber nicht, warum sie nicht noch funktioniert. Ich glaube, Sie können nur cat .mp4Dateien zusammenfügen, wenn Sie nichts anderes tun möchten, als sie zu verketten.

1. Mit Katze

$ cat file1.mp4 file2.mp4 > file3.mp4
$ ffmpeg -i file3.mp4 -qscale:v 2 output.avi

Ich benutze immer noch die ffmpegganze Zeit, es kann auch Dateien verketten.

2. Verwenden von ffmpeg

  1. Erstellen Sie eine Liste der zu verkettenden Dateien

    $ cat inputs.txt 
    file sample_mpeg4.mp4
    file sample_mpeg4.mp4
  2. verketten

    $ ffmpeg -f concat -i inputs.txt -c copy out.mp4
    
    $ ll |grep -E "sample|out"
    -rw-rw-r--. 1 saml saml 491860 Feb 19 23:36 out.mp4
    -rw-r--r--. 1 saml saml 245779 Feb 19 23:32 sample_mpeg4.mp4

    Weitere Methoden werden im FFmpeg-Wiki behandelt: Verketten (Verbinden, Zusammenführen) von Mediendateien .

    HINWEIS: Ubuntu scheint das concatFormat nicht zu unterstützen . Sie müssen das Concat-Protokoll verwenden. Darüber hinaus verfügt es über Codec-Optionen pro Stream. Die Verwendung des Concat-Protokolls führt daher zu folgenden Ergebnissen:

    $ ffmpeg -i input1.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate1.ts
    
    $ ffmpeg -i input2.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate2.ts
    
    $ ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" \
         -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4

    Ubuntu ffmpeg-Optionen sind hier dokumentiert .


Interessant! Ich wusste nicht, dass catdas für MP4-Dateien ausreicht! Die Lösung ist jedoch nicht interaktiv!
Slyx

@Slyx - ja, deshalb habe ich gefragt, was du mit interaktiv meinst. Lassen Sie mich sehen, was Sie dazu gesagt haben, und sehen, was ich dazu hinzufügen kann. Überprüfen Sie, ob dies catfunktioniert. Das letzte Mal, als ich es benutzte, war es mit .mpgDateien und es def. arbeitete mit denen.
slm

2
Ich habe das überprüft. Die Verwendung catist keine gültige Lösung. Die generierte Datei aus catzwei Dateien zeigt nur den Inhalt der ersten Eingabedatei!
Slyx

@Slyx - cat funktioniert, aber die Zeitstempel sind nicht korrekt. Wenn Sie also versuchen, es wiederzugeben, wird der Videoplayer durch den Zeitstempelsprung von 00 bis zum Ende und dann zurück zu 00 verwirrt. Wenn Sie das Video transkodieren würden würde als Teil dieses Prozesses behoben werden. Es gibt auch Möglichkeiten, die Zeitstempel neu zu generieren.
slm

Das meine ich auch. Die beiden Inhalte sind vorhanden, aber der Media Player erkennt nur den ersten.
Slyx

4

Ich benutze MP4Box als Arbeitsbasis.
Das Skript, das ich vorschlage, liest alle Dateien nacheinander und überprüft jede (ob es sich um eine normale Datei handelt). Der Benutzer wird aufgefordert, den eingegebenen Dateinamen zu erstellen.

#!/bin/bash
printf "###  Concatenate Media files ###\n"
fInputCount=0
# Reading input files
IFS=''
while (true)
do
    let currentNumber=$fInputCount+1 
    printf "File n°%s (\"ok\" to finish): " $currentNumber
    read inputFile
    [ "$inputFile" == "ok" ] && break
    [ ! -e "$inputFile" ] || [ ! -f "$inputFile" ] && printf "\"%s\" : Invalid filename. Skipped !\n" "$inputFile" && continue
    ((fInputCount++))
    inputFileList[$fInputCount]=$inputFile
    printf "\"%s\" : Added to queue !\n" "$inputFile"
done
[ "$fInputCount" == "0" ] || [ "$fInputCount" == "1" ] && echo "No enough input data. BYE ! " && exit
# Listing the input file list 
for ((i=1;i<=$fInputCount;i++))
do
    printf "%2d : %s\n" $i ${inputFileList[$i]}
done
# Reading the output filename
while (true)
do
    printf "Output file without extention (\"none\" to dismiss) : "
    read outputRead
    [ "$outputRead" == "none" ] && echo "Dismissed. BYE ! " && exit
    [ "$outputRead" == "" ] && echo "Try again ! " && continue
    [ -e "$outputRead" ] && echo "\"$outputRead\" exists. Try again !" && continue
    outputFile=$outputRead.mp4
    echo "Output to \"$outputFile\". Go !" && break
done
# Creating a random temporary filename
tmpOutFile="/tmp/concatMedia"`date +"%s%N"| sha1sum | awk '{print $1}'`".mp4"
# Joining the two first input files
MP4Box -cat "${inputFileList[1]}" -cat "${inputFileList[2]}" $tmpOutFile
# Adding all other files
for ((i=3;i<=$fInputCount;i++))
do
    tmpIntermediateFile=$tmpOutFile
    tmpOutFile="/tmp/concatMedia"`date +"%s%N"| sha1sum | awk '{print $1}'`".mp4"
    MP4Box -cat $tmpIntermediateFile -cat "${inputFileList[$i]}" $tmpOutFile
    rm $tmpIntermediateFile
done
mv $tmpOutFile "$outputFile"
# Finished
echo "\"$outputFile\" Saved !"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.