Wie schneide ich mit ffmpeg bei exakten Frames?

22

Ich versuche, ffmpeg zu verwenden, um Videodateien zu genauen Zeiten zu schneiden. In der ffmpeg-Hilfe wird die Option -timecode_frame_start angezeigt, mit der der Start-Frame angegeben werden kann. Es ist jedoch nicht möglich, diesen Befehl zum Laufen zu bringen. Das resultierende Video beginnt immer am Anfang des Originalvideos. Hier ist ein Beispiel für den Befehl, den ich ausführe:

ffmpeg -i input.mpg -acodec copy -vcodec copy -timecode_frame_start 200 -vframes 210 -n ouput.mpg

Ich habe die Option timecode_frame_start vor und nach den anderen Optionen verschoben, ohne dass sich die Ergebnisse geändert haben. Gibt es eine zusätzliche Option, die ich angeben muss? Ich habe verschiedene Dateiformate ausprobiert, mkv, avi, mp4, und es scheint nicht, dass das Problem mit dem Codec zusammenhängt. Hier ist eine Datei, die ich ausprobiert habe:

http://www.seaotter.com/marine/movies/hermit-long-01.mpg

Vermisse ich etwas?

curmil
quelle
Es scheint, dass dies auf der Mailingliste beantwortet wurde (und NB, dass mit -vcodec copy kein "richtiges" Frame-spezifisches Schneiden möglich ist, da es nur auf i-Frames resynchronisiert werden kann
Rogerdpack
@ user39364 Ich habe auf der Mailingliste nachgefragt und es stellte sich heraus, dass diese Option nicht das tut, was das OP will. Ich habe auch etwas Neues gelernt :)
slhck
Just zu beachten wollte , dass ich ein Verfahren zum Schneiden bei genauen Rahmen mit gefunden meltsehen, genau geschnitten Videodateien von der Kommandozeile - Super User
sdaau

Antworten:

46

Ich habe gerade erfahren, dass das timecode_frame_startso nicht funktioniert. Die einzige Möglichkeit, bei bestimmten Frames zu beginnen, besteht darin, eine Reihe von Frames in ss.msSyntax umzuwandeln hh:mm:ss.ms. Wenn Ihr Video also 25 fps hat und Sie mit 133 Bildern beginnen möchten, benötigen Sie

133/25 = 5,32

Also renn

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac out.mp4

Beachten Sie, dass das Ausschneiden exakter Frames mit bitstream copy ( -c:v copy) nicht möglich ist, da nicht alle Frames intra-codiert sind und für sich alleine stehen können.

-ss wird immer rahmengenau sein.

Wenn Sie eine bestimmte Anzahl von Frames codieren möchten, verwenden Sie -frames:vzum Beispiel:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac -frames:v 60 out.mp4

Sie können auch Videofilter verwenden , die Audiounterstützung ist jedoch möglicherweise nicht exakt. Und anscheinend ist das Suchen nach Frames immer noch kein Feature. Sie können diesem FFmpeg-Benutzer-Mailinglisten-Thread folgen, um weitere Informationen zu erhalten:

Sie können -vf selectfür eine genaue Rahmenauswahl verwenden (so etwas wie -vf 'select=gte(n\,100)'das Überspringen der 100 ersten Rahmen)

slhck
quelle
3
für Videos mit Drop-Frames (z. B. 29,97 fps), die länger als 10 Minuten sind; Wie würden Sie vorgehen, um die Zeit für ein bestimmtes Bild genau zu berechnen?
GFoley83
Die select=gte(n\,100)Methode funktioniert, aber das Suchen verschlingt die Leistung. Wenn Sie testen, indem Sie nur 30 Frames gleichzeitig codieren: Je weiter ich in das Video starte, desto länger dauert die Ausführung von ffmpeg, da gesucht wird.
Adam Grant
6

Die Option

-vf select = "zwischen (n \, start_frame_num \, end_frame_num ), setpts = PTS-STARTPTS"
z.B,

-vf select=“between(n\,200\,300),setpts=PTS-STARTPTS"

Schneidet das Video vom 200. bis zum 300. Frame (einschließlich), beginnt die Sequenzzählung bei 0.

Nuo Chen
quelle