首先我想提一下,我在跨浏览器视频嵌入方面没有太多经验。不过,也许这些解释会有所帮助。
播放视频基本上有两种方式:使用浏览器播放视频和使用插件。
使用浏览器意味着您需要为不同的浏览器提供不同的视频文件。 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 文件中有哪些视频和音频编解码器?