FFmpeg peut capturer des images à partir de vidéos qui peuvent être utilisées en tant que vignettes pour représenter la vidéo. La plupart des manières de le faire sont décrites dans le wiki de FFmpeg .
Mais, je ne veux pas choisir des images aléatoires à certains intervalles. J'ai trouvé quelques options en utilisant des filtres sur FFmpeg pour capturer les changements de scène:
Le filtre thumbnail
tente de trouver les images les plus représentatives de la vidéo:
ffmpeg -i input.mp4 -vf "thumbnail,scale=640:360" -frames:v 1 thumb.png
et la commande suivante sélectionne uniquement les images contenant plus de 40% des modifications par rapport aux précédentes (et donc probablement des modifications de scènes) et génère une séquence de 5 fichiers PNG.
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png
Crédit d'information pour les commandes ci-dessus à Fabio Sonnati . La seconde me semblait meilleure car je pouvais obtenir n images et choisir le meilleur. Je l'ai essayé et il a généré la même image 5 fois.
Une enquête plus poussée m'a amené à:
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.png
-vsync vfr
assure que vous obtenez des images différentes. Cela choisit toujours toujours la première image de la vidéo. Dans la plupart des cas, la première image est un générique / logo et n'a pas de sens. J'ai donc ajouté un -ss
3 pour supprimer les 3 premières secondes de la vidéo.
Ma dernière commande ressemble à ceci:
ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg
C'était le mieux que je puisse faire. J'ai remarqué que, puisque je ne sélectionne que 5 vidéos, toutes datent pour la plupart du début de la vidéo et risquent de manquer des scènes importantes qui se produisent plus tard dans la vidéo.
Je voudrais choisir votre cerveau pour toute autre meilleure option.
libopenjpeg
.. ne sais pas si cela fait une différence.mjpeg
encodeur pour moi, et j'ai également vérifiéjpegoptim
etexiv2
, les deux fonctionnant bien pour moi avec tous les résultats JPG de vos exemples de commandes.Réponses:
Que diriez-vous de rechercher, idéalement, la première trame> 40% de changement dans chacun des 5 intervalles de temps, où les intervalles de temps sont les 1ère, 2ème, 3ème, 4ème et 20ème parties de la vidéo.
Vous pouvez également le diviser en 6 périodes et ignorer le premier pour éviter les crédits.
En pratique, cela signifie que vous devez définir un nombre faible de fps lorsque vous appliquez votre contrôle de changement de scène et votre argument pour rejeter le premier bit de la vidéo.
...quelque chose comme:
la source
Unable to find a suitable output format for 'fps=fps=1/600'
. La solution consiste à ajouter-vf
avant cet argument (voir stackoverflow.com/questions/28519403/ffmpeg-command-issue )Il est difficile de définir le sens, mais si vous souhaitez que N vignettes couvrent efficacement l’ensemble du fichier vidéo, c’est ce que j’utilise pour générer des vignettes lors de la production avec le contenu téléchargé par l’utilisateur.
Pseudo-code
Où:
ffmpeg -i <movie>
seule ouffprobe
avec un très bon graveur de sortie JSONSimplement ce qui précède écrit l'image-clé centrale de chaque partition du film. Par exemple, si le film a une longueur de 300 secondes et que vous souhaitez 3 vignettes, il faut une image clé après 50, 150 et 250 secondes. Pour 5 vignettes, il s'agirait de 30, 90, 150, 210, 270. Vous pouvez ajuster N en fonction de la durée du film D, par exemple, un film de 5 minutes aura 3 vignettes mais plus d'une heure aura 20 vignettes.
Performance
Chaque appel de la
ffmpeg
commande ci-dessus prend une fraction de seconde (!) Pour environ 1 Go H.264. C’est parce qu’il saute instantanément à la<time>
position (à l’esprit-ss
auparavant-i
) et prend la première image clé qui est pratiquement complète en JPEG. Il n'y a pas de temps perdu pour rendre le film pour correspondre à la position exacte du temps.Post-traitement
Vous pouvez mélanger ci-dessus avec
scale
ou toute autre méthode de redimensionnement. Vous pouvez également supprimer les cadres de couleur unie ou essayer de le mélanger à d’autres filtresthumbnail
.la source
-ss N
à avant-i
est une astuce incroyable. Merci!Une fois, j’ai fait quelque chose de similaire, mais j’ai exporté toutes les images de la vidéo (en 1 ips) et les ai comparées à un utilitaire Perl que j’ai trouvé, qui calcule la différence entre les images. J'ai comparé chaque image aux vignettes précédentes, et si elle était différente de toutes les vignettes, je l'ai ajoutée à la collection de vignettes. L’avantage ici est que si votre vidéo passe de la scène A à B et qu’elle revient à A, ffmpeg exporte 2 images de A.
la source
Essaye ça
En utilisant cette commande, je peux générer le nombre requis de vignettes qui sont représentatives de la vidéo entière.
la source
fps
être(no_of_frames_req * fps_of_vid) / total_video_frames
?Voici ce que je fais pour générer une vignette périodique des flux m3u8 en direct à utiliser comme affiche. J'ai découvert qu'exécuter une tâche ffmpeg continue juste pour générer des vignettes consommait tout mon processeur. Je me suis donc tourné vers un cronjob toutes les 60 secondes pour générer toutes les vignettes de mes flux.
Si vous devez effectuer plus de 60 secondes (limitation de cronjob), vous pouvez créer une
while
boucle dans votre script qui s'exécutera à jamais. Ajoutez simplement unsleep 30
pour modifier la fréquence à 30 secondes. Je ne recommande toutefois pas de faire cela avec un grand nombre de vidéos, car la précédente exécution risque de ne pas s'achever avant le début de la suivante.Idéalement avec cronjob je le lance juste toutes les 5 minutes.
la source