web-dev-qa-db-fra.com

Comment décharger/détruire correctement un élément VIDEO

Je travaille sur une application de navigation/lecture multimédia en temps réel qui utilise des objets <video> dans le navigateur pour la lecture, le cas échéant.

J'utilise un mélange de javascript direct et jQuery, 

Ma préoccupation concerne spécifiquement la mémoire. L'application ne se recharge jamais dans la fenêtre et l'utilisateur peut visionner de nombreuses vidéos. La gestion de la mémoire devient donc une préoccupation majeure avec le temps. Lors des tests d’aujourd’hui, je constate que le profil de la mémoire saute en fonction de la taille de la vidéo à diffuser avec chaque chargement ultérieur, sans jamais revenir à la ligne de base.

J'ai essayé les choses suivantes avec le même résultat:

1 - Videz le conteneur parent contenant l'élément créé, par exemple:

$(container_selector).empty();

2 - Mettez en pause et supprimez les enfants correspondant à 'vidéo', puis videz le conteneur parent:

$(container_selector).children().filter("video").each(function(){
    this.pause();
    $(this).remove();
});
$(container_selector).empty();

Quelqu'un a-t-il rencontré ce problème et existe-t-il une meilleure façon de le faire?

34
sparkey0

Il est très difficile de disposer de la vidéo à partir de la structure DOM. Cela peut entraîner un plantage du navigateur. Voici la solution qui m'a aidé dans mon projet. 

var videoElement = document.getElementById('id_of_the_video_element_here');
videoElement.pause();
videoElement.removeAttribute('src'); // empty source
videoElement.load();

cela réinitialisera tout, silencieux sans erreur!

Voici les détails complets et une meilleure explication http://www.attuts.com/aw-snap-solution-video-tag-dispose-method/

J'espère que cela résoudra votre question. 

54
toon lite

Cette "solution" est censée fonctionner, probablement parce qu'elle rendrait ces objets de conteneur vidéo disponibles pour la récupération de place (voir la note ci-dessous pour une discussion sur les raisons pour lesquelles delete ne devrait pas faire une différence). Dans tous les cas, vos résultats sont susceptibles de varier selon le navigateur:

$(container_selector).children().filter("video").each(function(){
    this.pause(); // can't hurt
    delete this; // @sparkey reports that this did the trick (even though it makes no sense!)
    $(this).remove(); // this is probably what actually does the trick
});
$(container_selector).empty();

Remarque: Il ne fait aucun doute que le mot clé delete est spécifié uniquement pour supprimer les propriétés d'objets (comme d'autres l'ont souligné dans les commentaires). La journalisation this sur la console avant et après la ligne delete this ci-dessus affiche le même résultat à chaque fois. delete this ne devrait rien faire et ne changerait rien. Pourtant, cette réponse continue de recevoir un filet de votes, et des personnes ont signalé que le fait d’omettre delete this l’a empêché de fonctionner. Peut-être y at-il une étrangeté dans la façon dont certains moteurs JS de navigateur implémentent delete, ou une interaction inhabituelle entre delete du navigateur et ce que jQuery fait avec this.

Sachez donc que si cette solution résout votre problème, si cela fonctionne, vous ne saurez pas pourquoi, et il est tout aussi probable que vous cessiez de travailler pour un certain nombre de raisons.

16
Ken Redler

Pour réinitialiser la vidéo à Blank sans la supprimer 

$("#video-intro").first().attr('src','')

Il arrête la vidéo

4
Bishoy Hanna
delete(this); 

est pas une solution. Si cela a fonctionné pour x ou y, c'est une mauvaise conduite du navigateur. Lire ici

L'opérateur delete supprime une propriété d'un objet.

La vérité est que certains navigateurs (Firefox par exemple) vont mettre en mémoire cache le tampon vidéo lorsque la propriété de lecture automatique est activée. C'est pénible à gérer.

Le fait de supprimer la balise vidéo du DOM ou de la suspendre ne peut produire que des résultats instables. Vous devez décharger le tampon. 

var video = document.getElementById('video-id');
video.src = "";

Mon expérience montre que c'est fait ainsi, mais malheureusement, cette implémentation de navigateur n'est pas complètement spécifiée par le spec . Vous n'avez pas besoin d'appeler load () après le changement de src. Lorsque vous modifiez le code source d'une balise video, vous appelez implicitement un load () dessus, cela est indiqué dans les spécifications W3C.

3
Arnaud Leyder

Juste pour clarifier pour ceux qui essaient plus tard, la solution est la suivante: (confirmé avec les vidéos h264 dans Safari 5.0, pas encore testé dans FF/Opera)

$(container_selector).children().filter("video").each(function(){
    this.pause();
    delete(this);
    $(this).remove();
});
$(container_selector).empty();
2
sparkey0

ok, voici une solution simple qui fonctionne certainement:

var bodypage = document.getElementsByTagName('body')[0];
var control_to_remove = document.getElementById('id_of_the_element_here');
bodypage.removeChild(control_to_remove);
1
Ganzert

Cet extrait ne fait aucune manipulation DOM efficace (pas de suppression de balise) et ne déclenche pas l'événement error pour <video> contrairement à cette réponse :

var video = document.getElementById('video');
video.removeAttribute('src');
video.load();

De plus, il ne déclenche pas l'événement loadstart. Et c'est comme si cela devrait fonctionner - pas de vidéo, pas de démarrage de la charge.

Vérifié dans Chrome 54/FF 49.

1
Paul Annekov
var video = document.getElementById('video');
        if (video.firstChild) {
            video.removeChild(video.firstChild);
            video.load();
        }
0
Quan Quan

J'ai rencontré ce problème à un niveau plus complexe où nous chargeons environ 80 vidéos sur une page et rencontrons des problèmes de gestion de la mémoire dans IE et Edge. J'ai posté notre solution sur une question similaire que j'avais posée en particulier sur notre problème: https://stackoverflow.com/a/52119742/1253298

0
BBaysinger

Voici une réponse sur la façon de fermer la caméra - pas seulement en pause. C'est le flux qui doit être arrêté - et non la référence aux éléments vidéo: stream.stop ()

0

Pas beaucoup compliqué. Il suffit de mettre votre SRC à null.

Eg: document.querySelector('#yourVideo').src = null;

Cela supprimera votre attribut vidéo src. Terminé.

0
Dikshant Patodia