Je conçois un lecteur vidéo personnalisé HTML5
. Ainsi, il aura son propre curseur personnalisé pour imiter la progression de la vidéo. Je dois donc comprendre l'intégralité du Shebang en mémoire tampon d'une vidéo HTML5
.
Je suis tombé sur cet article: Buffering vidéo . Il indique que l'objet mis en mémoire tampon est constitué de plusieurs plages de temps dans un ordre linéaire de l'heure de début. Mais je n'ai pas pu trouver ce qui suit:
Dites que la vidéo commence. Il continue jusqu'à 1h45 tout seul (de temps en temps peut-être, dans l'attente de nouvelles données), après quoi je saute soudainement à 32h45. Maintenant, après un certain temps, si je retourne à 1:27 (dans la plage de temps initialement chargée et jouée, avant de faire le saut), la lecture commencera-t-elle immédiatement comme elle était déjà chargée auparavant? Ou est-ce que depuis que j'ai fait un saut, cette partie est perdue et devra être récupérée à nouveau? Dans les deux cas, le comportement est-il cohérent pour tous ces scénarios?
Supposons que je fasse 5 ou 6 sauts de ce type, en attendant chaque fois quelques secondes que certaines données soient chargées après le saut. Est-ce que cela signifie que l'objet buffered
aura toutes ces plages de temps stockées? Ou peut-être que certains se perdent? Est-ce une sorte de pile, où les gammes précédentes seront effacées au fur et à mesure que plus de gammes seront chargées en raison de sauts supplémentaires?
En vérifiant si l'objet buffered
a une plage de temps commençant à 0 (oubliez la diffusion en direct) et se terminant à la durée de la vidéo, assurez-vous que l'intégralité de la ressource vidéo a été chargée? Sinon, y a-t-il un moyen de savoir que la vidéo entière a été téléchargée et que toute partie est recherchée, à partir de laquelle la vidéo peut être lue en continu jusqu'à la fin sans délai?
Les spécifications du W3C ne sont pas très claires à ce sujet, et je ne trouve pas non plus de ressource vidéo distante suffisamment grande (disons plus d’une heure) à tester.
La mise en mémoire tampon de la vidéo dépend de la mise en œuvre du navigateur et peut donc varier d'un navigateur à l'autre.
Différents navigateurs peuvent utiliser différents facteurs pour déterminer de conserver ou de supprimer une partie du tampon. Les segments anciens, l’espace disque, la mémoire et les performances sont des facteurs typiques.
La seule façon de vraiment savoir est de "voir" ce que le navigateur a ou est en train de charger.
Pour cela, j'ai créé un visualiseur de mémoire tampon qui montre quelle partie se trouve dans la mémoire tampon. Le visualiseur montrera le courant et toutes les parties de la mémoire tampon:
Par exemple, dans Chrome, j'ai joué quelques secondes, puis j'ai sauté à environ 30 secondes et vous pouvez voir qu'il commence à charger une autre partie à partir de cette position.
(Le tampon semble aussi être lié aux images clés, il est donc possible de décoder les n images dans ce tampon. Cela signifie que le tampon peut commencer à charger des données un peu avant la position réelle).
J'ai fourni une vidéo de démonstration d'environ 1 minute - mais ce n'est pas assez long pour faire les tests appropriés. Free libre de fournir des liens vidéo contenant une vidéo plus longue (ou s'il vous plaît partager si vous voulez que je mette à jour la démo avec cela).
La fonction principale effectuera une itération dans l’objet buffered
de l’élément video. Toutes les parties existantes seront affichées dans le canevas juste en dessous de la vidéo en rouge.
Vous pouvez cliquer (ne pas faire glisser) sur cette visionneuse pour déplacer la vidéo vers différentes positions.
/// buffer viewer loop (updates about every 2nd frame)
function loop() {
var b = vid.buffered, /// get buffer object
i = b.length, /// counter for loop
w = canvas.width, /// cache canvas width and height
h = canvas.height,
vl = vid.duration, /// total video duration in seconds
x1, x2; /// buffer segment mark positions
/// clear canvas with black
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
/// red color for loaded buffer(s)
ctx.fillStyle = '#d00';
/// iterate through buffers
while (i--) {
x1 = b.start(i) / vl * w;
x2 = b.end(i) / vl * w;
ctx.fillRect(x1, 0, x2 - x1, h);
}
/// draw info
ctx.fillStyle = '#fff';
ctx.textBaseline = 'top';
ctx.textAlign = 'left';
ctx.fillText(vid.currentTime.toFixed(1), 4, 4);
ctx.textAlign = 'right';
ctx.fillText(vl.toFixed(1), w - 4, 4);
/// draw cursor for position
x1 = vid.currentTime / vl * w;
ctx.beginPath();
ctx.arc(x1, h * 0.5, 7, 0, 2 * Math.PI);
ctx.fill();
setTimeout(loop, 29);
}
Selon
l'attribut buffered
contient des informations sur toutes les plages de temps actuellement mises en mémoire tampon. À ma connaissance, si une partie mise en mémoire tampon est perdue, elle est supprimée de l'objet (si cela se produit).
En particulier, le dernier lien semble être très utile pour comprendre le sujet (puisqu'il offre un exemple de code), mais gardez à l'esprit qu'il s'agit de documents Mozilla et que la prise en charge peut être différente dans d'autres navigateurs.
Pour répondre à vos questions
Dites que la vidéo commence. Il continue jusqu'à 1h45 tout seul (de temps en temps peut-être, dans l'attente de nouvelles données), après quoi je saute soudainement à 32h45. Maintenant, après un certain temps, si je retourne à 1:27 (dans la plage de temps initialement chargée et jouée, avant de faire le saut), la lecture commencera-t-elle immédiatement comme elle était déjà chargée auparavant?
Il devrait jouer immédiatement lors du retour en arrière, sauf si le tampon de cette partie a été déchargé. Je pense qu'il est très raisonnable de supposer que les tampons ou les plages de tampons sont déchargés à un moment donné si la taille globale de la mémoire tampon dépasse un certain volume.
Supposons que je fasse 5 ou 6 sauts de ce type, en attendant chaque fois quelques secondes que certaines données soient chargées après le saut. Est-ce que cela signifie que l'objet mis en mémoire tampon aura toutes ces plages de temps stockées?
Oui, toutes les plages mises en mémoire tampon doivent être lisibles via l'attribut.
Est-ce que vérifier si l'objet mis en mémoire tampon a une plage de temps commençant à 0 (oubliez la diffusion en direct) et se terminant à la durée de la vidéo garantit que la totalité de la ressource vidéo a été chargée?
Oui, ceci est l'exemple de code dans le dernier lien. Apparemment, cette méthode est applicable pour déterminer si la vidéo entière a été chargée.
if (buf.start(0) == 0 && buf.end(0) == v.duration)
Presque tous les navigateurs enregistrent les données mises en mémoire tampon dans le cache pour cette session. Le cache expire après que l'utilisateur se soit éloigné de cette page. Je ne pense pas que l'utilisateur devra charger la page à chaque fois qu'il charge la vidéo à partir d'un point où la vidéo a été chargée. L'utilisateur sera confronté à ce problème uniquement lorsque le serveur efface toutes les données du cache. La balise vidéo HTML5 prendra en charge cette fonctionnalité et enregistrera la vidéo jusqu’au point où elle a été chargée.
Cela ne signifie pas que la session a été perdue, cela signifie que l'objet (si vous utilisez flash player) recherche des données à partir de ce point particulier ou que la balise vidéo html5 présente des problèmes en raison de l'échec de la connexion INTERNET, ou d'autres erreurs de serveur.
Les métadonnées sont automatiquement chargées. Jusqu'à ce que vous utilisiez ceci <audio preload="none"...
, le navigateur ne téléchargera rien du serveur, vous pouvez l'utiliser comme:<audio preload="auto|metadata|none"...
Si vous n'en utilisez aucun, rien n'est téléchargé à moins que l'utilisateur clique sur le bouton de lecture, et les métadonnées téléchargeront le nom, le minutage et d'autres métadonnées du serveur, mais pas le fichier d'une manière ou d'une autre.
Je vous renverrai toujours pour lire certaines documentations de jQuery. Comme jQuery vous permettra de modifier et de mettre à jour le contenu en utilisant l'API ajax, il vous sera utile également. J'espère que vous réussissez! À votre santé.
Bien que la description de la réponse acceptée soit excellente, j'ai décidé de mettre à jour son exemple de code, pour plusieurs raisons:
progress
.document.getElementById()
.for()
était plus élégante qu'une boucle arrière while()
.Notez que j'ai supprimé la tête de lecture et l'horodatage pour garder le code propre, car cette réponse se concentre uniquement sur la visualisation du tampon vidéo.
LIEN VERS VISUALISATEUR DE TAMPONS VIDÉO EN LIGNE
Réécriture de la fonction loop()
de la réponse acceptée:
function drawProgress(canvas, buffered, duration){
// I've turned off anti-aliasing since we're just drawing rectangles.
var context = canvas.getContext('2d', { antialias: false });
context.fillStyle = 'blue';
var width = canvas.width;
var height = canvas.height;
if(!width || !height) throw "Canvas's width or height weren't set!";
context.clearRect(0, 0, width, height); // clear canvas
for(var i = 0; i < buffered.length; i++){
var leadingEdge = buffered.start(i) / duration * width;
var trailingEdge = buffered.end(i) / duration * width;
context.fillRect(leadingEdge, 0, trailingEdge - leadingEdge, height);
}
}