So verketten Sie Clips aus demselben Video mit ffmpeg


15

Ich habe ein langes Video mit verschiedenen Szenen. Ich möchte mit ffmpeg 2.1.4 2 Szenen aus dem Video extrahieren und verketten (die nicht auf einem I-Frame beginnen).

Nehmen wir als Argument an, ich möchte 5 Sekunden zwischen 01:00 und 02:00.

Ich kann dies tun:

ffmpeg -ss 01:00 -i in.mkv -ss 02:00 -i in.mkv -filter_complex "
  [0:v]select='lt(t,5)'[v0];
  [0:a]aselect='lt(t,5)'[a0];
  [v0][a0][1:v][1:a]concat=n=2:v=1:a=1
" -c:a libvorbis -t 10 out.mkv

Das gibt mir den gewünschten Film, aber select zwingt ffmpeg tatsächlich dazu, den gesamten Rest des Films zu dekodieren. Wie kann ich es also veranlassen, den ersten Film abzuschneiden, anstatt ihn zu dekodieren?

Ich würde es vorziehen, wenn möglich, dies mit einem komplexen ffmpeg-Filter zu tun. Ich weiß, dass ich nur verwenden kann, -tum zuerst separate Filme zu rekodieren, aber der zusätzliche Kodierungsschritt ist in meinem Fall sehr langsam und verliert auch einiges an Qualität für dieses Video.

Ich kann anscheinend keinen Filter finden, der die Länge eines Dampfes abschneidet. Gibt es Filterknoten, die den Parametern -toder entsprechen -ss?

Antworten:


16

Konzentratfilter

Diese Methode empfiehlt sich, wenn Sie zusätzliche Filterung durchführen müssen:

Verwenden Sie die trim, atrim, setpts, asetpts, und concatFilter:

ffmpeg -i input -filter_complex \
"[0:v]trim=60:65,setpts=PTS-STARTPTS[v0]; \
 [0:a]atrim=60:65,asetpts=PTS-STARTPTS[a0]; \
 [0:v]trim=120:125,setpts=PTS-STARTPTS[v1];
 [0:a]atrim=120:125,asetpts=PTS-STARTPTS[a1]; \
 [v0][a0][v1][a1]concat=n=2:v=1:a=1[out]" \
-map "[out]" output.mkv
  • setptsund asetptsverhindert eine ruckelnde Ausgabe aufgrund von Problemen mit dem Präsentationszeitstempel.

  • Stellen Sie sicher, dass Sie eine aktuelle Version verwenden. Auf der FFmpeg-Download- Seite finden Sie Links zu Builds für Windows, OS X und Linux.


concat demuxer

Eine andere Methode besteht darin, die Segmente einzeln zu erstellen und zu kopieren , anstatt sie neu zu codieren (um Zeit und Qualität zu sparen), und sie mit dem Concat-Demuxer zu verbinden .

$ ffmpeg -ss 60 -i input -t 5 -codec copy clip1.mkv
$ ffmpeg -ss 120 -i input -t 5 -codec copy clip2.mkv
$ echo "file 'clip1.mkv'" > concat.txt
$ echo "file 'clip2.mkv'" >> concat.txt
$ ffmpeg -f concat -i concat.txt -codec copy output.mkv

2
Ah danke. Ordnung ist das, was mir gefehlt hat. Es dauert jedoch sehr lange, bis der von mir angegebene Zeitversatz erreicht ist, als würde alles bis dahin dekodiert. Außerdem fehlte in einem Teil der Ausgabe Audio. Um das Problem zu beheben, habe ich dieselbe Eingabe mehrmals mit -ss angegeben und dann das Video mit Trim abgeschnitten. In diesem Fall brauchen Sie keine setpts, da ss pts auf 0 setzt. Das schien zu funktionieren und hatte keine seltsamen zufälligen Pausen während der Codierung. Das Kopieren von Streams habe ich bereits versucht. Es beginnt beim vorherigen I-Frame, sodass Sie einen anderen Teil des Films als den gewünschten erhalten.
18

Würden Sie bitte meine Frage beantworten, die dieser ähnlich ist? video.stackexchange.com/questions/18247/…
Eftekhari

Interessanterweise -filter_complexfunktioniert das, aber die concatDateien nicht - dh das erste Video sieht gut aus, aber die Qualität des zweiten ist schrecklich. Beachten Sie, dass ich diese Befehle genau für beide kopiert habe (mit Ausnahme der Eingabedatei).
Bobmarksie

7

Das sollte schneller gehen ...

ffmpeg -ss 1:00 -t 5 -i in.mkv -ss 2:00 -t 5 -i in.mkv \
  -filter_complex "[0][1]concat=n=2:v=1:a=1" \ 
  out.mkv

Es ist nicht erforderlich, -t in der Ausgabe anzugeben. Es ist nicht erforderlich, Audio und Video vor dem Concat zu trennen.


1
Hierfür wird der Concat-Filter verwendet, für den eine Neucodierung erforderlich ist. Dies kann vom Benutzer gewünscht oder nicht gewünscht werden.
Logan
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.