2

データ生成モードでNetStreamを使用して、appendBytesを使用して埋め込みFLVを再生しています。ストリームの再生が終了したら、FLVファイルをループさせたいと思います。これを達成する方法がわかりません。これが私がこれまでに持っているものです(これは完全な例ではありません):

        public function createBorderAnimation():void
        {
            // Load the skin image
            borderAnimation = Assets.BorderAnimation;

            // Convert the animation to a byte array
            borderAnimationBytes = new borderAnimation();

            // Initialize the net connection
            border_nc = new NetConnection();
            border_nc.connect( null );

            // Initialize the net stream
            border_ns = new NetStream( border_nc );
            border_ns.client = { onMetaData:function( obj:Object ):void{ trace(obj); } }
            border_ns.addEventListener( NetStatusEvent.NET_STATUS, border_netStatusHandler );
            border_ns.play( null );
            border_ns.appendBytes( borderAnimationBytes );

            // Initialize the animation
            border_vd = new Video( 1024, 768 );
            border_vd.attachNetStream( border_ns );

            // Add the animation to the stage
            ui = new UIComponent();
            ui.addChild( DisplayObject( border_vd ) );
            grpBackground.addElement( ui );             
        }

        protected function border_netStatusHandler( event:NetStatusEvent ):void
        {
            if( event.info.code == "NetStream.Buffer.Flush" || event.info.code == "NetStream.Buffer.Empty" )
            {
                border_ns.appendBytesAction( NetStreamAppendBytesAction.RESET_BEGIN );
                border_ns.appendBytes( borderAnimationBytes );
                border_ns.appendBytesAction( NetStreamAppendBytesAction.END_SEQUENCE );
            }
        }

これはアニメーションをループしますが、それは狂ったように記憶をかみ砕き始めます。NetStream.seek(0)とNetStream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK)を使用してみましたが、次に何をすべきかわかりません。その後、appendBytesを再度呼び出そうとすると、機能しません。おそらく、FLVヘッダーなどを含むフルバイト配列を追加しているためです。私はそれがどのように機能するかについてはあまりよく知りません。

どんな助けでも大歓迎です。

4

2 に答える 2

5

[編集]

最初は、コードにメモリの問題は見られませんでした。ただし、私が使用していたサンプルアプリ(以下)は、NetStream.Buffer.EmptyからのメッセージのみをリッスンしますNetStatusEventNetStream.Buffer.Flushメッセージをリッスンしません。あなたの例のように、私はちょうど両方を聞いてみました、そしてアプリは大騒ぎになります:)

seek(0)以下のコードは、を使用して再生を再開する方法も示していますappendBytes()。これを機能させるには、から待機してNetStream.Seek.NotifyからNetStatusEvent、バイトを追加する必要があります。

また、(コメント欄)を使わずに再生を再開seek(0)しましたが、メモリ使用量は問題ありませんでした。

Mac OS Xを使用しており、topコマンドとアクティビティモニターでメモリを測定しています。Activity Monitorの仮想メモリの統計は大幅に変動しましたが、メモリリークのようなものはありません。

