2011-11-25 52 views
3

實際上,我自己找到了解決方案,但是當我搜索Adobe論壇並在此之前發現問題反覆出現但從未解決時,我想回答我自己的問題,以便爲未來的谷歌搜尋某人。Flex VideoDisplay只是平坦的泄漏

但無論如何,它泄漏,並從以前的評論者判斷,在無數的情況。在我的情況下,它在另一個SWFLoader中的SWFLoader中,當父SWFLoader消失時,視頻停留在內存中,並且沒有removeEventListener或gc.collect組合或者RemovedFromStage處理程序中的什麼組合可以解決此問題。您可以在那裏停止視頻,因此它不會繼續播放,但仍然保留在內存中,每次運行時都會添加另外10Mb左右的視頻。

而且在括號內,我只是很迷惑Adobe如何讓像這樣的東西像他們一樣不斷修復。顯然有些事件監聽器被埋在自己代碼的某個地方,而這些代碼從來沒有發佈過,但顯然他們可能不太在意。我認爲這種事情至少應該是閃現日益邊緣化的原因之一。對我來說,閃存開發人員的數量似乎也並不理解這個問題,他們認爲這不是一個問題,直到幾乎所有的系統內存都被佔用,瀏覽器崩潰。那麼,從我自己的傳統應用程序開發來看,在任務管理器中看到每當用戶點擊一個按鈕並且從未發佈時內存不斷地變得不可接受。

所以最初我開始尋找第三方彈性視頻播放器,並立即跑過Open Source Media Framework。在他們的軟件包中,他們實際上有許多不同的方法和類,通過它們可以調用視頻。我嘗試了其中的一些(MediaPlayerSprite,MediaContainer,VideoElement,LightweightVideoElement等),但所有這些都泄漏了,就像Flex的VideoDisplay一樣!很明顯,Flex VideoDisplay使用我認爲(也許)背後的OSMF代碼。無論如何,整個其他公司並不關心泄漏 - 令人難以置信,莫名其妙。

回答

1

只需使用原始的flash.media.Video。你還必須單獨創建一個NetStream,一個NetConnection,並且運行你自己的定時器,如果你想擁有像VideoDisplay一樣的功能,它可以在運行時自動更新播放頭時間。 (您需要這樣做並使用自己的計時器來跟蹤加載進度。)您還需要在removedFromStage處理程序中執行一些操作以避免泄漏。這是真正的重要組成部分,但初始化的一切,像下面這樣:

var uic:UIComponent = new UIComponent();   
var ns:NetStream;   
var v:Video = new Video();   
var nc:NetConnection = new NetConnection();  
var timer:Timer = new Timer(250);   

... 

uic.addChild(v);  
this.addChild(uic);  
v.width=Number(parameters.w); 
v.height=Number(parameters.h); 

nc.connect(null);   
ns = new NetStream(nc);   
ns.addEventListener("netStatus",play_end); 
uic.addEventListener("removedFromStage",v_remove); 

v.attachNetStream(ns);   

ns.play(session.source);   
ns.pause();   

timer.addEventListener("timer",load_handlr);   
timer.start();   

而在removedFromStage處理:

private function v_remove(e:Event) {  

    ns.close();  
    nc.close(); 

    v.attachNetStream(null); 

    timer.stop()  
} 

就是這樣。所以,有趣的是,我創建的eventlisteners中沒有一個必須被刪除,只是必須停止一個計時器。還有對nc.close等的調用(不確定實際上是否需要v.attachNetStream(null);)。 VideoDisplay有它自己的close()方法,但我曾試過,並且對VideoDisplay中的泄漏沒有影響。

因此,上述停止視頻,並防止泄漏。在我的情況下,我希望視頻繼續播放直到結束,爲此我必須刪除其他事件偵聽器,因此它不會在循環中繼續重新啓動(並且由於該原因未釋放內存),以及然後取出調用ns.close所以它會起到年底:

private function v_remove(e:Event) { 

    nc.close(); 

    v.attachNetStream(null); 

    timer.stop() 
    timer.removeEventListener("timer",timer_handlr); 
    ns.removeEventListener("netStatus",play_end); 
    uic.removeEventListener("removedFromStage",v_remove); 

} 

所以只是一些有用的神祕的煉丹的人還在做Flash開發我猜。爲什麼Adobe無法提供一些通用目的的方法來完全摧毀任意對象,風險自負我想我們永遠不會知道。

0

不確定這是否會對您有所幫助,但在使用視頻組件時,我已成功卸載視頻(在Flash中,而不是Flex)。它不會空出的視頻(和泄漏),除非你做這個(錄像機是我的組件實例)...

  try{ 

      for each(var v: VideoPlayer in videoPlayer.flvplayback_internal::videoPlayers){ 
       log("Cleaning up VideoPlayer:" + v); 
       v.close(); 
       v.clear(); 
      } 


     }catch(e:Error){ 
      log("EndVideo Failed: " + e); 
     } 
+0

它絕對是一個Flex的問題,我想指出的下方,flash.media.Video可以成功釋放。實際上,我並沒有在Flex/AS3層次結構中訪問名爲VideoPlayer的類。 – Mark