Flex VideoDisplay 只是平坦泄漏

发布于 2024-12-17 19:35:58 字数 927 浏览 0 评论 0原文

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

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

顺便说一句,我只是很奇怪 Adob​​e 怎么能让这样的事情像他们一样一直得不到解决。显然有一些事件监听器埋在他们自己的代码中的某个地方,这些代码永远不会被释放,但显然他们不在乎。我认为这类事情至少是闪存日益被边缘化的原因之一。让我感到奇怪的是,许多 Flash 开发人员似乎也没有意识到这个问题,他们认为这不是问题,直到所有系统内存都被消耗并且浏览器崩溃为止。嗯,我自己来自传统的应用程序开发,在任务管理器中看到每次用户点击按钮时内存不断增加并且从未释放是不可接受的。

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

And actually I found the solution myself, but as I searched Adobe forums and here previously and found the problem presented repeatedly but never resolved, thought I'd answer my own question here for the benefit of future google searches of someone.

But anyway it leaks, and judging from previous commentors, in a whole myriad of scenarios. In my case its in SWFLoader within another SWFLoader, and when the parent SWFLoader goes away, the video stays in memory, and no combination of removeEventListeners or gc.collect or what have you in a RemovedFromStage handler will fix the problem. You can stop the video there, so it doesn't keep playing, but it still stays in memory, and another 10Mb or so added each time you run it.

And parenthetically, I'm just mystified how Adobe could let something like this stay unfixed incessantly like they have. There is obviously some eventlistener buried somewhere in their own code which is never released, but clearly they could care less. I'm assuming this sort of thing has to be at least one of the reasons that flash is being increasingly marginalized. Its also strange to me the number of flash developers that don't seem to appreciate the problem either, that think its not a problem until literally all the system memory is consumed and the browser crashes. Well,coming from conventional application development myself, its not acceptable to see in task manager the memory continuously bumped up every time the user hits a button and never released .

So originally I started looking for 3rd party flex video players and immediately ran across the Open Source Media Framework . And in their package they actually have numerous different methods and classes by which a video can be invoked. And I tried several of these (MediaPlayerSprite, MediaContainer, VideoElement, LightweightVideoElement, etc) but all of these leaked as well, and in in the same way as Flex's VideoDisplay! Evidently though, Flex VideoDisplay uses the OSMF code behind the scenes I think (maybe). So anyway, a whole other company that doesn't care about leaks - incredible, inexplicable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花落人断肠 2024-12-24 19:35:59

只需使用原始的 flash.media.Video。如果您想拥有像 VideoDisplay 那样在运行时自动更新播放头时间的功能,您还必须单独创建一个 NetStream、一个 NetConnection,并且还运行自己的计时器。 (您需要这样做并使用自己的计时器自行跟踪加载进度。)您还需要在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 无法提供某种通用方法来完全摧毁任意对象(由您自担风险),我想我们永远不会知道。

Just use the original flash.media.Video. You'll have to also create a NetStream seperately, a NetConnection,and also run your own timer if you want to have functionality like in VideoDisplay that automatically updates the play head time while running. (You need to do that and track load progress yourself with your own timer.) You also need to do some things in a removedFromStage handler to avoid leaks. That's really the crucial part, but to initialize everything, something like the following:

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

And in the removedFromStage handler:

private function v_remove(e:Event) {      

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

  v.attachNetStream(null);  

  timer.stop()      
}

That's it. So, interestingly, none of the eventlisteners I created had to be removed, just that one timer had to be stopped. And also the call to nc.close, etc. (Not sure actually if the v.attachNetStream(null); is strictly necessary). VideoDisplay has its own close() method, but I had tried it and no effect on the leak in VideoDisplay.

So the above stops the video and prevents the leak. In my case I want the video to keep playing until the end though, and for that I did have to remove the other event listeners, so it wouldn't keep restarting in a loop (and the memory not released for that reason), and then take out the call to ns.close so it will play to the end:

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

}

So just some useful arcane alchemy for anyone still doing flash development I guess. Why Adobe could not provide some general purpose method to completely nuke an arbitrary object at your own risk I guess we'll never know.

你的背包 2024-12-24 19:35:59

不确定这是否对您有帮助,但我在使用视频组件时成功卸载了视频(在 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);
        }

Not sure if this will help you but I've had success unloading the video (in Flash, not Flex) when using the video component. It doesn't empty out the video (and leaks) unless you do this this (videoPlayer is my Component instance)...

         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);
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文