package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.NetStatusEvent;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.net.NetStreamAppendBytesAction;
    import flash.utils.ByteArray;

    public class LoopEmbedFLV extends Sprite
    {

        [Embed(source="woot.flv",mimeType="application/octet-stream")]
        private var flv:Class;

        private var bytes:ByteArray;
        private var nc:NetConnection;
        private var ns:NetStream;
        private var video:Video;

        public function LoopEmbedFLV()
        {
            super();
            stage.scaleMode=StageScaleMode.NO_SCALE;
            stage.align=StageAlign.TOP_LEFT;
            bytes = new flv();
            nc=new NetConnection();
            nc.connect(null);
            ns=new NetStream(nc);
            video=new Video();
            addChild(video);
            video.attachNetStream(ns);
            ns.client = { onMetaData: function():void { } };
            ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
            ns.play(null);
            ns.appendBytes(bytes);
        }

        private function onNetStatus(event:NetStatusEvent):void
        {
            var code:String=event.info.code;
            trace(code);
            switch(code)
            {
                case "NetStream.Buffer.Empty":
                    ns.seek(0);
//                  seekToBeginning();
                    break;
                case "NetStream.Seek.Notify":
                    var seekPoint:Number = event.info.seekPoint;
                    trace("seeking to: ", seekPoint);
                    seekPoint == 0 ? seekToBeginning() : seekToOffset(seekPoint);
                    break;
            }
        }

        private function seekToBeginning():void
        {
            ns.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
            ns.appendBytes(bytes);
            ns.appendBytesAction(NetStreamAppendBytesAction.END_SEQUENCE);
        }
        private function seekToOffset(seekPoint:Number):void
        {
            ns.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
            // todo
        }
    }
}
于 2012-08-13T17:11:21.110 に答える
1
package {

    import flash.display.MovieClip;
    import flash.events.AsyncErrorEvent;
    import flash.events.IOErrorEvent;
    import flash.events.NetStatusEvent;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.utils.ByteArray;


    public class VideoPlayer extends MovieClip {

        /** Проиграть массив данныx <b>byteArray</b> (flv) в видеоконтейнере <b>video</b>. Проигрывается 1 + n раз, при n >= 0 и infinity при n < 0
         * 
         * @param video - видеоконтейнер
         * @param fileArray - массив данныx (flv) 
         * @param repeat - количество повторений видеоролика (-1 - бесконечный цикл, 0 - проиграть без повторений, (n > 0) - n повторений)
         * 
         */     
        public static function playVideo(video:Video, byteArray:ByteArray, repeat:int = -1):void {
            var netConnection:NetConnection;
            var netStream:NetStream;
            var repeatCount:int = 0;

            var netStream_Status_Handler:Function = function(event:NetStatusEvent):void {
                switch(event.info.code || "") {
                    case 'NetStream.Buffer.Empty': {
                        update();
                    }
                    default: {
                        break;
                    }
                }
            }

            var netStream_IOError_Handler:Function = function(event:AsyncErrorEvent):void {

            }

            var netConnection_Status_Handler:Function = function(event:NetStatusEvent):void {
                switch(event.info.code || "") {
                    case 'NetConnection.Connect.Success': {
                        update();
                        break;
                    }

                    default: {
                        break;
                    }
                }
            }

            var update:Function = function():void {
                if(repeat > -1 && repeat < repeatCount) {
                    return;
                }

                repeatCount++;

                try {
                    if(netStream) {
                        netStream.close();
                        if(netStream.hasOwnProperty("dispose")) { // совместимость с fla|as3
                            netStream["dispose"]();
                        }
                        netStream = null;
                    }

                    netStream = new NetStream(netConnection);
                    netStream.addEventListener(NetStatusEvent.NET_STATUS, netStream_Status_Handler);
                    netStream.addEventListener(IOErrorEvent.IO_ERROR, netStream_IOError_Handler);
                    netStream.client = {};
                    netStream.play(null);
                    netStream["appendBytes"](byteArray); // совместимость с fla|as3

                    video.attachNetStream(netStream); 
                } catch(error:Error) {

                }
            }

            var netConnection_AsyncError_Handler:Function = function(event:AsyncErrorEvent):void {

            }

            var netConnection_IOError_Handler:Function = function(event:AsyncErrorEvent):void {

            }

            netConnection = new NetConnection();
            netConnection.addEventListener(NetStatusEvent.NET_STATUS , netConnection_Status_Handler);
            netConnection.addEventListener(AsyncErrorEvent.ASYNC_ERROR , netConnection_AsyncError_Handler);
            netConnection.addEventListener(IOErrorEvent.IO_ERROR , netConnection_IOError_Handler);
            netConnection.connect(null);
        }

    }
}
于 2013-07-09T13:59:36.463 に答える