Extrahieren des Index von Schlüsselbildern aus einem Video mit ffmpeg

13

Ich verwende ffmpeg zum Extrahieren von Keyframes aus einem Video. Dies ist der Befehl:

ffmpeg -i test2.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg

Wie kann ich den Index jedes Keyframes im Video extrahieren lassen? Für den ersten I-Frame wäre der Index beispielsweise 0, für den zweiten 24 usw.

Faten Khalifa
quelle
möglich Duplikat superuser.com/questions/669716/...
user236012
Schauen Sie sich mit ffprobe um und verarbeiten Sie die Ausgabe nach, um den Index zu erhalten.
Dienstag,
@dstob könntest du mehr darüber erklären, was du meinst? da bin ich neu bei ffmpeg.
Faten Khalifa
@LordNeckbeard Die Bildnummer in den Videobildern, z. Das erste Bild des Videos wäre bei Index 0. Ich möchte den Index jedes Schlüsselbildes in den Videobildern kennen.
Faten Khalifa
Sie möchten, dass die Bildnummer auf das Vorschaubild (auf das Bild selbst) gedruckt wird?
Logan

Antworten:

19

Wie @dstob bereits erwähnt, können Sie ffprobedie I-Frames und die zugehörigen Informationen abrufen . ffprobeenthält einige der statischen Builds auf der Download-Seite und kann auch aus dem Quellcode erstellt werden.

Dies setzt voraus, dass Sie unter Linux / Unix arbeiten:

Frames und Frame-Typen extrahieren

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1

Der grepBefehl filtert die darin enthaltenen Zeilen Iund zählt deren Index (mithilfe der -nOption). Der cutBefehl wählt nur die erste Spalte der Ausgabe aus (den Index). Beachten Sie, dass dieser Index auf 1 und nicht auf 0 basiert.

Benennen Sie Ausgabedateien basierend auf dem Index um

Sie können diese Indizes tatsächlich an eine Liste weiterleiten:

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1 > frame_indices.txt

Machen Sie dann auch eine Liste aller Thumbnails:

ls -1 thumbnails*.jpeg > thumbnails.txt

Dann fügen Sie diese beiden zusammen:

paste thumbnails.txt frame_indices.txt > combined.txt

Die Liste enthält nun den Namen des Thumbnails und den Index. Führen Sie eine Umbenennung basierend darauf durch:

while read -r thumbnail index; do
  newIndex=$(echo $index - 1 | bc) # subtract 1 from the index
  mv -- "$thumbnail" "thumbnail-$newIndex.jpeg"  # rename file
done < combined.txt

Die oben genannten werden umbenannt thumbnail-01.jpegin thumbnail-0.jpeg. Beachten Sie, dass der Ausgabeindex nicht mit Nullen aufgefüllt wird. Wenn Sie es auf 5 Ziffern auffüllen möchten, verwenden Sie printf:

newIndex=$(printf '%05d' $(echo $index - 1 | bc))

Unter Windows würden Sie genau dasselbe tun, ffprobeaber die Ausgabe anders analysieren. Keine Ahnung, wie man die Umbenennung dort vornimmt.

slhck
quelle
Dieser Fehler wird angezeigt: 'grep' wird nicht als interner oder externer Befehl, ausführbares Programm oder Batch-Datei erkannt.
Faten Khalifa
2
Das liegt daran, dass Sie unter Windows arbeiten. Wie gesagt, diese Antwort setzt Linux oder Unix voraus. Sie waren in Ihrer Frage nicht genauer. Sie können dasselbe unter Windows erreichen, indem Sie Cygwin oder ähnliche GNU / Linux-Ebenen für Windows verwenden.
Slhck
Das ist eine große Hilfe, danke. Eine Korrektur: Ich denke, die Indizes in Ihrem ersten Befehl sind um den Faktor drei versetzt, weil es für jede Zeile eine [FRAME]Linie und eine Linie gibt. [/FRAME]pict_type
Jack O'Connor
2
@ JackO'Connor Es gibt nur eine Zeile pro Frame, wenn Sie die -of csvOption für verwenden ffprobe. Sie beschreiben jedoch das Standardausgabeformat.
Slhck
0

Wenn Sie FFMPEG wie ursprünglich angegeben verwenden möchten, können Sie eine vollständige oder teilweise Auflistung sowie eine JPG-Datei mit den folgenden Angaben erstellen:

ffmpeg.exe \
  -i "C:\Users\UserName\Desktop\jpegs and list\VideoName.mp4" \
  -t 15 \
  -vf select="eq(pict_type\,PICT_TYPE_I)" \
  -vsync 2 \
  -s 160x90 \
  -f image2 thumbnails-%02d.jpeg \
  -loglevel debug 2>&1| for /f "tokens=4,8,9 delims=. " %d in ('findstr "pict_type:I"') do echo %d %e.%f>>"keyframe_list.txt"

Unbefristet entfernen -t 15oder Anzug wechseln. -s 160x90 -f image2 thumbnail-%02d.jpegZum Entfernen von Thumbnails entfernen oder ändern.

Budman1
quelle