Ich möchte einen FFmpeg-Suchbefehl, der so schnell und genau ist. Ich fand diese .
Die Lösung ist, dass wir uns sowohl -ss
für die Eingabe (schnelle Suche) als auch für die Ausgabe (genaue Suche) bewerben . Aber: Wenn die Eingabesuche nicht genau ist, wie können wir dann sicher sein, dass die Suchposition genau ist?
Zum Beispiel: Wenn wir nach 00:03:00 suchen wollten, ist der Befehl ungefähr so:
ffmpeg -ss 00:02:30 -i <INPUT> ... -ss 00:00:30 <OUTPUT>
Der erste -ss
wird sich irgendwo anders umsehen 00:02:30
, sagen wir nicht 00:02:31
. Und nach der zweiten Suche wäre das Endergebnis 00:03:01
- nicht das, was wir wollen. Ist das korrekt?
Wohin strebt der Erste -ss
? Sucht es nach dem Keyframe, der am nächsten ist 00:02:30
?
Wenn ja, hier ist mein Gedanke - korrigieren Sie mich, wenn ich mich irre: Nach der ersten Suche erhalten wir den Zeitstempel des Ergebnisses (in diesem Beispiel:) 00:02:31
, dann wenden wir in diesem Fall die zweite Suche mit angemessener Zeit an 00:00:29
.
Die Frage ist: Wie erhalten wir den Zeitstempel des ersten Suchergebnisses?
ffprobe
. Andernfalls würde ein Zwischenformat ausreichen, z. B. ProRes 422, DNxHD, die visuell verlustfrei sind und nur innerhalb eines Frames angezeigt werden. Oder du verwendest so etwas wie HuffYUV usw. Aber dann verlierst du natürlich wieder den "schnellen" Aspekt.Unrecognized option 'select_streams'
select_streams
Option wurde im Oktober 2012 hinzugefügt . :) Sie könnten darauf verzichten, aber dann würden Sie auch Informationen für Audio-Frames erhalten, gemischt dazwischen.Ich verstehe, dass diese Frage einige Jahre alt ist, aber die neueste Version von ffprobe kann Frames überspringen . Sie können
-skip_frame nokey
nur Informationen zu den Keyframes (I-Frames) melden. Das kann Ihnen viel Zeit sparen! Bei einer 2 GB 1080p MP4-Datei dauerte es ohne die überspringenden Frames 4 Minuten. Das Hinzufügen des Skip-Parameters dauert nur 20 Sekunden.Befehl:
ffprobe -select_streams v -skip_frame nokey -show_frames -show_entries frame = pkt_pts_time, pict_type D: \ test.mp4
Ergebnisse:
Die Ergebnisse enthalten also nur Informationen zu den Keyframes.
quelle
Aufbauend auf der Antwort von slhck ist hier eine Bash-Funktion, die den nächsten Keyframe zurückgibt , der VOR
N
Sekunden auftritt .Dadurch wird auch
-read_intervals
sichergestellt, dass ffprobe erst 25 Sekunden vorN
Sekunden nach Ihrem Keyframe sucht . Dieser Trick und das Beenden von awk, wenn der Zeitstempel gefunden wird, beschleunigen die Dinge erheblich.Beispielverwendung:
Ich benutze dies, um Videodateien zu schneiden, ohne sie neu zu kodieren. Da Sie keine neuen Keyframes hinzufügen können, ohne sie neu zu codieren,
ffnearest
suche ich vor dem Ausschneiden nach dem Keyframe. Hier ist ein Beispiel:Beachten Sie, dass Sie in diesem Beispiel möglicherweise das Format der
-ss
Übergabe im Parameter ändern müssen, wenn Sie länger als die ersten 60 Sekunden suchen.(Es ist ärgerlich, wenn ffmpeg angewiesen wird, genau nach dem Zeitstempel des Keyframes zu suchen, um diesen Keyframe in der Ausgabe auszuschließen, aber 0,5 Sekunden vom tatsächlichen Zeitstempel des Keyframes abzuziehen, ist der Trick. Für bash müssen Sie
bc
Ausdrücke mit Dezimalstellen auswerten , aber in zsh-ss 00:00:$[$(ffnearest input.mkv 28)-0.5]
funktioniert.)quelle
Wenn Sie Informationen über die I-Frames erhalten möchten, können Sie verwenden
quelle