Flex + буфер + прямой эфир через RTMP = катастрофа - PullRequest
2 голосов
/ 27 января 2010

Нигде в этом нет никакой любви, и в это довольно сложно поверить. Прямая трансляция и буфер на NetStream не смешиваются. Зачем? В документах не говорится, что вы не можете этого сделать.

Воспроизведение задерживается. Предполагается, что буфер заполнен до того, что вы установили перед игрой. Вместо этого, примерно в половине случаев, игрок начинает играть сразу и игнорирует установленное вами время буфера. Затем вы попадаете в короткие циклы буферизации и буферизации, что ухудшает качество воспроизведения.

Сделай это сам. Вот самый простой из потоковых видео проигрывателей. Никакие оборки. Просто подключите его к вашему прямому эфиру, изменив строку по умолчаниюURURL и имя потока в операторе ns.play ().

Запустите его в режиме отладки Flex. Он будет проверять и печатать свойство ns.bufferLength каждую секунду. Буфер установлен на 20 секунд в настоящее время. В прошлый раз, когда я запускал его, я никогда не делал его выше 2 секунд в буфере. Игрок начал играть сразу, вместо того, чтобы сначала буферизовать полные 20 секунд. Иногда вы получаете в полной мере 20, а иногда нет. Зачем? Понятия не имею.

Не можете ли вы надежно буферизовать живой поток или что-то не так с кодом?

<?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>

Мой последний запуск:

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

Ответы [ 2 ]

3 голосов
/ 09 января 2011

Ссылка AS3 прямо заявляет, что вы не можете сделать это:

Живой контент При потоковой передаче живого контента установите для свойства bufferTime значение 0.

Учитывая, что если вы сообщите нам, чего пытаетесь достичь, возможно, мы сможем предложить другое решение.

0 голосов
/ 15 декабря 2010

Еще одна мысль, но здесь речь пойдет о том, что внутренний механизм потоковой передачи Flash Player может отказаться буферизовать больше живых потоков, чем тот, который он считает «необходимым». Идея в том, что если у вас есть прямой эфир, у вас есть прямой эфир. В большинстве случаев задержка из-за буфера (например, видеочат один на один) была бы нелепой и действительно расстраивающей.

Этими вещами на самом деле можно управлять с сервера, но я могу ошибаться в этом. Надеюсь, вы сможете найти хорошее решение для этой проблемы: -)

...