如何在数据生成模式下使用NetStream循环播放视频

时间:2012-08-09 20:58:37

标签: actionscript-3 flash flex netstream

我在数据生成模式下使用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头和东西的完整字节数组?我不太熟悉这一切是如何运作的。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:5)

<强> [编辑]

最初我没有看到代码存在内存问题。但是,我使用的示例应用程序(下面)仅侦听来自NetStream.Buffer.Empty的{​​{1}}消息。它不会监听NetStatusEvent消息。我只是试着去听两个,就像你的例子一样,应用程序变得混乱:)

下面的代码还说明了如何使用NetStream.Buffer.Flush重新启动seek(0)播放。要做到这一点,您需要等待appendBytes()中的NetStream.Seek.Notify,然后附加字节。

我还没有使用NetStatusEvent(注释掉的行)重新开始播放,内存使用情况也不错。

我正在使用Mac OS X并使用seek(0)命令和活动监视器测量内存。 Activity Monitor的虚拟内存统计数据大幅波动,但没有像内存泄漏一样。

top

答案 1 :(得分: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);
        }

    }
}