views:

953

answers:

1

Can't get any love anywhere on this and it's pretty hard to believe. Live streaming and a buffer on a NetStream do not mix. Why? The docs don't say you can't do this.

The playback gets hosed. Buffer is supposed to fill to what you set it to before playing. Instead though, about half the time, the player starts playing right away and disregards the buffer time you've set. Then you get caught in short buffering and rebuffering cycles that degrades the playback experience.

Give it a shot yourself. Here is the simplest of live streaming video players. No frills. Just connect it to your live stream by changing the defaultURL string and stream name in the ns.play() statement.

Run it in Flex debug mode. It will check and print the ns.bufferLength property every second. The buffer is set to 20 secs currently. Last time I ran it, I never made it above 2 seconds in the buffer. Player started playing right away instead of buffering the full 20 secs first. Sometimes you get to the full 20 and sometimes not. Why? No idea.

Can you not buffer a live stream reliably or is there something wrong with the code?

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    initialize="init()">
    <mx:Script>
        <![CDATA[
            import flash.media.Video;
            import flash.net.NetConnection;
            import flash.net.NetStream;
            import mx.core.UIComponent;

            private var vid:Video;
            private var videoHolder:UIComponent;
            private var nc:NetConnection;
            private var defaultURL:String="rtmp://your_streaming_server_url_here";
            private var ns:NetStream;
            private var msg:Boolean;

            private var intervalMonitorBufferLengthEverySecond:uint;

            private function init():void
            {
                vid=new Video();
                vid.width=864;
                vid.height=576; 
                vid.smoothing = true;                            
                //Attach the video to the stage              
                videoHolder = new UIComponent();
                videoHolder.addChild(vid);
                addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
                this.addChild(videoHolder);
                connect();
            }

            public function onSecurityError(e:SecurityError):void
            {
                trace("Security error: ");
            }

            public function connect():void
            {
                nc = new NetConnection();
                nc.client = this;
                nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
                nc.connect(defaultURL);                 
            }

            public function netStatusHandler(e:NetStatusEvent):void
            {
                switch (e.info.code) {
                    case "NetConnection.Connect.Success":
                        trace("Connected successfully");
                        createNS();                 
                        break;
                    case "NetConnection.Connect.Closed":
                        trace("Connection closed");                 
                        connect();
                        break;  
                    case "NetConnection.Connect.Failed":
                        trace("Connection failed");                 
                        break;
                    case "NetConnection.Connect.Rejected":
                        trace("Connection rejected");                                   
                        break;  
                    case "NetConnection.Connect.AppShutdown":
                        trace("App shutdown");                                  
                        break;          
                    case "NetConnection.Connect.InvalidApp":
                        trace("Connection invalid app");                                    
                        break;                                                                                                      
                }           
            }

            public function createNS():void
            {
                trace("Creating NetStream");
                ns=new NetStream(nc);
                //nc.call("FCSubscribe", null, "live_production"); // Only use this if your CDN requires it
                ns.addEventListener(NetStatusEvent.NET_STATUS, netStreamStatusHandler);
                vid.attachNetStream(ns);

                //Handle onMetaData and onCuePoint event callbacks: solution at http://tinyurl.com/mkadas
                //See another solution at http://www.adobe.com/devnet/flash/quickstart/metadata_cue_points/
                var infoClient:Object = new Object();
                infoClient.onMetaData = function oMD():void {};
                infoClient.onCuePoint = function oCP():void {};         
                ns.client = infoClient; 
                ns.bufferTime = 20; 
                ns.play("your_stream_name");    
                ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
                function asyncErrorHandler(event:AsyncErrorEvent):void {
                    trace(event.text);
                }   
                intervalMonitorBufferLengthEverySecond = setInterval(monPlayback, 1000);
            }

            public function netStreamStatusHandler(e:NetStatusEvent):void
            {
                switch (e.info.code) {
                    case "NetStream.Buffer.Empty":
                        trace("Buffer empty: ");
                        break;
                    case "NetStream.Buffer.Full":
                        trace("Buffer full:");
                        break;
                    case "NetStream.Play.Start":
                        trace("Play start:");
                        break;                      
                }       
            }

            public function monPlayback():void {
                // Print current buffer length
                trace("Buffer length: " + ns.bufferLength);
            }

            public function onBWDone():void { 
                //Do nothing
            }           

            public function onFCSubscribe(info:Object):void {       
                // Do nothing. Prevents error if connecting to CDN.     
            }

            public function onFCUnsubscribe(info:Object):void {     
                // Do nothing. Prevents error if connecting to CDN.     
            }

        ]]>
    </mx:Script>    
</mx:Application>

My last run:

Connected successfully

Creating NetStream

Play start:

Buffer length: 0.001

Buffer full: //Obviously the buffer is not full here. Bogus.

Buffer length: 2.202

Buffer length: 2.369

Buffer length: 2.102

Buffer length: 2.402

Buffer length: 2.302

Buffer length: 2.369

Buffer length: 2.269

Buffer length: 2.269

Buffer length: 2.302

Buffer length: 2.369

Buffer length: 1.926

Buffer length: 2.336

Buffer length: 2.286

Buffer length: 2.336

Buffer length: 2.336

Buffer length: 2.403

Buffer length: 2.388

Buffer length: 2.402

Buffer length: 2.335

Buffer length: 2.369

Buffer length: 2.336

Buffer length: 2.339

Buffer length: 2.369

Buffer length: 2.402

Buffer length: 2.369

Buffer length: 2.396

Buffer length: 2.436

Buffer length: 2.336

Buffer length: 2.269

A: 

Did you got the answer for this question..

Aswath