实际上我自己找到了这个解决方案,但是当我搜索Adobe论坛以及此前曾发现问题反复出现但从未解决时,我想我会回答我自己的问题,以便将来谷歌搜索某人。< / p>
但无论如何,从以前的评论员的角度来看,它在各种各样的情景中都会泄漏。在我的情况下,它在另一个SWFLoader中的SWFLoader中,当父SWFLoader消失时,视频保留在内存中,并且removeEventListeners或gc.collect的组合或者RemovedFromStage处理程序中没有的东西将解决问题。您可以在那里停止视频,因此它不会继续播放,但它仍然保留在内存中,每次运行时都会添加另外10Mb左右。
顺便说一句,我只是神秘地说Adobe如何能够让像这样的东西像他们一样不断地保持不变。显然有些事件隐藏在他们自己的代码中的某个地方,从未被释放过,但很明显他们可以少关心。我假设这种事情至少是闪电越来越被边缘化的原因之一。它对我来说也很奇怪,闪存开发人员似乎也没有意识到这个问题,认为这不是一个问题,直到字面上所有系统内存被消耗并且浏览器崩溃。好吧,我自己来自传统的应用程序开发,在任务管理器中看到每次用户点击按钮并且从未发布时,内存不断增加是不可接受的。
所以最初我开始寻找第三方灵活视频播放器并立即跑过Open Source Media Framework。在他们的包中,他们实际上有许多不同的方法和类,可以通过它们调用视频。我尝试了其中的几个(MediaPlayerSprite,MediaContainer,VideoElement,LightweightVideoElement等),但所有这些都泄露了,并且与Flex的VideoDisplay一样!显然,Flex VideoDisplay在我认为(可能)的幕后使用OSMF代码。所以,无论如何,整个其他公司都不关心泄漏 - 令人难以置信,莫名其妙。
答案 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);
}