2011-09-25 189 views
3

我想知道如何最好地替換網頁上的嵌入式視頻。我有一串視頻文件(AVI),遊客可以選擇和觀看。javascript/html:替換嵌入式視頻內存泄漏?

我對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; 

是否有任何內存清理我應該照顧?

+0

我刪除了嵌入式標籤,因爲它是嵌入式系統,而不是嵌入在網頁中。 – tinman

回答

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文件中包含哪些視頻和音頻編解碼器?