【问题标题】:javascript/html: Replacing embedded videos memory leak?javascript/html:替换嵌入式视频内存泄漏?
【发布时间】:2011-09-25 15:17:58
【问题描述】:

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

I am pretty new to javascript and html, but what I am currently doing is embedding the videos on the webpage as objects, and when a new video is selected, I change the url param for the object.这会正确更改视频,但是在播放几个视频后,浏览器会变得无响应。查看任务管理器,内存使用量随着每个视频的打开而增加。

我原本以为既然对象有相同的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;

有什么我应该注意的内存清理吗?

【问题讨论】:

  • 我删除了嵌入式标签,因为它适用于嵌入式系统,而不是嵌入网页中的东西。

标签: javascript html memory video


【解决方案1】:

首先我想提一下,我在跨浏览器视频嵌入方面没有太多经验。不过,也许这些解释会有所帮助。

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

使用浏览器意味着您需要为不同的浏览器提供不同的视频文件。 Firefox、Chrome、Opera 有 WebM 或 OGV,IE9 和 Safari 有 H264。 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 文件中有哪些视频和音频编解码器?

【讨论】:

    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 2012-07-27
    • 2011-10-11
    • 1970-01-01
    • 2011-02-28
    相关资源
    最近更新 更多