3

实际上我自己找到了解决方案,但是当我搜索 Adob​​e 论坛和之前在这里发现问题反复出现但从未解决时,我想我会在这里回答我自己的问题,以便将来谷歌搜索某人。

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

顺便说一句,我只是对 Adob​​e 怎么能让这样的事情像他们一样不停地保持不变感到困惑。显然有一些事件监听器埋在他们自己的代码中的某个地方,这些代码从未发布过,但显然他们可能不在乎。我假设这种事情至少是闪存越来越被边缘化的原因之一。对我来说,似乎也没有意识到这个问题的 Flash 开发人员的数量也很奇怪,他们认为这不是问题,直到实际上所有的系统内存都被消耗并且浏览器崩溃了。好吧,我自己来自传统的应用程序开发,在任务管理器中看到每次用户点击按钮时内存不断增加并且从未释放是不可接受的。

所以最初我开始寻找 3rd 方 flex 视频播放器并立即遇到了 开源媒体框架。在他们的包中,他们实际上有许多不同的方法和类,可以通过这些方法和类来调用视频。我尝试了其中的几个(MediaPlayerSprite、MediaContainer、VideoElement、LightweightVideoElement 等),但所有这些都泄露了,并且与 Flex 的 VideoDisplay 一样!显然,Flex VideoDisplay 在我认为(也许)背后使用了 OSMF 代码。因此,无论如何,另一家不关心泄漏的公司 - 令人难以置信,莫名其妙。

4

2 回答 2

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

}

因此,我猜对于仍在进行 Flash 开发的任何人来说,这只是一些有用的奥术炼金术。为什么 Adob​​e 无法提供一些通用方法来完全核对任意对象,风险自负我想我们永远不会知道。

于 2011-11-25T19:41:54.370 回答
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);
        }
于 2011-11-25T20:24:43.100 回答