Extraire l'index des images clés d'une vidéo à l'aide de ffmpeg

17

J'utilise ffmpeg pour extraire les images clés d'une vidéo. Voici la commande:

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

Comment puis-je obtenir l'index de chaque image clé extraite dans la vidéo? Par exemple, pour la première trame I, l'indice serait 0, pour la seconde, ce serait 24, etc.

Faten Khalifa
la source
doublon possible de superuser.com/questions/669716/…
user236012
Cherchez à utiliser ffprobe puis post-traiter la sortie pour obtenir l'index?
dstob
@dstob pourriez-vous expliquer davantage ce que vous voulez dire? comme je suis nouveau sur ffmpeg.
Faten Khalifa
@LordNeckbeard Le numéro d'image dans les images vidéo, ex. la première image de la vidéo serait à l'index 0 Je veux connaître l'index de chaque image clé dans les images vidéo.
Faten Khalifa
Vous souhaitez que le numéro du cadre soit imprimé sur la vignette (sur l'image elle-même)?
llogan

Réponses:

21

Comme @dstob mentionné, vous pouvez utiliser ffprobepour obtenir les images I et leurs informations associées. ffprobeest livré avec certaines des versions statiques sur la page de téléchargement et peut également être construit à partir des sources.

Cela suppose que vous êtes sous Linux / Unix:

Extraire des cadres et types de cadres

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

La grepcommande filtre les lignes avec Ielles et compte leur index (en utilisant l' -noption). La cutcommande sélectionne uniquement la première colonne de la sortie (l'index). Notez que cet index est basé sur 1, pas sur 0.

Renommer les fichiers de sortie en fonction de l'index

Vous pouvez réellement diriger ces index vers une liste:

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

Faites ensuite également une liste de toutes les vignettes:

ls -1 thumbnails*.jpeg > thumbnails.txt

Collez ensuite ces deux éléments ensemble:

paste thumbnails.txt frame_indices.txt > combined.txt

La liste contient maintenant le nom de la vignette et de l'index. Effectuez un changement de nom basé sur cela:

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

Ce qui précède renommera thumbnail-01.jpegà thumbnail-0.jpeg. Notez qu'il n'y a pas de remplissage nul sur l'index de sortie. Si vous voulez le mettre à zéro, disons, à 5 chiffres, utilisez printf:

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

Sous Windows, vous feriez exactement la même chose ffprobemais en analysant la sortie différemment. Cependant, je ne sais pas comment effectuer le changement de nom.

slhck
la source
Cette erreur s'affiche: 'grep' n'est pas reconnu comme une commande interne ou externe, un programme exploitable ou un fichier de commandes.
Faten Khalifa
2
C'est parce que vous êtes sous Windows. Comme je l'ai dit, cette réponse suppose Linux ou Unix. Vous n'étiez pas plus précis dans votre question. Vous pouvez obtenir la même chose sous Windows en utilisant Cygwin ou des couches GNU / Linux similaires pour Windows.
slhck
Ceci est d'une grande aide, merci. Une correction: je pense que les indices de votre première commande sont décalés d'un facteur trois, car il y a une [FRAME]ligne et une [/FRAME]ligne pour chaque pict_typeligne.
Jack O'Connor
2
@ JackO'Connor Il n'y a qu'une seule ligne par trame si vous utilisez l' -of csvoption pour ffprobe. Ce que vous décrivez est cependant le format de sortie par défaut.
slhck
0

Si vous souhaitez utiliser FFMPEG comme indiqué initialement, vous pouvez lister tout ou partie de la liste ainsi que créer des jpg avec les éléments suivants:

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"

Retirez -t 15sans limite de temps ou changez en fonction. Supprimer -s 160x90 -f image2 thumbnail-%02d.jpegou modifier en fonction de la suppression des miniatures.

Budman1
la source
Dans Windows 7 CMD, cela échoue au \. Changer \ en ^ provoque un échec au: I ". Avez-vous une version qui fonctionne sous Windows?
ChrisJJ