3

実際、私は自分で解決策を見つけましたが、以前にAdobeフォーラムとここを検索し、問題が繰り返し提示されたが解決されなかったことがわかったので、誰かの将来のGoogle検索のためにここで自分の質問に答えようと思いました.

とにかく、それは漏れており、以前のコメンテーターから判断すると、無数のシナリオで. 私の場合、別の SWFLoader 内の SWFLoader にあり、親の SWFLoader がなくなると、ビデオはメモリに残り、removeEventListeners または gc.collect の組み合わせ、または RemovedFromStage ハンドラーにあるものは問題を解決しません。そこでビデオを停止することができるので、再生を続けませんが、それでもメモリに残り、実行するたびにさらに 10Mb ほど追加されます。

そして括弧書きとして、Adobe がこのようなものを絶え間なく修正せずに放置しておくことができたのか、私は不思議に思っています。リリースされない独自のコードのどこかに埋もれているイベントリスナーが明らかにありますが、明らかに彼らはあまり気にしません。この種のことが、フラッシュがますます疎外されている理由の少なくとも 1 つに違いないと思います。また、システム メモリがすべて消費されてブラウザがクラッシュするまで問題ではないと考えているフラッシュ開発者の数も、この問題を認識していないようです。さて、私自身の従来のアプリケーション開発から来て、ユーザーがボタンを押すたびにタスクマネージャーでメモリが継続的に増加し、決して解放されないのを見るのは受け入れられません。

そのため、最初にサードパーティのフレックス ビデオ プレーヤーを探し始めたところ、すぐに Open Source Media Frameworkに出会いました。そして、彼らのパッケージには、実際には、ビデオを呼び出すことができるさまざまなメソッドとクラスが多数含まれています。そして、これらのいくつか (MediaPlayerSprite、MediaContainer、VideoElement、LightweightVideoElement など) を試しましたが、これらもすべてリークし、Flex の VideoDisplay と同じように! 明らかに、Flex VideoDisplay は舞台裏で OSMF コードを使用しています (たぶん)。とにかく、リークを気にしないまったく別の会社 - 信じられない、説明のつかない.

4

2 に答える 2

1

元の 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()      
}

それでおしまい。興味深いことに、私が作成したイベントリスナーはどれも削除する必要はなく、ただ 1 つのタイマーを停止する必要がありました。また、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);

}

つまり、まだフラッシュ開発を行っている人にとって、いくつかの有用な難解な錬金術だと思います。アドビが、自己責任で任意のオブジェクトを完全に破壊するための汎用的な方法を提供できなかった理由は、私たちには決してわからないでしょう。

于 2011-11-25T19:41:54.370 に答える
0

これが役立つかどうかはわかりませんが、ビデオ コンポーネントを使用しているときに、ビデオを (Flex ではなく Flash で) アンロードすることに成功しました。これを行わない限り、ビデオを空にすることはありません(そしてリークします)(videoPlayerは私のComponentインスタンスです)...

         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 に答える