Je recherche un moyen d'afficher HTML5 <video>
, image par image.
Le scénario: avoir une vidéo, avec un bouton supplémentaire qui passe à l'image suivante lorsque vous appuyez dessus.
Selon vous, quelle est la meilleure méthode pour ce faire?
timeUpdate
, qui sur FireFox est appelé pour chaque image , puis mettez simplement la vidéo en pause. Cependant, les autres navigateurs ne se comportent pas comme Firefox.currentTime
en +1/24 de seconde, où "24" est la fréquence d'images. Je n'ai cependant aucune idée de comment acquérir le FPS.J'ai trouvé cette page de test HTML5 très utile , qui suit la capacité de tous les navigateurs à obtenir une recherche de trame précise.
Il semble que la plupart des navigateurs autorisent la deuxième approche, même si vous devez connaître la fréquence d'images. Opera, cependant, est l'exception et nécessite une approche similaire à la première (le résultat n'est pas parfait). Voici une page de démonstration que j'ai créée qui utilise une vidéo à 29,97 images/s (norme de télévision américaine). Notez qu'il n'a pas été largement testé, donc il pourrait ne pas fonctionner dans IE 9, Firefox 4, ou les futures versions de n'importe quel navigateur.
HTML:
<p id="time"></p>
<video id="v0" controls tabindex="0" autobuffer preload>
<source type="video/webm; codecs="vp8, vorbis"" src="http://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.webm"></source>
<source type="video/ogg; codecs="theora, vorbis"" src="http://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.ogv"></source>
<source type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"" src="http://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.mp4"></source>
<p>Sorry, your browser does not support the <video> element.</p>
</video>
JavaScript (exécuté au chargement de la page et utilise jQuery 1.4.4 par souci de concision):
var vid = $('#v0')[0];
vid.onplay = vid.onclick = function() {
vid.onplay = vid.onclick = null;
setTimeout(function() {
vid.pause();
setInterval(function() {
if($.browser.opera) {
var oldHandler = vid.onplay;
vid.onplay = function() {
vid.pause();
vid.onplay = oldHandler;
};
vid.play();
} else {
vid.currentTime += (1 / 29.97);
}
}, 2000);
}, 12000);
setInterval(function() {
$('#time').html((vid.currentTime * 29.97).toPrecision(5));
}, 100);
};
Après avoir lutté contre ce même problème, j'ai trouvé une méthode de force brute pour trouver le taux de trame. Sachant que le taux de trame ne passera jamais 60 images par seconde, je cherche à travers la vidéo au 1/60ème de seconde. Comparer chaque image à la dernière en plaçant la vidéo sur un élément de canevas, puis en utilisant getImageData pour obtenir des données de pixels. Je le fais sur une seconde de vidéo, puis je compte le nombre total d'images uniques pour obtenir la fréquence d'images.
Vous n'avez pas besoin de vérifier chaque pixel. J'attrape environ les 2/3 de l'intérieur de la vidéo, puis vérifie environ chaque 8ème pixel de haut en bas (selon la taille). Vous pouvez arrêter la comparaison avec un seul pixel différent, de sorte que cette méthode est raisonnablement rapide et fiable, bien pas comparée à la lecture d'une propriété frameRate, mais mieux que de deviner.
La meilleure chose que vous puissiez probablement faire jusqu'à ce que les normes soient confirmées et mises en œuvre (ce seront des âges!) Est de deviner la fréquence d'images et l'incrémentation d'ici là. À moins que vous ne soyez dans un environnement contrôlé, je vous déconseille de dépendre fortement de HTML5 ... autant que j'aime ses fonctionnalités, il ne sera pas pris en charge de manière fiable.