/// <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); }
/// <summary> /// Deep copy! /// </summary> public object Clone() { AMFObjectProperty clone = new AMFObjectProperty(); clone.stringName = stringName; clone.type = type; clone.numVal = numVal; if (objVal != null) { clone.objVal = (AMFObject)objVal.Clone(); } clone.stringVal = stringVal; clone.dateUTCOffset = dateUTCOffset; clone.date = date; 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; }