如何正确卸载/销毁VIDEO元素

问题描述 投票:37回答:12

我正在开发一个实时媒体浏览/回放应用程序,它在浏览器中使用<video>对象进行播放(如果可用)。

我正在使用直接javascript和jQuery的混合,

我关心的是记忆。应用程序永远不会在窗口中重新加载,并且用户可以观看许多视频,因此随着时间的推移,内存管理成为一个大问题。在今天的测试中,我看到内存配置文件按照每个后续加载流式传输的视频大小跳跃,并且永远不会回落到基线。

我尝试了以下相同的结果:

1 - 清空包含已创建元素的父容器,例如:

$(container_selector).empty();

2 - 暂停并删除匹配“视频”的子项,然后清空父容器:

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

有没有其他人遇到这个问题,有没有更好的方法来做到这一点?

javascript jquery dom memory-management html5
12个回答
60
投票

从DOM结构中处理视频非常棘手。它可能会导致浏览器崩溃。这是帮助我完成项目的解决方案。

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

这会重置一切,保持沉默,没有错误!

这里是完整的细节和更好的解释http://www.attuts.com/aw-snap-solution-video-tag-dispose-method/

希望它能解决您的疑问。


0
投票
var video = document.getElementById('video');
        if (video.firstChild) {
            video.removeChild(video.firstChild);
            video.load();
        }

0
投票

没那么复杂。把你的src放到null。

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

它将删除您的视频src属性。完成。


0
投票

我在一个更复杂的层面遇到了这个问题,我们在页面上加载了大约80个视频,并且在IE和Edge中存在内存管理问题。我在一个类似的问题上发布了我们的解决方案,我特别询问了我们的问题:https://stackoverflow.com/a/52119742/1253298


16
投票

据报道,这种“解决方案”可以正常工作,大概是因为它可以使这些视频容器对象可用于垃圾收集(请参阅下面的说明,讨论为什么delete不应该有所作为)。在任何情况下,您的结果可能会因浏览器而异:

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

注意:毫无疑问,delete关键字仅用于从对象中删除属性(正如其他人在评论中指出的那样)。在上面的this行之前和之后将delete this记录到控制台,每次都显示相同的结果。 delete this应该什么都不做,没有任何区别。然而,这个答案仍然得到了涓涓细流的投票,人们报告说省略delete this使它停止工作。也许有些浏览器JS引擎如何实现delete,或浏览器的delete与jQuery与this所做的事情之间的异常交互。

所以,请注意,如果这个答案解决了你的问题,那么如果它确实有效,那么就不清楚为什么会出现这种情况,而且出于各种原因它也可能停止工作。


4
投票

将视频重置为空白而不删除它

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

它会停止播放视频


3
投票
delete(this); 

不是解决方案。如果它适用于x或y,则是浏览器不当行为。阅读here

delete运算符从对象中删除属性。

事实是,当autoplay属性打开时,某些浏览器(例如Firefox)会在内存中缓存视频缓冲区。处理是一种痛苦。

从DOM中删除视频标记或暂停它只会产生不稳定的结果。你必须卸载缓冲区。

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

我的实验表明它是这样完成的,但不幸的是这是spec没有完全指定的浏览器实现。在src更改后,您不需要调用load()。更改视频标记的src时,隐式调用其上的load(),这在W3C规范中有说明。


2
投票

只是为了澄清后来尝试这个的人,解决方法是:(在Safari 5.0中使用h264视频确认,在FF / opera中未经测试)

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

1
投票

好的,这是一个简单的解决方案,肯定有效:

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

1
投票

这个片段没有做任何有效的DOM操作(没有标记删除),并且不会像error那样为<video>触发this answer事件:

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

此外,它不会引发loadstart事件。它就像它应该工作 - 没有视频,没有负载启动。

检查Chrome 54 / FF 49。



0
投票

这是关于如何关闭相机的答案 - 不仅仅是暂停。它应该停止流 - 而不是视频元素参考:stream.stop()

© www.soinside.com 2019 - 2024. All rights reserved.