Flash Flex视频显示器只是平面泄漏
事实上,我自己也找到了解决方案,但当我搜索Adobe论坛和这里之前,发现这个问题反复出现但从未解决,我想我应该在这里回答我自己的问题,以便将来谷歌搜索某人 但不管怎样,从之前的评论来看,它在无数的场景中泄露。在我的例子中,它位于另一个SWFLoader中的SWFLoader中,当父SWFLoader离开时,视频将保留在内存中,并且removeEventListeners或gc.collect或RemovedFromStage处理程序中的任何内容的组合都不能解决问题。您可以在那里停止视频,这样它就不会继续播放,但它仍然保留在内存中,并且每次运行时都会添加大约10Mb的视频 顺便说一句,我很困惑Adobe怎么能像他们一样让这样的东西不停地被解开。显然有一些eventlistener隐藏在他们自己的代码中,这些代码从未发布过,但很明显,他们可能不太在意。我认为这类事情至少是flash日益被边缘化的原因之一。对我来说,同样奇怪的是,很多flash开发人员似乎也不了解这个问题,他们认为这不是一个问题,直到所有的系统内存都被消耗掉,浏览器崩溃。嗯,从传统的应用程序开发我自己,它不能接受看到在任务管理器内存不断上升,每次用户点击一个按钮,从来没有释放Flash Flex视频显示器只是平面泄漏,flash,actionscript-3,apache-flex,video,osmf,Flash,Actionscript 3,Apache Flex,Video,Osmf,事实上,我自己也找到了解决方案,但当我搜索Adobe论坛和这里之前,发现这个问题反复出现但从未解决,我想我应该在这里回答我自己的问题,以便将来谷歌搜索某人 但不管怎样,从之前的评论来看,它在无数的场景中泄露。在我的例子中,它位于另一个SWFLoader中的SWFLoader中,当父SWFLoader离开时,视频将保留在内存中,并且removeEventListeners或gc.collect或RemovedFromStage处理程序中的任何内容的组合都不能解决问题。您可以在那里停止视频,这样它就
因此,最初我开始寻找第三方flex视频播放器,并立即跑遍了整个网络。在他们的包中,他们实际上有许多不同的方法和类,通过它们可以调用视频。我尝试了其中的几种(MediaPlayerSprite、MediaContainer、VideoElement、LightweightVideoElement等),但所有这些都泄漏了,泄漏的方式与Flex的VideoDisplay相同!显然,Flex VideoDisplay在幕后使用了OSMF代码,我认为(可能)。所以不管怎么说,一家完全不在乎泄密的公司——难以置信,莫名其妙。只要使用原来的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()
}
就这样。所以,有趣的是,我创建的EventListener都不需要删除,只需要停止一个计时器。以及对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不能提供一些通用方法,让您自己承担风险,完全使用核武器攻击任意对象。不确定这是否对您有帮助,但我在使用视频组件时成功卸载了视频(使用Flash,而不是Flex)。它不会清空视频(并泄漏),除非您这样做(videoPlayer是我的组件实例)
正如我在下面指出的,这肯定是一个Flex问题,flash.media.Video可以成功释放。我实际上没有访问Flex/AS3层次结构中名为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);
}