Beispiel #1
0
        /// <summary>
        /// Deep clone
        /// </summary>
        public object Clone()
        {
            NetStreamStatusEvent clone = new NetStreamStatusEvent();

            clone.Event     = Event;
            clone.Code      = Code;
            clone.Level     = Level;
            clone.EventInfo = (AMFObject)EventInfo.Clone();

            return(clone);
        }
        protected void NS_OnStatus(object sender, NetStreamStatusEvent netStreamStatusEvent)
        {
            NetStreamHelper netStreamHelper = FindNetStreamHelper(sender as NetStream);
            if (netStreamHelper != null)
            {
                switch (netStreamStatusEvent.Code)
                {
                    case "NetStream.Play.Stop": // start buffering next mediaitem?
                        if (!netStreamHelper.NetStream.SeekIsActive && !netStreamHelper.IsComplete)
                        {
                            commandInProgress = false; // reset it
                            netStreamHelper.IsComplete = true;
                        }
                        // possible button state changed
                        DoEvent_MP_OnControleButtonStateChange(OnControleButtonStateChange, this);
                        break;
                    case "NetStream.Play.OnMetaData":
                        lock (lockVAR)
                        {
                            netStreamHelper.Item.NetStreamDurationInMS = Convert.ToInt64(netStreamHelper.NetStream.Duration * 1000);
                        }
                        break;
                    case "NetStream.Play.Start":
                    case "NetStream.Play.Resume":
                        failedPlayCount = 0; // reset
                        commandInProgress = false; // reset it after Play command
                        // Do not set PlayState from Seek to Playing, otherwise 
                        // call to "StartPlayingAudioChannel" won't start playing audio again!
                        // "StartPlayingAudioChannel" is called from "NC_OnMediaPacket"
                        // so playing will start when there is data in the buffer

                        MP_OnMediaItem onMediaItemSeekEnd = null;
                        MediaItem item = null;
                        lock (lockVAR)
                        {
                            if (netStreams.Count > 0 && netStreams[0].PlayState == NetStreamState.Seek)
                            {
                                if (OnMediaItemSeekEnd != null)
                                {
                                    // We're playing
                                    onMediaItemSeekEnd = OnMediaItemSeekEnd;
                                    item = (MediaItem)netStreams[0].Item.Clone();
                                }
                            }
                        } //lock
                        DoEvent_MP_OnMediaItem(onMediaItemSeekEnd, this, item);
                        // possible button state changed
                        DoEvent_MP_OnControleButtonStateChange(OnControleButtonStateChange, this);
                        break;
                    case "NetStream.Seek.Notify":
                        // wait for "NetStream.Play.Start"
                        // Flush buffer once more (because packets could be stored between call en send to remote server
                        if (netStreamHelper.Buffer != null)
                        {
                            netStreamHelper.Buffer.Clear();
                        }
                        // Should already be set to this!
                        netStreamHelper.PlayState = NetStreamState.Seek;
                        // possible button state changed
                        DoEvent_MP_OnControleButtonStateChange(OnControleButtonStateChange, this);
                        break;
                    case "NetStream.Pause.Notify":
                        commandInProgress = false; // reset it after seek command
                        // possible button state changed
                        DoEvent_MP_OnControleButtonStateChange(OnControleButtonStateChange, this);
                        break;

                    case "NetStream.Play.Failed": // event when playing fails and we have to skip to the next one
                    case "NetStream.Play.StreamNotFound":
                    case "NetStream.Failed":
                        failedPlayCount++;

                        // Fake status so Next and stop work
                        lock (lockVAR)
                        {
                            if (netStreams.Count == 1)
                            {
                                netStreams[0].Item.SkipBecauseOfError = true;
                                netStreams[0].PlayState = NetStreamState.Playing;
                            }
                            else if (netStreams.Count > 1)
                            {
                                NetStreamHelper nsh = netStreams[netStreams.Count - 1];
                                netStreams.RemoveAt(netStreams.Count - 1);
                                netStreams[netStreams.Count - 1].NextNetStreamStarted = false;

                                nsh.Item.SkipBecauseOfError = true;
                                CloseAudioStream(nsh);

                                MPThread_CheckForPreBuffering();
                                break;
                            }
                        } //lock

                        if (currentPlaylist.NextMediaItemIndex != -1 && failedPlayCount <= 10)
                        {
                            // Continue with next one if there is one!
                            MPThread_Next();
                        }
                        else
                        {
                            // stop playing, 10 consecutive fails 
                            MPThread_Stop();
                        }
                        break;
                } //switch
            }
        }
        /// <summary>
        /// Deep clone
        /// </summary>
        public object Clone()
        {
            NetStreamStatusEvent clone = new NetStreamStatusEvent();
            clone.Event = Event;
            clone.Code = Code;
            clone.Level = Level;
            clone.EventInfo = (AMFObject)EventInfo.Clone();

            return clone;
        }
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] // hide it for code completion
        virtual protected bool Internal_HandleOnStatusDecoded(RTMPPacket packet, string eventStr, string codeStr, string levelStr, AMFObject obj)
        {
            //LibRTMPLogger.Log(LibRTMPLogLevel.Error, string.Format("[CDR.LibRTMP.NetStream.Internal_HandleOnStatusDecoded] event={0} code={1} level={2} Timestamp={3}", eventStr, codeStr, levelStr, packet.TimeStamp));
            //Console.WriteLine(string.Format("event={0} code={1} level={2} Timestamp={3} seekIsActive={4}", eventStr, codeStr, levelStr, packet.TimeStamp, seekIsActive.ToString()));

            if (OnStatus != null)
            {
                NetStreamStatusEvent netStreamStatusEvent = new NetStreamStatusEvent();
                netStreamStatusEvent.Clear();
                netStreamStatusEvent.Event = eventStr;
                netStreamStatusEvent.Code = codeStr;
                netStreamStatusEvent.Level = levelStr;
                netStreamStatusEvent.EventInfo = (AMFObject)obj.Clone(); // for thread safety

                MQ_RTMPMessage message = new MQ_RTMPMessage();
                message.MethodCall = MethodCall.OnEventCallUserCode;
                message.Params = new object[] { OnStatus, this, netStreamStatusEvent };
                netConnection.PostOnEventUserCallCodeMessage(message);
            }

            // Make sure we point to the right record which is buffered!
            if (codeStr == "NetStream.Play.Switch")
            {
                // end of stream (adjust duration to correct for inaccuracy!)
                lock (lockVAR)
                {
                    seekIsActive = false;
                } //lock
            }

            // Now do our thing
            switch (codeStr)
            {
                // We need to flush the existing buffers and wait until 
                // new data arrives
                case "NetStream.Seek.Notify":
                    lock (lockVAR)
                    {
                        seekIsActive = true; // is probably already set
                        blockMediaPackets++;
                        deltaTimeStampInMS = packet.TimeStamp;
                    }

                    Internal_OnSeekNotify(packet.TimeStamp);
                    break;

                case "NetStream.Play.Reset": // send when playlist starts at the beginning
                    lock (lockVAR)
                    {
                        atBeginOfAudio = true;
                        mediaBytesReceived = 0;
                        deltaTimeStampInMS = 0;
                    } //lock
                    break;

                case "NetStream.Play.Switch":
                    // Tell we have to stop playing (and drain the buffers!)
                    if (mediaBytesReceived > 0) // only when we are streaming already
                    {
                        blockMediaPackets++;
                    }
                    break;
                case "NetStream.Data.Start":
                    mediaBytesReceived = 0;
                    break;

                // stream begins to play (that is data is send)
                // deblock if needed
                case "NetStream.Play.Start":
                    lock (lockVAR)
                    {
                        if (blockMediaPackets > 0)
                        {
                            blockMediaPackets--;
                        }
                        seekIsActive = false; // is probably already set
                    } //lock
                    break;
                case "NetStream.Play.Stop":
                    ReplaySavedPackets(); // needed in case packets where saved (we're at the end so a byte sync will not occure anymore)
                    lock (lockVAR)
                    {
                        atBeginOfAudio = true;
                    }
                    break;

                // Pause logic
                case "NetStream.Pause.Notify":
                    ReplaySavedPackets(); // needed in case packets where saved (we're at the end so a byte sync will not occure anymore)
                    lock (lockVAR)
                    {
                        if (mediaBytesReceived > 0) // we're buffering
                        {
                            pauseIsActive = true;
                            Internal_OnPauseStream(true);
                            if (OnPauseStream != null)
                            {
                                MQ_RTMPMessage message = new MQ_RTMPMessage();
                                message.MethodCall = MethodCall.OnEventCallUserCode;
                                message.Params = new object[] { OnPauseStream, this, true };
                                netConnection.PostOnEventUserCallCodeMessage(message);
                            }
                        }
                    } //lock
                    break;
                case "NetStream.Unpause.Notify":
                    lock (lockVAR)
                    {
                        syncAfterPauseNeeded = true;
                        pauseIsActive = false;
                        Internal_OnPauseStream(false);
                        if (OnPauseStream != null)
                        {
                            MQ_RTMPMessage message = new MQ_RTMPMessage();
                            message.MethodCall = MethodCall.OnEventCallUserCode;
                            message.Params = new object[] { OnPauseStream, this, false };
                            netConnection.PostOnEventUserCallCodeMessage(message);
                        }
                    } //lock
                    break;

                case "NetStream.Play.Failed":
                case "NetStream.Play.StreamNotFound":
                case "NetStream.Failed":
                    break;
                case "NetStream.Play.Complete": // all data is send
                    lock (lockVAR)
                    {
                        seekIsActive = false; // safety
                    }
                    break;

            } //switch

            // Code can be eg:
            // "NetStream.Failed"
            // "NetStream.Play.Failed" 
            // "NetStream.Play.StreamNotFound" 
            // "NetConnection.Connect.InvalidApp"
            // "NetStream.Play.Start"
            // "NetStream.Publish.Start"
            // "NetStream.Play.Complete" //audio
            // "NetStream.Play.Stop"     // audio
            // "NetStream.Pause.Notify"
            // "NetStream.Seek.Notify"

            return true;
        }
Beispiel #5
0
 private void NS_OnStatus(object sender, NetStreamStatusEvent netStreamStatusEvent)
 {
     if (netStreamStatusEvent.Code == "NetStream.Play.Complete")
     {
         Console.WriteLine("RTMP NetStream has ended sending data. (Audio playing will stop some time later)");
     }
 }