web-dev-qa-db-fra.com

Vidéo HTML5: force l'abandon de la mise en mémoire tampon

Comment forcer un événement d'abandon sur une vidéo HTML5? J'ai une superposition où, lorsque je la ferme, la vidéo doit être interrompue, puis arrêter la mise en mémoire tampon . Cependant, ma connexion Internet continue de devenir folle. Oh, j'utilise Chrome 7.0.5 sur Mac OS X 10.6.

J'ai essayé plusieurs choses - aucune d'entre elles n'a fonctionné:

(Pour ceux qui ne connaissent pas XUI, x $ est semblable à la fonction de wrapping jQuery)

Tout d'abord, l'envoi d'un événement HTML annulé:

var videoEl = x$('#video_el')[0];
videoEl.pause();
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('abort', false, false);
videoEl.dispatchEvent(evObj);

Ensuite, changez le src puis forcez une charge:

var videoEl = x$('#video_el')[0];
videoEl.pause();
videoEl.src = "";
videoEl.load(); //tried with and without this step

EDIT: Mon élément vidéo ressemble à ceci:

<video id="video_el" src="<video_url>" preload="none" controls="controls" />

Encore une fois, aucun de ces travaux. Quelqu'un a déjà rencontré ce problème auparavant? Aucune suggestion? 

En résumé, j'essaie de forcer un élément vidéo HTML5 à arrêter la mise en mémoire tampon.

Merci!

45
Brad Swerdfeger

Ok, donc depuis quelques jours, j'ai vraiment du mal avec ce problème.
Voici mon analyse et solution:

En bref, le problème que j'ai essayé de résoudre:
J'ai remarqué que le lecteur HTML5 n'arrête pas le téléchargement lorsque le lecteur est en pause (même après un laps de temps raisonnable). En travaillant avec un flux audio 24 h/24 et 7 j/7 et en développant un site Web mobile, j’ai réalisé que c’était loin d’être optimal pour mes visiteurs, compte tenu de la forte utilisation de leurs données s’ils laissaient le site ouvert - bien que je pense que je ferais très plaisir à certains opérateurs de télécommunication " ce problème...
Juste pour clarifier, je ne me soucie pas vraiment des fichiers de longueur fixe. Le téléchargement du fichier complet est la plupart du temps une fonctionnalité requise pour afficher les ressources en ligne (pensez à une connexion lente), ce que je n’ai donc pas essayé d’empêcher.

Une analyse:
L'élément audio HTML5 n'a pas de fonction stop () ni d'option permettant de définir la quantité de données qu'il est autorisé à mettre en mémoire tampon, ou une façon de dire que vous souhaitez que l'élément cesse de le mettre en mémoire tampon - Ne confondez pas ceci avec la fonction de "préchargement", cela ne s'applique qu'à l'élément avant que le bouton de lecture ne soit cliqué.
Je ne sais pas pourquoi et pourquoi cette fonctionnalité n'est pas disponible. Si quelqu'un peut m'expliquer pourquoi ces fonctions cruciales ne sont pas implémentées dans une norme qui devrait rendre le développement Web pour les téléphones mobiles plus efficace et plus normalisé, j'aimerais le savoir.

Solution:
La seule solution de travail que j'ai trouvée pour implémenter une fonction (en quelque sorte) d'arrêt dans votre élément audio est la suivante:
1. Mettre en pause le lecteur actuel - vous pouvez accrocher l'événement de pause sur le lecteur via audio.addEventListener ('pause', votreFonction);
2. Définissez la source sur vide - audio.src = "";
3. Chargez le fichier src - audio.load ();
4. Supprimer tout l'élément audio
5. Insérer un nouvel élément audio HTML5 sans définir la source
6. Définir la source (la source qui était là à la première place) - audio.src = "ancienne URL de la source
7. Recréez l'événement pause - audio.addEventListener ('pause', current-function);

L'injection complète d'un nouveau lecteur audio HTML5 est nécessaire pour iOS. Réinitialiser simplement le fichier src puis le charger entraîne le lecteur à "lire automatiquement" dans mon cas ...

Pour les paresseux (comprend jQuery):

