private bool MQInternal_SendSeek(NetStream netStream, long seekTimeInMS) { int transactionNum = ++numInvokes; RTMPPacket packet = new RTMPPacket(); packet.Channel = netStream.CommandChannel; // 0x08 ??? packet.HeaderType = HeaderType.Medium; packet.PacketType = PacketType.Invoke; packet.TimeStamp = 0; packet.InfoField2 = 2; packet.HasAbsTimestamp = false; List<byte> enc = new List<byte>(); RTMPHelper.EncodeString(enc, "seek"); RTMPHelper.EncodeNumber(enc, transactionNum); enc.Add(0x05); // NULL RTMPHelper.EncodeNumber(enc, seekTimeInMS); // number of milliseconds to seek into playlist packet.Body = enc.ToArray(); packet.BodySize = (uint)enc.Count; LibRTMPLogger.Log(LibRTMPLogLevel.Trace, string.Format("[CDR.LibRTMP.NetConnection] Sending seek: ({0})", seekTimeInMS.ToString())); methodCallDictionary.Add(transactionNum, "seek"); return MQInternal_SendPacket(packet); }
/// <summary> /// Create a logical channel for message communication for use /// in publishing of audio or video and metadata carrying /// </summary> /// <returns></returns> public void CreateStream(NetStream ns) { MQ_RTMPMessage message = new MQ_RTMPMessage(); message.MethodCall = MethodCall.CreateStream; message.Params = new object[] { ns }; ; AddMessageToPump(message); }
private bool MQ_SendCloseStream(NetStream netStream) { RTMPPacket packet = new RTMPPacket(); packet.Channel = netStream.CommandChannel;// netStream.CommandChannel; or 0x03 both work!? packet.HeaderType = HeaderType.Large; packet.PacketType = PacketType.Invoke; packet.InfoField2 = netStream.Stream_ID; List<byte> enc = new List<byte>(); RTMPHelper.EncodeString(enc, "closeStream"); RTMPHelper.EncodeNumber(enc, 0); // 0 according to spec adobe enc.Add(0x05); // NULL packet.Body = enc.ToArray(); packet.BodySize = (uint)enc.Count; return MQInternal_SendPacket(packet); }
private bool MQInternal_SendPause(NetStream netStream, bool doPause) { int transactionNum = ++numInvokes; RTMPPacket packet = new RTMPPacket(); packet.Channel = netStream.CommandChannel; // 0x08 ??? packet.HeaderType = HeaderType.Medium; packet.PacketType = PacketType.Invoke; List<byte> enc = new List<byte>(); RTMPHelper.EncodeString(enc, "pause"); RTMPHelper.EncodeNumber(enc, transactionNum); enc.Add(0x05); // NULL RTMPHelper.EncodeBoolean(enc, doPause); RTMPHelper.EncodeNumber(enc, (double)channelTimestamp[netStream.MediaChannel]); packet.Body = enc.ToArray(); packet.BodySize = (uint)enc.Count; LibRTMPLogger.Log(LibRTMPLogLevel.Info, string.Format("[CDR.LibRTMP.NetConnection] Sending pause: ({0}), Time = {1}/{2}", doPause.ToString(), channelTimestamp[netStream.MediaChannel], TimeSpan.FromMilliseconds(Convert.ToInt32(channelTimestamp[netStream.MediaChannel])))); methodCallDictionary.Add(transactionNum, "pause"); return MQInternal_SendPacket(packet); }
private bool MQ_SendCreateStream(NetStream netStream) { int transactionNum = ++numInvokes; // Put netStream in transaction reference table so we can match it up when the rtmp server // give us the result back transactionIDReferenceTable[transactionNum] = netStream; RTMPPacket packet = new RTMPPacket(); packet.Channel = 0x03; // control channel (invoke) packet.HeaderType = HeaderType.Medium; packet.PacketType = PacketType.Invoke; LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "[CDR.LibRTMP.NetConnection] Sending createStream"); packet.AllocPacket(256); // should be enough List<byte> enc = new List<byte>(); RTMPHelper.EncodeString(enc, "createStream"); RTMPHelper.EncodeNumber(enc, transactionNum); enc.Add(0x05); // NULL packet.BodySize = (uint)enc.Count; packet.Body = enc.ToArray(); methodCallDictionary.Add(transactionNum, "createStream"); return MQInternal_SendPacket(packet); }
/// <summary> /// Stream_id checks "netStreams" /// Is orginal call pattern: private bool MQInternal_SendPlay(NetStream netStream, string mediafile, int start, int lenToPlay, bool resetPlayList, AMFObjectProperty properties) /// </summary> private bool MQInternal_SendPlay(NetStream netStream, string mediaFile, int start, int lenToPlay, bool resetPlayList, AMFObjectProperty properties) { RTMPPacket packet = new RTMPPacket(); packet.Channel = netStream.CommandChannel; // 0x08 ??? packet.HeaderType = HeaderType.Large; packet.PacketType = PacketType.Invoke; packet.InfoField2 = netStream.Stream_ID; List<byte> enc = new List<byte>(); RTMPHelper.EncodeString(enc, "play"); RTMPHelper.EncodeNumber(enc, 0); // 0 according to spec adobe enc.Add(0x05); // NULL RTMPHelper.EncodeString(enc, mediaFile); /* Optional parameters start and len. * * start: -2, -1, 0, positive number * -2: looks for a live stream, then a recorded stream, if not found any open a live stream * -1: plays a live stream * >=0: plays a recorded streams from 'start' milliseconds */ // RTMPHelper.EncodeNumber(enc, -1000.0d); (liveStream) if (start > 0) { RTMPHelper.EncodeNumber(enc, start); } else { RTMPHelper.EncodeNumber(enc, 0.0d); } // len: -1, 0, positive number // -1: plays live or recorded stream to the end (default) // 0: plays a frame 'start' ms away from the beginning // >0: plays a live or recoded stream for 'len' milliseconds RTMPHelper.EncodeNumber(enc, lenToPlay); // Reset. Optional wether to flush previous playlist if (properties == null) { RTMPHelper.EncodeBoolean(enc, resetPlayList); } else { properties.Encode(enc); } packet.Body = enc.ToArray(); packet.BodySize = (uint)enc.Count; LibRTMPLogger.Log(LibRTMPLogLevel.Trace, string.Format("[CDR.LibRTMP.NetConnection] Sending play: '{0}'", mediaFile)); return MQInternal_SendPacket(packet); }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] // hide it for code completion internal void UnRegisterNetStream(NetStream netStream) { if (netStream.Stream_ID >= 0 && netStreams[netStream.Stream_ID].Equals(netStream)) { // Unregister netStreams[netStream.Stream_ID] = null; } else { // Look for it if (netStream != null) { for (int i = netStreams.GetLowerBound(0); i < netStreams.GetUpperBound(0); i++) { if (netStream.Equals(netStreams[i])) { // Unregister netStreams[i] = null; } } //for i } } if (netStream != null && netStreamsList.Contains(netStream)) { netStreamsList.Remove(netStream); } }
private bool MQ_SendCall(NetStream netStream, string methodName, object[] values) { // Let's try to encode the values infpo AMF List<byte> enc = new List<byte>(); foreach (object value in values) { switch (value.GetType().ToString()) { case "System.Boolean": RTMPHelper.EncodeBoolean(enc, Convert.ToBoolean(value)); break; case "System.Byte": case "System.SByte": case "System.Decimal": case "System.Double": case "System.Single": case "System.Int32": case "System.UInt32": case "System.Int64": case "System.UInt64": case "System.Int16": case "System.UInt16": RTMPHelper.EncodeNumber(enc, Convert.ToDouble(value)); break; case "System.Char": case "System.String": RTMPHelper.EncodeString(enc, Convert.ToString(value)); break; case "System.Object": default: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, string.Format("[CDR.LibRTMP.NetConnection.MQ_SendCall] call(\"{0}\") parameter type not supported for encoding", methodName)); break; } //switch } //for int transactionNum = ++numInvokes; // needed incase there is a result which is send back // Put netStream in transaction reference table so we can match it up when the rtmp server // give us the result back transactionIDReferenceTable[transactionNum] = netStream; RTMPPacket packet = new RTMPPacket(); packet.Channel = 0x03; // control channel (invoke) packet.HeaderType = HeaderType.Medium; packet.PacketType = PacketType.Invoke; LibRTMPLogger.Log(LibRTMPLogLevel.Trace, string.Format("[CDR.LibRTMP.NetConnection] Sending call(\"{0}\")", methodName)); RTMPHelper.EncodeString(enc, methodName); RTMPHelper.EncodeNumber(enc, transactionNum); enc.Add(0x05); // NULL packet.BodySize = (uint)enc.Count; packet.Body = enc.ToArray(); methodCallDictionary.Add(transactionNum, methodName); return MQInternal_SendPacket(packet); }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] // hide it for code completion internal void RegisterNetStream(NetStream netStream) { if (netStream.Stream_ID >= 0 && netStreams[netStream.Stream_ID] == null) { netStreams[netStream.Stream_ID] = netStream; } if (!netStreamsList.Contains(netStream)) { netStreamsList.Add(netStream); } }
private void MQInternal_SetContentBufferTime(NetStream netStream, int contentBufferTime) { if (netStream.Stream_ID > 0 && contentBufferTime > 0) { SendPing(3, (uint)netStream.Stream_ID, (uint)contentBufferTime); } }
public void Close() { Stop(); if (NetStream != null) { NetStream.Close(); NetStream = null; } Buffer = null; }
// =========================================================================================================================================== protected NetStreamHelper FindNetStreamHelper(NetStream netStream) { // find sender in netStreams list! // Most of the time it takes only 1 loop to find the right netstream NetStreamHelper netStreamHelper = null; foreach (NetStreamHelper nth in netStreams) { if (nth.NetStream.Equals(netStream)) { netStreamHelper = nth; break; } } // foreach return netStreamHelper; }
public void Run() { zPlayBuffer = new CircularBlockBuffer(); zPlay = new ZPlay(); netConnection = new NetConnection(); netConnection.OnDisconnect += new NC_OnDisconnect(OnDisconnect); netConnection.OnTick += new NC_OnTick(NC_OnTick); try { int result = -1; // This is to connect to default vod app netConnection.Connect(new ServerLink("rtmp://localhost:1935/vod"), new NC_ResultCallBackConnect((sender, success) => { // Runs in RTMP thread (NOT MainThread!!!) Console.WriteLine("NetConnection.Connect => Success=" + success.ToString()); if (success) { result = 1; } else { result = 0; } })); // Wait until we are connected (needed because we run async) while (result == -1) { Thread.Sleep(100); } //while // Succes for connecting to rtmp server if (result == 1) { NetStream netStream = new NetStream(netConnection); netStream.OnStatus += new NS_OnStatus(NS_OnStatus); netStream.OnAudioPacket += new NC_OnMediaPacket(NC_OnMediaPacket); netStream.WaitForValidStream_ID(4000); // wait max 4 seconds for the netstream to become valid (for real test connect to event) // This is to get and MP3 stream netStream.Play("Comfort_Fit_-_03_-_Sorry.mp3", 0, -1, true); } Console.WriteLine("Press enter to stop."); Console.ReadLine(); } finally { // Cleanup if (netConnection != null) { netConnection.Close(); netConnection = null; } if (zPlay != null) { TStreamStatus status = new TStreamStatus(); zPlay.GetStatus(ref status); if (status.fPlay) { zPlay.StopPlayback(); } zPlay.Close(); zPlay = null; } if (zPlayBuffer != null) { zPlayBuffer = null; } } }