Flex VideoDisplay只是漏洞

时间:2011-11-25 19:31:35

标签: flash actionscript-3 flex video osmf

实际上我自己找到了这个解决方案,但是当我搜索Adobe论坛以及此前曾发现问题反复出现但从未解决时,我想我会回答我自己的问题,以便将来谷歌搜索某人。< / p>

但无论如何,从以前的评论员的角度来看,它在各种各样的情景中都会泄漏。在我的情况下,它在另一个SWFLoader中的SWFLoader中,当父SWFLoader消失时,视频保留在内存中,并且removeEventListeners或gc.collect的组合或者RemovedFromStage处理程序中没有的东西将解决问题。您可以在那里停止视频,因此它不会继续播放,但它仍然保留在内存中,每次运行时都会添加另外10Mb左右。

顺便说一句,我只是神秘地说Adobe如何能够让像这样的东西像他们一样不断地保持不变。显然有些事件隐藏在他们自己的代码中的某个地方,从未被释放过,但很明显他们可以少关心。我假设这种事情至少是闪电越来越被边缘化的原因之一。它对我来说也很奇怪,闪存开发人员似乎也没有意识到这个问题,认为这不是一个问题,直到字面上所有系统内存被消耗并且浏览器崩溃。好吧,我自己来自传统的应用程序开发,在任务管理器中看到每次用户点击按钮并且从未发布时,内存不断增加是不可接受的。

所以最初我开始寻找第三方灵活视频播放器并立即跑过Open Source Media Framework。在他们的包中,他们实际上有许多不同的方法和类,可以通过它们调用视频。我尝试了其中的几个(MediaPlayerSprite,MediaContainer,VideoElement,LightweightVideoElement等),但所有这些都泄露了,并且与Flex的VideoDisplay一样!显然,Flex VideoDisplay在我认为(可能)的幕后使用OSMF代码。所以,无论如何,整个其他公司都不关心泄漏 - 令人难以置信,莫名其妙。

2 个答案:

答案 0 :(得分: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()      
}

就是这样。所以,有趣的是,我创建的事件监视器都不会被删除,只需要停止一个计时器。还有对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);

}

对于任何仍在进行闪存开发的人来说,这只是一些有用的奥术炼金术。为什么Adobe无法提供一些通用的方法来完全核对任意对象,我自己也不会知道。

答案 1 :(得分:0)

不确定这对您是否有帮助,但在使用视频组件时,我已成功卸载视频(在Flash中,而不是Flex)。它不会清空视频(和泄漏),除非你这样做(videoPlayer是我的组件实例)......

         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);
        }