Ich versuche, einige Abschnitte eines Videos mit FFmpeg zu löschen.
Stellen Sie sich zum Beispiel vor, Sie hätten eine Sendung im Fernsehen aufgenommen und wollten die Werbespots ausschneiden. Dies ist mit einem GUI-Video-Editor einfach. Sie markieren einfach den Anfang und das Ende jedes zu entfernenden Clips und wählen Löschen. Ich versuche das gleiche über die Kommandozeile mit FFmpeg zu machen.
Ich weiß, wie man ein einzelnes Segment zu einem neuen Video schneidet :
ffmpeg -i input.avi -ss 00:00:20 -t 00:00:05 -map 0 -codec copy output.avi
Dadurch wird ein fünf Sekunden langer Clip geschnitten und als neue Videodatei gespeichert. Wie kann ich jedoch das Gegenteil tun und das gesamte Video ohne den angegebenen Clip speichern und wie kann ich angeben, dass mehrere Clips entfernt werden sollen?
Wenn mein Video beispielsweise durch ABCDEFG dargestellt werden könnte, würde ich gerne ein neues Video erstellen, das aus ACDFG besteht.
quelle
Antworten:
Nun, Sie können immer noch den
trim
Filter dafür verwenden. Angenommen, Sie möchten die Segmente 30-40 Sek. (10 Sek.) Und 50-80 Sek. (30 Sek.) Ausschneiden:Was habe ich hier gemacht? Ich habe die ersten 30 Sekunden, 40-50 Sekunden und 80 Sekunden bis zum Ende getrimmt und sie dann
out1
mit demconcat
Filter zu einem Strom kombiniert .Über Setpts: Wir brauchen dies, weil das Trimmen die Bildanzeigezeit nicht verändert, und wenn wir den 10-Sekunden-Decoderzähler ausschneiden, werden für diese 10 Sekunden keine Frames angezeigt.
Wenn Sie auch Audio haben möchten, müssen Sie dasselbe für Audio-Streams tun. Der Befehl sollte also lauten:
quelle
Ich kann die Lösung von ptQa nie zum Laufen bringen, hauptsächlich, weil ich nie herausfinden kann, was die Fehler der Filter bedeuten oder wie sie behoben werden können. Meine Lösung scheint etwas umständlicher zu sein, da sie ein Durcheinander hinterlassen kann. Wenn Sie sie jedoch in ein Skript einschleusen, kann die Bereinigung automatisiert werden. Ich mag diesen Ansatz auch deshalb, weil, wenn in Schritt 4 etwas schief geht, die Schritte 1 bis 3 ausgeführt werden und die Wiederherstellung nach Fehlern etwas effizienter ist.
Die grundlegende Strategie verwendet
-t
und-ss
Videos von jedem Segment Sie wollen, dann verbinden sich alle Teile für die endgültige Version zu bekommen.Angenommen, Sie haben 6 Segmente ABCDEF, die alle 5 Sekunden lang sind, und Sie möchten A (0-5 Sekunden), C (10-15 Sekunden) und E (20-25 Sekunden).
oder
Damit werden die Dateien a.tvshow, c.tvshow und e.tvshow erstellt. Das
-t
sagt, wie lang jeder Clip ist. Wenn c 30 Sekunden lang ist, können Sie 30 oder 0:00:30 eingeben. Die-ss
Option gibt an, wie weit das Quellvideo übersprungen werden soll, sodass es sich immer auf den Anfang der Datei bezieht.Sobald Sie eine Reihe von Videodateien haben, erstelle ich eine Datei
ace-files.txt
wie die folgende:Notieren Sie sich die "Datei" am Anfang und den Namen der zu maskierenden Datei.
Dann der Befehl:
Das fasst alle Dateien
abe-files.txt
zusammen, kopiert ihre Audio- und Videocodecs und erstellt eine Datei,ace.tvshow
die nur die Abschnitte a, c und e enthalten sollte. Dann erinnere mich nur zu löschenace-files.txt
,a.tvshow
,c.tvshow
unde.tvshow
.Haftungsausschluss : Ich habe keine Ahnung, wie (in) effizient dies im Vergleich zu den anderen Ansätzen ist,
ffmpeg
aber für meine Zwecke funktioniert es besser. Hoffe es hilft jemandem.quelle
ace-files.txt
in Ihrem Beispiel) vermeiden, indem Sie :ffmpeg -f concat -i <(printf "file '%s'\n" $(pwd)/prefix_*.tvshow) -c copy output.tvshow
Ich habe ein Skript erstellt, um die Bearbeitung von aufgezeichnetem Fernsehen zu beschleunigen. Das Skript fragt Sie nach den Anfangs- und Endzeiten der Segmente, die Sie behalten möchten, und teilt sie in Dateien auf. Sie haben folgende Möglichkeiten:
Video davon in Aktion: hier
Lass mich wissen was du denkst.
quelle
safe=0
, dhffmpeg -f concat -safe 0 -i ...
Siehe ffmpeg.org/ffmpeg-all.html#Options-36Obwohl die Antwort von ptQa zu funktionieren scheint, habe ich eine andere Lösung entwickelt, die bewiesen hat, dass sie gut funktioniert.
Im Wesentlichen schneide ich ein Video für jeden Teil des Originalvideos aus, den ich in mein Ergebnis aufnehmen möchte. Später habe ich verketten sie mit der Concat Demuxer erklärt hier .
Die Lösung ist die gleiche, die ich zuerst ausprobiert und Synchronisierungsprobleme vorgestellt habe. Was ich hinzugefügt habe, ist der Befehl -avoid_negative_ts 1 beim Generieren der verschiedenen Videos. Mit dieser Lösung verschwinden die Synchronisierungsprobleme.
quelle
Für diejenigen, die Probleme haben, dem Ansatz von ptQa zu folgen, gibt es einen etwas rationaleren Weg, dies zu tun. Anstatt jeden Schritt des Weges zu konzentrieren, mache sie einfach alle am Ende.
Definieren Sie für jeden Eingang ein A / V-Paar:
Definieren Sie so viele Paare, wie Sie benötigen, und fassen Sie sie dann in einem Durchgang zusammen, wobei n = Gesamtanzahl der Eingaben ist.
Dies kann leicht in einer Schleife aufgebaut werden.
Ein vollständiger Befehl, der zwei Eingaben verwendet, könnte folgendermaßen aussehen:
quelle