How to properly unload/destroy a VIDEO element
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.
Related videos on Youtube
sparkey0
Updated on March 20, 2021Comments
-
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 almost 6 yearsI 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 almost 14 yearsOkay, so you put me on the right track -- this = null; did not work, but delete(this); did!
-
Ken Redler almost 14 yearsGlad to hear it. I'll update the answer to include your findings.
-
sparkey0 almost 14 yearsThanks again! Btw, this=null threw an error -- should be avoided.
-
Casey Chu almost 14 yearsThe
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 almost 14 yearsOddly 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 over 8 yearsThanks. The above solutions did not work for me. But, yours did.
-
nils over 8 yearsThe
videoElement.load()
seems to be the key so that it works in Firefox. -
CodeToad over 8 yearsThis solution solved a problem of video not playing after being removed and re-added to the DOM in chrome v.47.
-
Adam Lesniak over 8 yearsThat seems to be the best answer - fixed problem for me, properly and in PRACTICE disposes the video.
-
danielgormly over 8 yearsI also had to videoElement.innerHTML="" too otherwise it would keep loading the source. also above link is now dead.
-
NiCk Newman about 8 yearsLatest 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 about 8 yearsThis 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 almost 8 yearsYou saved my life. If I ever meet you, I will offer you 5 beers
-
Paul Annekov over 7 yearsstackoverflow.com/a/40419032/782599 this answer doesn't fire
error
event on element. -
alitheg over 7 yearsThis 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 about 7 yearsIE and Edge sends a request to the server if
src
is set to""
, similar toimg
elements. The attribute should instead be removed, as recommended by the standard. -
Alocus almost 6 yearsFor 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 over 5 yearsWhat browsers does this example succeed in? IE, Edge?
-
jCaMaX almost 5 yearsIf you´re using video tag and source tag independently, this is the way to do it.
-
Samson Maben over 3 yearsanyone how can i avoid MEDIA_ERROR_DECODE? I am doing the above recommended way of tearing the video element.
-
Crashtor about 3 yearsSir, you are a life saver.
-
Sage Pointer almost 3 yearsIn 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.