我正在开发一个实时媒体浏览/回放应用程序,它在浏览器中使用<video>
对象进行播放(如果可用)。
我正在使用直接javascript和jQuery的混合,
我关心的是记忆。应用程序永远不会在窗口中重新加载,并且用户可以观看许多视频,因此随着时间的推移,内存管理成为一个大问题。在今天的测试中,我看到内存配置文件按照每个后续加载流式传输的视频大小跳跃,并且永远不会回落到基线。
我尝试了以下相同的结果:
1 - 清空包含已创建元素的父容器,例如:
$(container_selector).empty();
2 - 暂停并删除匹配“视频”的子项,然后清空父容器:
$(container_selector).children().filter("video").each(function(){
this.pause();
$(this).remove();
});
$(container_selector).empty();
有没有其他人遇到这个问题,有没有更好的方法来做到这一点?
从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/
希望它能解决您的疑问。
var video = document.getElementById('video');
if (video.firstChild) {
video.removeChild(video.firstChild);
video.load();
}
没那么复杂。把你的src放到null。
Eg: document.querySelector('#yourVideo').src = null;
它将删除您的视频src
属性。完成。
我在一个更复杂的层面遇到了这个问题,我们在页面上加载了大约80个视频,并且在IE和Edge中存在内存管理问题。我在一个类似的问题上发布了我们的解决方案,我特别询问了我们的问题:https://stackoverflow.com/a/52119742/1253298
据报道,这种“解决方案”可以正常工作,大概是因为它可以使这些视频容器对象可用于垃圾收集(请参阅下面的说明,讨论为什么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
所做的事情之间的异常交互。
所以,请注意,如果这个答案解决了你的问题,那么如果它确实有效,那么就不清楚为什么会出现这种情况,而且出于各种原因它也可能停止工作。
将视频重置为空白而不删除它
$("#video-intro").first().attr('src','')
它会停止播放视频
delete(this);
不是解决方案。如果它适用于x或y,则是浏览器不当行为。阅读here:
delete运算符从对象中删除属性。
事实是,当autoplay属性打开时,某些浏览器(例如Firefox)会在内存中缓存视频缓冲区。处理是一种痛苦。
从DOM中删除视频标记或暂停它只会产生不稳定的结果。你必须卸载缓冲区。
var video = document.getElementById('video-id');
video.src = "";
我的实验表明它是这样完成的,但不幸的是这是spec没有完全指定的浏览器实现。在src更改后,您不需要调用load()。更改视频标记的src时,隐式调用其上的load(),这在W3C规范中有说明。
只是为了澄清后来尝试这个的人,解决方法是:(在Safari 5.0中使用h264视频确认,在FF / opera中未经测试)
$(container_selector).children().filter("video").each(function(){
this.pause();
delete(this);
$(this).remove();
});
$(container_selector).empty();
好的,这是一个简单的解决方案,肯定有效:
var bodypage = document.getElementsByTagName('body')[0];
var control_to_remove = document.getElementById('id_of_the_element_here');
bodypage.removeChild(control_to_remove);
这个片段没有做任何有效的DOM操作(没有标记删除),并且不会像error
那样为<video>
触发this answer事件:
var video = document.getElementById('video');
video.removeAttribute('src');
video.load();
此外,它不会引发loadstart
事件。它就像它应该工作 - 没有视频,没有负载启动。
检查Chrome 54 / FF 49。
这是关于如何关闭相机的答案 - 不仅仅是暂停。它应该停止流 - 而不是视频元素参考:stream.stop()