web-dev-qa-db-fra.com

Moyen le plus rapide d'extraire une image spécifique d'une vidéo (PHP / ffmpeg / n'importe quoi)

J'ai une page Web qui, entre autres, doit extraire une image spécifique d'une vidéo mise en ligne par l'utilisateur. L'utilisateur cherche une partie particulière d'un .mp4 dans le lecteur, puis clique sur un bouton, et un appel ajax est renvoyé vers un script php qui prend le .mp4, et l'heure exacte de la vidéo, et l'utilise pour extraire un cadre "miniature".

Ma solution actuelle utilise la commande php exec:

exec("ffmpeg -i $videoPath -ss $timeOffset -vframes 1 $jpgOutputPath");

... qui fonctionne très bien, sauf que c'est aussi lent que la mélasse. Je suppose que ffmpeg est un peu trop pour le travail, et je pourrais peut-être faire mieux en utilisant les bibliothèques sous-jacentes ou quelque chose ... mais je n'ai aucune idée de comment le faire.

Idéalement, je ne veux pas avoir à installer quoi que ce soit qui nécessite un véritable "processus d'installation" ... c'est-à-dire que déposer un exécutable dans le dossier avec mon application Web est bien, mais je préfère ne pas avoir à exécuter réellement un programme d'installation. De plus, la solution devrait pouvoir s'exécuter sur mac, linux et windows (bien que linux soit la priorité absolue).

Que puis-je faire pour accélérer ce processus?

Merci.

47
DanM

Bien sûr, vous pouvez coder du C/C++ et le lier à -lav *, créant essentiellement une version simplifiée de ffmpeg juste pour extraire des cadres, et peut-être même le faire comme une extension php (je ne l'exécuterais pas non plus comme le même utilisateur , encore moins dans le même processus). Mais il est très peu probable que le résultat soit plus rapide, car vous éviteriez seulement une fourche et une surcharge de configuration, mais votre problème probable est en fait le décodage, qui serait toujours le même.

Au lieu de cela, vous devez d'abord examiner l'utilisation de ffmpeg en mode de recherche rapide (ou en mode hybride rapide/précis). Leurs états wiki sur la recherche rapide:

Le paramètre -ss doit être spécifié avant -i :

ffmpeg -ss 00:03:00 -i Underworld.Awakening.avi -frames: v 1 out1.jpg

Cet exemple produira un cadre d'image (out1.jpg) vers la troisième minute à partir du début du film. L'entrée sera analysée à l'aide d'images clés, ce qui est très rapide. L'inconvénient est qu'il terminera également la recherche sur une image clé, pas nécessairement située à l'heure spécifiée (00:03:00), de sorte que la recherche ne sera pas aussi précise que prévu.

La recherche rapide est moins précise, mais beaucoup plus rapide, car ffmpeg n'aura pas réellement besoin de décoder (la plupart) le film pendant la recherche, tandis que le mode hybride rapide/précis est un bon compromis. Lisez la page wiki pour toutes les options disponibles.

Modifier le 14/06/10:

Depuis FFmpeg 2.1, lors du transcodage avec ffmpeg (c'est-à-dire pas la copie de flux), -ss est désormais précis même lorsqu'il est utilisé comme option d'entrée. Le comportement précédent peut être restauré avec l'option -noaccurate_seek. (source)

Ainsi, avec 2.1+, la recherche "hybride" ne devrait plus être nécessaire pour des résultats précis en ce qui concerne le recodage (et l'enregistrement dans .jpeg est un ré-encodage). Il suffit de faire la recherche rapide habituelle (-ss ... -i ...) au lieu d'une recherche lente (-i ... -ss ...).

72
nmaier