web-dev-qa-db-fra.com

Utiliser FFMPEG: Comment faire une détection de changement de scène? avec timecode?

D'après cet article, il semble possible d'utiliser FFMPEG pour détecter les changements de scène dans les vidéos: http://www.luckydinosaur.com/u/ffmpeg-scene-change-detector

Maintenant, j'ai une vidéo qui affiche un texte de livre et lorsque le texte (Word ou phrase) est prononcé, il est mis en surbrillance. Quelque chose comme ce livre audio: https://youtu.be/lA7L6ZNVKjc

J'ai besoin de connaître l'horodatage lorsque le texte est mis en surbrillance (d'où un changement de scène), cela me permettra d'ajouter des balises d'horodatage sur ma vidéo youtube, de sorte qu'il sera plus facile pour les auditeurs de parcourir le livre audio.

Quelle est la ligne de commande magic qui ferait cela?

Merci beaucoup!

14
Mozart

La combinaison du filtre scene (pour détecter les changements de scène) et du filtre showinfo devrait donner ce que vous voulez:

ffmpeg -i input.flv  \
       -filter:v "select='gt(scene,0.4)',showinfo" \
       -f null \
       - 2> ffout

Cette commande extrait toutes les images qui diffèrent de l'image précédente de plus de (gt) 0.4 (sur une échelle allant de 0 à 1). Pour ces cadres, les informations sont imprimées (showinfo) comme ceci

[Parsed_showinfo_1 @ 0x2d85e60] n:   0 pts:2537204 pts_time:2.5372  pos:  2998114 fmt:rgb24 sar:1/1 s:1920x1200 i:P iskey:1 type:I checksum:5616582E plane_checksum:[5616582E]

Il ne vous reste plus qu'à extraire l'horodatage. Je pense que vous êtes intéressé par pts_time. Vous pouvez le faire comme ceci:

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep [0-9.]* -o > timestamps

Cela vous donnera la liste de tous les horodatages:

2.5372
4.37799
6.65301
8.09344

Pour que cette approche fonctionne, vous devez disposer d'une version de FFmpeg qui implémente la détection de scène. En outre, vous devez sélectionner une valeur appropriée pour le seuil (0.4 dans la première commande). Vous pouvez essayer de trouver un seuil optimal en extrayant des images pour différents seuils (puis en les examinant manuellement), comme ceci

ffmpeg -i input.flv \
       -filter:v "select='gt(scene,0.1)',showinfo" \
       -vsync 0 frames/%05d.jpg

Juste pour clarification: grep [0-9.]* n'exclut pas les entiers comme indiqué dans une autre réponse. Il correspond à toute séquence de caractères composée de chiffres et de points, mais il convient également à des non-chiffres tels que "4.4.4". Cependant, ffmpeg ne devrait pas produire d’horodatages mal formés.

17
ckoehn

Je n'ai pas le représentant pour poster un commentaire sur la réponse ci-dessus, mais je tenais à souligner que le grep posté par @ckoehn et @keypulsations ne saisira que les horodatages en virgule flottante. Pour saisir les horodatages à virgule flottante et entière, utilisez la regex suivante

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep -E '[0-9]+(?:\.[0-9]*)?' -o > timestamps
7
Luke Harrison

J'essayais la réponse @ckoehn et cela a fonctionné. Jusqu'à ce que cela cesse de fonctionner, l'astérisque du dernier grep posait problème. Pour éviter cela, je recommande d'utiliser des guillemets doubles dans les phrases de grep comme:

grep showinfo ffout | grep pts_time:[0-9.]* -o | grep "[0-9.]*" -o > timestamps
3
Ignacio Peletier

Vous pouvez simplement utiliser la commande:

ffmpeg inputvideo.mp4 -filter_complex "select='gt(scene,0.3)',metadata=print:file=time.txt" -vsync vfr img%03d.png

Cela ne sauvegardera que les informations pertinentes dans le fichier time.txt, comme ci-dessous.

frame:0    pts:108859  pts_time:1.20954
lavfi.scene_score=0.436456
frame:1    pts:285285  pts_time:3.16983
lavfi.scene_score=0.444537
frame:2    pts:487987  pts_time:5.42208
lavfi.scene_score=0.494256
frame:3    pts:904654  pts_time:10.0517
lavfi.scene_score=0.462327
frame:4    pts:2533781 pts_time:28.1531
lavfi.scene_score=0.460413
frame:5    pts:2668916 pts_time:29.6546
lavfi.scene_score=0.432326

Le cadre est le numéro de série du changement de plan détecté depuis le début. De plus, choisissez votre valeur de seuil (ici 0,3) de manière appropriée pour que votre cas d'utilisation obtienne les résultats corrects

1
Abhijeet