javascript / html:替换嵌入式视频内存泄漏?

时间:2011-09-25 15:17:59

标签: javascript html memory video

我想知道如何最好地替换网页上的嵌入视频。我有一堆视频文件(avi),访问者可以选择和观看。

我对javascript和html很新,但我目前正在做的是将视频作为对象嵌入网页,当选择新视频时,我更改了对象的url参数。这会正确地更改视频,但是在几个视频之后,浏览器就会无响应。查看任务管理器,每个视频打开时内存使用率都会上升。

我原本以为由于对象具有相同的id,它会删除第一个视频并加载下一个视频。但是,似乎第一个视频仍在内存中。有一个更好的方法吗?

我使用的是Windows 7,Windows Media Player 12,IE8。我也想知道这是否与这些技术有关,因为当我在旧PC(Windows XP,WMP 9,IE8)上运行时,它似乎没有泄漏内存。

基本上我正在做的事情: html中的视频标签:

    <object width="100%" height="100%" id="video"
    classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
    <param name="url" value="video1.avi">
    <param name="autostart" value="1">
    <param name="uiMode" value="full" />
    </object>

然后当用户选择新视频时(javascript - 假设newVideoPath包含下一个视频的路径):

    $("video").url = newVideoPath;

我应该照顾一下内存清理吗?

1 个答案:

答案 0 :(得分:1)

首先,我想提一下,我对跨浏览器视频嵌入没有多少经验。或许这些解释仍有帮助。

基本上有两种播放视频的方式:使用浏览器播放视频和使用插件。

使用浏览器意味着您需要为不同的浏览器提供不同的视频文件。适用于IE9和Safari的Firefox,Chrome,Opera和H264都有WebM或OGV。 IE8及以下版本根本不支持视频。

插件方法的优势在于您可以提供插件所需的功能。问题是你永远不知道是否存在诸如Windows Media Player,Flash或其他插件的插件。

这导致您需要提供不同的媒体文件(不同的文件格式)以获得合理的工作视频概率。 John Dyer's tutorial列出了要采取的重要步骤 - 但是在尝试使用插件之前,您还应该为WebM提供服务。提供AVI文件没有多大意义,因为这种格式只是一个可以包含任何视频和音频编解码器的容器。

<video>
    <source src="myfile.mp4">
    <source src="myfile.ogg">
    <object src="flashplayer.swf?file=myfile.mp4">
        <embed src="flashplayer.swf?file=myfile.mp4">
    </object>
</video>

此代码尝试投放myfile.mp4,如果失败myfile.ogg,如果失败,则使用Adobe的Flash投放myfile.mp4。您可以使用尽可能多的source标记添加文件,因为您可以使用文件格式。然后浏览器将使用它理解的第一个文件。

本教程有一个扩展版本,它首先使用JavaScript来检测视频支持,并在必要时为Flash添加回退。您可以使用Windows Media Player替换Flash部件。

classid属性上的一个词:此属性指的是指定的ActiveX控件。这有两个问题。 ActiveX仅在Windows上可用,并且在所有其他平台上都将失败。由于classid指定了一个特定的控件,因此没有插件实现的Windows系统也会失败 - 所以请避免这样的事情。因此,我建议首先使用HTML5方法和视频标记,然后只提供一些文件。这样做允许浏览器选择合适的播放器来增加视频播放的变化。然后需要添加一些JavaScript以提供回退。

最后,我们最终得到了类似的内容:

<video id="video">
    <source src="myfile.webm">
    <source src="myfile.mp4">
    <source src="myfile.ogg">
</video>
<script type="text/javascript">
(function(){
    var dummy = document.createElement("video");
    // See if native video support is not available
    if(typeof(video.canPlayType)===undefined || video.canPlayType('video/webm') == '' || add other video types here corresponding to source tags){
        var videoElement = document.getElementById('video');
        var fallbackContainer = document.createElement('div');
        // Insert your HTML string for Windows Media, Flash, MPlayer or whatever else here
        var fallback = '…';
        fallbackContainer.innerHTML = fallback;
        // This replaces the native (not available) video player with the plugin
        videoElement.parentNode.replaceChild(fallbackContainer, videoElement);
    }
})();
</script>

您还可以使用类似MediaElement.js的内容,并避免自己处理所有不同的环境。

现在,让我们回过头来关于内存泄漏和替换视频的问题。如果您的脚本导致内存泄漏,那么您使用的实现存在一些严重问题。但在指责实施之前,您应确保确实存在泄漏。

垃圾收集(释放内存的过程)需要时间,因此在“合适”时间完成,而不是尽快完成。所以很可能你的浏览器(或插件)只能在一段时间后或内存不足时清理。然后,每当您更改视频时,您都会看到增加的内存,但这不会是泄漏,因为它最终会被清除。尝试通过多次更改视频来触发垃圾收集,直到内存不足为止 - 是否进行了清理?尝试更改浏览器中的选项卡或关闭选项卡 - 是否进行清理?如果你现在看到清理,可能没有泄漏担心。实现只是认为你的测试用例不需要释放内存。

如果您发现它真的是泄漏,您可以尝试分离到视频,使用新视频而不是替换旧视频。为此,请使用与以前相同的方法:

var oldVideoElement = document.getElementById('video');
// Add some video element creation here for the new video
var newVideoElement = …;
// Replace video but make the browser aware of the replacement by using DOM methods
oldVideoElement.parentNode.replaceChild(newVideoElement, oldVideoElement);
// Get rid of the reference to the old video (just in case IE8 has still problems with discarding references)
var oldVideoElement = null;

使用DOM方法允许浏览器完全从内存中删除插件。幸运的是,你的泄漏现在已经消失了。使用相同的技术通过创建新视频在文件之间切换,并使用它来替换旧视频(整个元素,而不仅仅是文件名)。

如果这没有帮助,您需要提供更多信息:您要定位哪些操作系统和浏览器?你知道有一个特定的插件吗?您的AVI文件中包含哪些视频和音频编解码器?