How to properly unload/destroy a VIDEO element

94,862

Solution 1

It is very tricky to dispose video from the DOM structure. It may lead to browser crashing. Here is the solution that helped me in my project.

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

this will reset everything, silent without errors !

Edit: Here are the full details as recommended in the Standard: https://html.spec.whatwg.org/multipage/media.html#best-practices-for-authors-using-media-elements

Hope it resolve your query.

Solution 2

This "solution" is reported to work, presumably because it would make those video container objects available for garbage collection (see the note below for a discussion of why delete shouldn't be making a difference). In any case, your results are likely to vary by browser:

$(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();

Note: There's no doubt that the delete keyword is specified only to remove properties from objects (as others have pointed out in the comments). Logging this to the console both before and after the delete this line, above, shows the same result each time. delete this should do nothing and make no difference. Yet this answer continues to receive a trickle of votes, and people have reported that omitting delete this makes it stop working. Perhaps there's strangeness in how some browser JS engines implement delete, or an unusual interaction between a browser's delete and what jQuery is doing with this.

So, just be aware, if this answer solves your problem, that if it does work, it's not clear why that's the case, and it's just as likely to stop working for any number of reasons.

Solution 3

To reset the video to Blank without removing it

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

It stops the video

Solution 4

delete(this); 

is not a solution. If it worked for x or y it is a browser misbehaviour. Read here:

The delete operator removes a property from an object.

The truth is that some browsers (Firefox for example) will cache in memory the video buffer when autoplay property is on. It is a pain to deal with.

Removing the video tag from the DOM or pausing it can only produce unstable results. You have to unload the buffer.

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

My experiment shows that it is done as so but unfortunately this is browser implementation not completely specified by the spec. You do not need to call load() after src change. When changing the src of a video tag you implicitly call a load() on it, this is stated in the W3C spec.

Solution 5

This snippet doesn't do any effecient DOM manipulations (no tag removal) and doesn't fire error event for <video> unlike this answer:

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

Furthermore, it doesn't fire loadstart event. And it's like it should work - no video, no load start.

Checked in Chrome 54 / FF 49.

Share:
94,862

Related videos on Youtube

sparkey0
Author by

sparkey0

Updated on March 20, 2021

Comments

  • sparkey0
    sparkey0 about 3 years

    I'm working on a realtime media browsing/playback application that uses <video> objects in the browser for playback, when available.

    I'm using a mix of straight javascript, and jQuery,

    My concern is specifically with memory. The application never reloads in the window, and the user can watch many videos, so memory management becomes a large concern over time. In testing today, I see the memory profile jumping by the size of the video to be streamed with each subsequent load, and never dropping back down to the baseline.

    I've tried the following things with the same result:

    1 - Empty the parent container containing the created element, eg:

    $(container_selector).empty();
    

    2 - Pause and remove children matching 'video', and then empty the parent container:

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

    Has anyone else run into this issue, and is there a better way to do this?

    • sparkey0
      sparkey0 almost 6 years
      I am updating the answer as things have evolved since this question was asked! I believe the 'delete' fix was almost certainly a browser bug at that time, and these days, i'd recommend pausing the video element, removing the src attribute and triggering reload. After that it can be safely removed from the DOM.
  • sparkey0
    sparkey0 almost 14 years
    Okay, so you put me on the right track -- this = null; did not work, but delete(this); did!
  • Ken Redler
    Ken Redler almost 14 years
    Glad to hear it. I'll update the answer to include your findings.
  • sparkey0
    sparkey0 almost 14 years
    Thanks again! Btw, this=null threw an error -- should be avoided.
  • Casey Chu
    Casey Chu almost 14 years
    The delete statement simply won't do anything because it only deletes properties. It would be exactly the same, I believe, if it were removed.
  • sparkey0
    sparkey0 almost 14 years
    Oddly enough it worked - might just be a combination of quirks in Safari or WebKit. Removing that line causes memory to creep up continuously, with it in, it will increase, then drop suddenly, i'm assuming when the gc runs periodically
  • Jason Williams
    Jason Williams over 8 years
    Thanks. The above solutions did not work for me. But, yours did.
  • nils
    nils over 8 years
    The videoElement.load() seems to be the key so that it works in Firefox.
  • CodeToad
    CodeToad over 8 years
    This solution solved a problem of video not playing after being removed and re-added to the DOM in chrome v.47.
  • Adam Lesniak
    Adam Lesniak over 8 years
    That seems to be the best answer - fixed problem for me, properly and in PRACTICE disposes the video.
  • danielgormly
    danielgormly over 8 years
    I also had to videoElement.innerHTML="" too otherwise it would keep loading the source. also above link is now dead.
  • NiCk Newman
    NiCk Newman about 8 years
    Latest Chrome (48) working here. I used this technique and it cleaned up my memory leak. I think browser's should automatically clear the .src property if an innerHTML was used to replace whatever video element it was in. But, that's for a different topic, thanks/
  • Voy
    Voy about 8 years
    This work as it stops video from playing, yet throws the MEDIA_ERR_SRC_NOT_SUPPORTED error, so watch out if you've got an event listener for errors
  • allemattio
    allemattio almost 8 years
    You saved my life. If I ever meet you, I will offer you 5 beers
  • Paul Annekov
    Paul Annekov over 7 years
    stackoverflow.com/a/40419032/782599 this answer doesn't fire error event on element.
  • alitheg
    alitheg over 7 years
    This answer solved my issue on iOS Safari - I was changing the html of the containing div but eventually videos stopped playing. Adding the above before constructing a new <video> element and adding it fixed the problem!
  • Timothy003
    Timothy003 about 7 years
    IE and Edge sends a request to the server if src is set to "", similar to img elements. The attribute should instead be removed, as recommended by the standard.
  • Alocus
    Alocus almost 6 years
    For Edge, my experience is if src = "", then load operation will fail, and if you were to reuse the node and try to set src and load, load will fail. That mean video.play() will not play.
  • BBaysinger
    BBaysinger over 5 years
    What browsers does this example succeed in? IE, Edge?
  • jCaMaX
    jCaMaX almost 5 years
    If you´re using video tag and source tag independently, this is the way to do it.
  • Samson Maben
    Samson Maben over 3 years
    anyone how can i avoid MEDIA_ERROR_DECODE? I am doing the above recommended way of tearing the video element.
  • Crashtor
    Crashtor about 3 years
    Sir, you are a life saver.
  • Sage Pointer
    Sage Pointer almost 3 years
    In FF/Chrome (and maybe other browsers), this produces an extra network request to URI "null" relative to the current document URL, as the attribute value is converted to string.