var audio = $("audio").get(0);
audio.pause(0);
var tmp = audio.src;
audio.src = "";
audio.load();
$("audio").remove();

$("#audio-player").html("<audio controls preload='none'></audio>");<br>
audio = $("audio").get(0);
audio.src = tmp;
audio.addEventListener('pause', current-function);

En appuyant sur pause, votre visiteur perdra son emplacement actuel dans le fichier audio/vidéo et celui-ci recommencera. Je n'ai pas de solution à ce problème. Encore une fois, si vous avez affaire à un flux en direct, cette solution devrait convenir.

J'espère que cela t'aides.

47
Ruben

Avec preload = "none", c’est ainsi que j’ai forcé l’abandon de la mise en mémoire tampon après la suspension de la vidéo, puis la lecture à l’emplacement mis en pause à l’aide de jQuery. 

<video id="video_el" src="<video_url>" preload="none" controls="controls" />    

<script>
jQuery(function() {

  var video = jQuery('video').get(0);

  video.addEventListener('pause',function(){
     var tmp_src = video.src;
     var playtime = video.currentTime;
     video.src = '';
     video.load();
     video.src = tmp_src;
     video.currentTime = playtime;
  });

});
</script>
8
Eric Leroy

L'étape clé semble consister à non définir src sur une valeur vide avant d'appeler load(). J'ai eu du succès en le faisant comme ceci:

var wasPlaying = !audioPlayer.paused;
audioPlayer.currentTime = 0.0; // Optional -- can be left out for pause
audioPlayer.pause();

if (wasPlaying) { // This prevents the browser from trying to load the entire source
    audioPlayer.load();
}

Dans Chrome et Firefox sur Win10, cela déclenche un événement d'abandon. Dans mon cas particulier, cela était nécessaire pour fermer les sockets qui resteraient autrement ouverts indéfiniment, ce qui a conduit à frapper la limite de six connexions par serveur avec plusieurs lecteurs utilisés sur la même page.

1
Dinfinity

Voir ici: http://dev.w3.org/html5/spec/video.html#attr-media-preload

Peut-être que vous pourriez définir preload à none?

Si cela ne fonctionne pas: pouvez-vous récupérer ses attributs, le supprimer, insérer un nouvel élément vidéo et lui attribuer les attributs enregistrés?

0
thejh

En réalité, vous pouvez faire la même chose en définissant l'attribut src en tant que fichier php/aspx avec certains paramètres pour lire le contenu du fichier et récupérer les données sous un type équivalent (par exemple, Content-Type: video/mp4). MAIS cela ne fonctionne pas dans IE 11 (quelle surprise: D), alors vous devrez faire le tour ci-dessus juste pour ce magnifique navigateur.

Utilisez ceci...

<video id="v1" preload="none">
  <source src="video.php?id=24" type="video/mp4">
</video>

Au lieu de cela...

<video id="v2" preload="none">
  <source src="video-24.mp4" type="video/mp4">
</video>

L’inconvénient est que vous ne pourrez pas déterminer toute la longueur de la vidéo, mais pour résoudre ce problème, il n’est pas trop gros, vous pouvez stocker cette valeur dans votre base de données ou tout simplement faire une autre petite astuce.

J'ai testé avec Chrome 32, Firefox 26, Opera 18 et IE 11 le script suivant

setInterval(function() {
    var r = [];

    try {
        r.Push(v1.buffered.end(0));
    } catch(e) {
        r.Push('nahh');
    };

    try {
        r.Push(v2.buffered.end(0));
    } catch(e) {
        r.Push('second nahh');
    };

    console.log(r.join(', '));
}, 500);

Dans mes tests locauxhosts ...

Firefox 26 Après avoir appuyé sur Play, il a TOUJOURS mis le fichier complet en mémoire tampon.

IE 11 (considérant que src="video-24.mp4", les autres ne fonctionnent pas) Après avoir appuyé sur Play, il a TOUJOURS mis en mémoire tampon la partie du fichier, même si elle était en pause, et ignore complètement l'attribut preload="none".

Chrome 32 fonctionne parfaitement (idem pour Opera 18).

0
Nevershowmyface