public void ReadLoop() { try { while (Continue) { var header = ReadHeader(); rtmpHeaders[header.StreamId] = header; RtmpPacket packet; if (!rtmpPackets.TryGetValue(header.StreamId, out packet) || packet == null) { packet = new RtmpPacket(header); rtmpPackets[header.StreamId] = packet; } var remainingMessageLength = packet.Length + (header.Timestamp >= 0xFFFFFF ? 4 : 0) - packet.CurrentLength; var bytesToRead = Math.Min(remainingMessageLength, readChunkSize); var bytes = reader.ReadBytes(bytesToRead); packet.AddBytes(bytes); if (packet.IsComplete) { rtmpPackets.Remove(header.StreamId); var @event = ParsePacket(packet); OnEventReceived(new EventReceivedEventArgs(@event)); // process some kinds of packets var chunkSizeMessage = @event as ChunkSize; if (chunkSizeMessage != null) { readChunkSize = chunkSizeMessage.Size; } var abortMessage = @event as Abort; if (abortMessage != null) { rtmpPackets.Remove(abortMessage.StreamId); } } } } catch (Exception ex) { #if DEBUG Debug.Print("Exception: {0} at {1}", ex, ex.StackTrace); if (ex.InnerException != null) { var inner = ex.InnerException; Debug.Print("InnerException: {0} at {1}", inner, inner.StackTrace); } #endif OnDisconnected(new ExceptionalEventArgs("rtmp-packet-reader", ex)); } }
private RtmpEvent ParsePacket(RtmpPacket packet) { switch (packet.Header.MessageType) { case MessageType.SetChunkSize: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new ChunkSize(r.ReadInt32())))); case MessageType.AbortMessage: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new Abort(r.ReadInt32())))); case MessageType.Acknowledgement: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new Acknowledgement(r.ReadInt32())))); case MessageType.UserControlMessage: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => { ushort num = r.ReadUInt16(); List <int> intList = new List <int>(); while (r.Length - r.Position >= 4L) { intList.Add(r.ReadInt32()); } return (RtmpEvent) new UserControlMessage((UserControlMessageType)num, intList.ToArray()); }))); case MessageType.WindowAcknowledgementSize: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new WindowAcknowledgementSize(r.ReadInt32())))); case MessageType.SetPeerBandwidth: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new PeerBandwidth(r.ReadInt32(), r.ReadByte())))); case MessageType.Audio: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new AudioData(packet.Buffer)))); case MessageType.Video: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => (RtmpEvent) new VideoData(packet.Buffer)))); case MessageType.DataAmf3: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => RtmpPacketReader.ReadCommandOrData(r, (Command) new NotifyAmf3())))); case MessageType.CommandAmf3: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => { int num = (int)r.ReadByte(); return RtmpPacketReader.ReadCommandOrData(r, (Command) new InvokeAmf3()); }))); case MessageType.DataAmf0: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => RtmpPacketReader.ReadCommandOrData(r, (Command) new NotifyAmf0())))); case MessageType.CommandAmf0: return(this.ParsePacket(packet, (Func <AmfReader, RtmpEvent>)(r => RtmpPacketReader.ReadCommandOrData(r, (Command) new InvokeAmf0())))); default: return((RtmpEvent)null); } }
public void ReadLoop() { try { while (Continue) { var header = ReadHeader(); rtmpHeaders[header.StreamId] = header; RtmpPacket packet; if (!rtmpPackets.TryGetValue(header.StreamId, out packet) || packet == null) { packet = new RtmpPacket(header); rtmpPackets[header.StreamId] = packet; } var remainingMessageLength = packet.Length + (header.Timestamp >= 0xFFFFFF ? 4 : 0) - packet.CurrentLength; var bytesToRead = Math.Min(remainingMessageLength, readChunkSize); var bytes = reader.ReadBytes(bytesToRead); packet.AddBytes(bytes); if (packet.IsComplete) { rtmpPackets.Remove(header.StreamId); var @event = ParsePacket(packet); OnEventReceived(new EventReceivedEventArgs(@event)); // process some kinds of packets var chunkSizeMessage = @event as ChunkSize; if (chunkSizeMessage != null) readChunkSize = chunkSizeMessage.Size; var abortMessage = @event as Abort; if (abortMessage != null) rtmpPackets.Remove(abortMessage.StreamId); } } } catch (Exception ex) { if (!Continue) return; #if DEBUG System.Diagnostics.Debug.Print("Exception: {0} at {1}", ex, ex.StackTrace); if (ex.InnerException != null) { var inner = ex.InnerException; System.Diagnostics.Debug.Print("InnerException: {0} at {1}", inner, inner.StackTrace); } #endif OnDisconnected(new ExceptionalEventArgs("rtmp-packet-reader", ex)); } }
public void Queue(RtmpEvent message, int streamId, int messageStreamId) { var header = new RtmpHeader(); var packet = new RtmpPacket(header, message); header.StreamId = 0; header.Timestamp = message.Timestamp; header.MessageStreamId = messageStreamId; header.MessageType = message.MessageType; queuedPackets.Enqueue(packet); packetAvailableEvent.Set(); }
RtmpEvent ParsePacket(RtmpPacket packet, Func <AmfReader, RtmpEvent> handler) { var memoryStream = new MemoryStream(packet.Buffer, false); var packetReader = new AmfReader(memoryStream, reader.SerializationContext); var header = packet.Header; var message = handler(packetReader); message.Header = header; message.Timestamp = header.Timestamp; return(message); }
FlvPacket RtmpPacketToFlvPacket(RtmpPacket rtmp_packet) { var rtmp_header = rtmp_packet.Header; var header = new FlvTagHeader(); header.StreamId = 0; header.TagType = rtmp_header.MessageType; header.Timestamp = rtmp_header.Timestamp; var packet = new FlvPacket(header); packet.Body = rtmp_packet.Body; return(packet); }
private RtmpEvent ParsePacket(RtmpPacket packet, Func <AmfReader, RtmpEvent> handler) { AmfReader amfReader = new AmfReader((Stream) new MemoryStream(packet.Buffer, false), this._reader.SerializationContext); RtmpHeader header = packet.Header; RtmpEvent rtmpEvent = handler(amfReader); RtmpHeader rtmpHeader = header; rtmpEvent.Header = rtmpHeader; int timestamp = header.Timestamp; rtmpEvent.Timestamp = timestamp; return(rtmpEvent); }
public void Queue(RtmpEvent message, int streamId, int messageStreamId) { var header = new RtmpHeader(); var packet = new RtmpPacket(header, message); header.StreamId = streamId; header.Timestamp = message.Timestamp; header.MessageStreamId = messageStreamId; header.MessageType = message.MessageType; if (message.Header != null) header.IsTimerRelative = message.Header.IsTimerRelative; queuedPackets.Enqueue(packet); packetAvailableEvent.Set(); }
void WritePacket(RtmpPacket packet) { var flv_packet = RtmpPacketToFlvPacket(packet); var header = flv_packet.Header; var streamId = header.StreamId; var message = flv_packet.Body; var buffer = GetMessageBytes(header, message); header.DataSize = buffer.Length; WriteTagHeader(header); writer.Write(buffer); WritePrevTagLength(buffer); }
public void ReadLoop() { try { while (Continue) { var header = ReadHeader(); rtmpHeaders[header.StreamId] = header; RtmpPacket packet; if (!rtmpPackets.TryGetValue(header.StreamId, out packet) || packet == null) { packet = new RtmpPacket(header); rtmpPackets[header.StreamId] = packet; } var remainingMessageLength = packet.Length + (header.Timestamp >= 0xFFFFFF ? 4 : 0) - packet.CurrentLength; var bytesToRead = Math.Min(remainingMessageLength, readChunkSize); var bytes = reader.ReadBytes(bytesToRead); packet.AddBytes(bytes); if (packet.IsComplete) { rtmpPackets.Remove(header.StreamId); var @event = ParsePacket(packet); OnEventReceived(new EventReceivedEventArgs(@event)); // process some kinds of packets var chunkSizeMessage = @event as ChunkSize; if (chunkSizeMessage != null) readChunkSize = chunkSizeMessage.Size; var abortMessage = @event as Abort; if (abortMessage != null) rtmpPackets.Remove(abortMessage.StreamId); } } } catch (Exception ex) { #if DEBUG && WITH_KONSEKI Kon.DebugException($"exception occurred", ex); #endif OnDisconnected(new ExceptionalEventArgs("rtmp-packet-reader", ex)); } }
public void Queue(RtmpEvent message, int streamId, int messageStreamId) { RtmpHeader header = new RtmpHeader(); RtmpPacket rtmpPacket = new RtmpPacket(header, message); header.StreamId = streamId; header.Timestamp = message.Timestamp; header.MessageStreamId = messageStreamId; header.MessageType = message.MessageType; if (message.Header != null) { header.IsTimerRelative = message.Header.IsTimerRelative; } this._queuedPackets.Enqueue(rtmpPacket); this._packetAvailableEvent.Set(); }
public void Queue(RtmpEvent message, int streamId, int messageStreamId) { var header = new RtmpHeader(); var packet = new RtmpPacket(header, message); header.StreamId = streamId; header.Timestamp = message.Timestamp; header.MessageStreamId = messageStreamId; header.MessageType = message.MessageType; if (message.Header != null) { header.IsTimerRelative = message.Header.IsTimerRelative; } queuedPackets.Enqueue(packet); // packetAvailableEvent.Set(); Interlocked.Exchange(ref packetAvailable, 1); }
public bool ReadOnce() { var header = ReadHeader(); if (header == null) { return(false); } rtmpHeaders[header.StreamId] = header; RtmpPacket packet; if (!rtmpPackets.TryGetValue(header.StreamId, out packet) || packet == null) { packet = new RtmpPacket(header); rtmpPackets[header.StreamId] = packet; } var remainingMessageLength = packet.Length + (header.Timestamp >= 0xFFFFFF ? 4 : 0) - packet.CurrentLength; var bytesToRead = Math.Min(remainingMessageLength, readChunkSize); var bytes = reader.ReadBytes(bytesToRead); packet.AddBytes(bytes); if (packet.IsComplete) { rtmpPackets.Remove(header.StreamId); var @event = ParsePacket(packet); OnEventReceived(new EventReceivedEventArgs(@event)); // process some kinds of packets var chunkSizeMessage = @event as ChunkSize; if (chunkSizeMessage != null) { readChunkSize = chunkSizeMessage.Size; } var abortMessage = @event as Abort; if (abortMessage != null) { rtmpPackets.Remove(abortMessage.StreamId); } } return(true); }
void WritePacket(RtmpPacket packet) { //Debugger.Break(); var header = packet.Header; var streamId = header.StreamId; var message = packet.Body; var buffer = GetMessageBytes(header, message); header.PacketLength = buffer.Length; RtmpHeader previousHeader; rtmpHeaders.TryGetValue(streamId, out previousHeader); rtmpHeaders[streamId] = header; rtmpPackets[streamId] = packet; WriteMessageHeader(header, previousHeader); var first = true; for (int i = 0; i < header.PacketLength; i += writeChunkSize) { if (!first) { WriteBasicHeader(ChunkMessageHeaderType.Continuation, header.StreamId); } var bytesToWrite = i + writeChunkSize > header.PacketLength ? header.PacketLength - i : writeChunkSize; writer.Write(buffer, i, bytesToWrite); first = false; } var chunkSizeMsg = message as ChunkSize; if (chunkSizeMsg != null) { writeChunkSize = chunkSizeMsg.Size; } }
public void ReadLoop() { try { while (this.Continue) { RtmpHeader header = this.ReadHeader(); this._rtmpHeaders[header.StreamId] = header; RtmpPacket packet1; if (!this._rtmpPackets.TryGetValue(header.StreamId, out packet1) || packet1 == null) { packet1 = new RtmpPacket(header); this._rtmpPackets[header.StreamId] = packet1; } byte[] bytes = this._reader.ReadBytes(Math.Min(packet1.Length + (header.Timestamp >= 16777215 ? 4 : 0) - packet1.CurrentLength, this._readChunkSize)); packet1.AddBytes(bytes); if (packet1.IsComplete) { this._rtmpPackets.Remove(header.StreamId); RtmpEvent packet2 = this.ParsePacket(packet1); this.OnEventReceived(new EventReceivedEventArgs(packet2)); ChunkSize chunkSize = packet2 as ChunkSize; if (chunkSize != null) { this._readChunkSize = chunkSize.Size; } Abort abort = packet2 as Abort; if (abort != null) { this._rtmpPackets.Remove(abort.StreamId); } } } } catch (Exception ex) { this.OnDisconnected(new ExceptionalEventArgs("rtmp-packet-reader", ex)); } }
private void WritePacket(RtmpPacket packet) { RtmpHeader header = packet.Header; int streamId = header.StreamId; RtmpEvent body = packet.Body; byte[] messageBytes = this.GetMessageBytes(header, body); header.PacketLength = messageBytes.Length; RtmpHeader previousHeader; this._rtmpHeaders.TryGetValue(streamId, out previousHeader); this._rtmpHeaders[streamId] = header; this._rtmpPackets[streamId] = packet; this.WriteMessageHeader(header, previousHeader); bool flag = true; int index = 0; while (index < header.PacketLength) { if (!flag) { this.WriteBasicHeader(ChunkMessageHeaderType.Continuation, header.StreamId); } int count = index + this._writeChunkSize > header.PacketLength ? header.PacketLength - index : this._writeChunkSize; this._writer.Write(messageBytes, index, count); flag = false; index += this._writeChunkSize; } ChunkSize chunkSize = body as ChunkSize; if (chunkSize == null) { return; } this._writeChunkSize = chunkSize.Size; }
RtmpEvent ParsePacket(RtmpPacket packet) { switch (packet.Header.MessageType) { case MessageType.SetChunkSize: return(ParsePacket(packet, r => new ChunkSize(r.ReadInt32()))); case MessageType.AbortMessage: return(ParsePacket(packet, r => new Abort(r.ReadInt32()))); case MessageType.Acknowledgement: return(ParsePacket(packet, r => new Acknowledgement(r.ReadInt32()))); case MessageType.UserControlMessage: return(ParsePacket(packet, r => { var eventType = r.ReadUInt16(); var values = new List <int>(); while (r.Length - r.Position >= 4) { values.Add(r.ReadInt32()); } return new UserControlMessage((UserControlMessageType)eventType, values.ToArray()); })); case MessageType.WindowAcknowledgementSize: return(ParsePacket(packet, r => new WindowAcknowledgementSize(r.ReadInt32()))); case MessageType.SetPeerBandwidth: return(ParsePacket(packet, r => new PeerBandwidth(r.ReadInt32(), r.ReadByte()))); case MessageType.Audio: return(ParsePacket(packet, r => new AudioData(packet.Buffer))); case MessageType.Video: return(ParsePacket(packet, r => new VideoData(packet.Buffer))); case MessageType.DataAmf0: return(ParsePacket(packet, r => ReadCommandOrData(r, new NotifyAmf0()))); case MessageType.SharedObjectAmf0: break; case MessageType.CommandAmf0: return(ParsePacket(packet, r => ReadCommandOrData(r, new InvokeAmf0()))); case MessageType.DataAmf3: return(ParsePacket(packet, r => ReadCommandOrData(r, new NotifyAmf3()))); case MessageType.SharedObjectAmf3: break; case MessageType.CommandAmf3: return(ParsePacket(packet, r => { // encoding? always seems to be zero var unk1 = r.ReadByte(); return ReadCommandOrData(r, new InvokeAmf3()); })); // Aggregated messages only seem to be used in audio and video streams, so we should be OK until we need multimedia. // case MessageType.Aggregate: default: #if DEBUG && RTMP_SHARP_DEV // Find out how to handle this message type. System.Diagnostics.Debugger.Break(); #endif break; } // Skip messages we don't understand return(null); }
RtmpEvent ParsePacket(RtmpPacket packet) { switch (packet.Header.MessageType) { case MessageType.SetChunkSize: return ParsePacket(packet, r => new ChunkSize(r.ReadInt32())); case MessageType.AbortMessage: return ParsePacket(packet, r => new Abort(r.ReadInt32())); case MessageType.Acknowledgement: return ParsePacket(packet, r => new Acknowledgement(r.ReadInt32())); case MessageType.UserControlMessage: return ParsePacket(packet, r => { var eventType = r.ReadUInt16(); var values = new List<int>(); while (r.Length - r.Position >= 4) values.Add(r.ReadInt32()); return new UserControlMessage((UserControlMessageType)eventType, values.ToArray()); }); case MessageType.WindowAcknowledgementSize: return ParsePacket(packet, r => new WindowAcknowledgementSize(r.ReadInt32())); case MessageType.SetPeerBandwith: return ParsePacket(packet, r => new PeerBandwith(r.ReadInt32(), r.ReadByte())); case MessageType.Audio: return ParsePacket(packet, r => new AudioData(packet.Buffer)); case MessageType.Video: return ParsePacket(packet, r => new VideoData(packet.Buffer)); case MessageType.DataAmf0: return ParsePacket(packet, r => ReadCommandOrData(r, new NotifyAmf0())); case MessageType.SharedObjectAmf0: break; case MessageType.CommandAmf0: return ParsePacket(packet, r => ReadCommandOrData(r, new InvokeAmf0())); case MessageType.DataAmf3: return ParsePacket(packet, r => ReadCommandOrData(r, new NotifyAmf3())); case MessageType.SharedObjectAmf3: break; case MessageType.CommandAmf3: return ParsePacket(packet, r => { // encoding? always seems to be zero var unk1 = r.ReadByte(); return ReadCommandOrData(r, new InvokeAmf3()); }); // Aggregated messages only seem to be used in audio and video streams, so we should be OK until we need multimedia. // case MessageType.Aggregate: default: #if DEBUG && RTMP_SHARP_DEV // Find out how to handle this message type. System.Diagnostics.Debugger.Break(); #endif break; } // Skip messages we don't understand return null; }
RtmpEvent ParsePacket(RtmpPacket packet, Func<AmfReader, RtmpEvent> handler) { var memoryStream = new MemoryStream(packet.Buffer, false); var packetReader = new AmfReader(memoryStream, reader.SerializationContext, reader.DeserializeToObjects, reader.DeserializeToDynamicWhenTypeNotFound); var header = packet.Header; var message = handler(packetReader); message.Header = header; message.Timestamp = header.Timestamp; return message; }
void WritePacket(RtmpPacket packet) { var header = packet.Header; var streamId = header.StreamId; var message = packet.Body; var buffer = GetMessageBytes(header, message); header.PacketLength = buffer.Length; RtmpHeader previousHeader; rtmpHeaders.TryGetValue(streamId, out previousHeader); rtmpHeaders[streamId] = header; rtmpPackets[streamId] = packet; WriteMessageHeader(header, previousHeader); var first = true; for (int i = 0; i < header.PacketLength; i += writeChunkSize) { if (!first) WriteBasicHeader(ChunkMessageHeaderType.Continuation, header.StreamId); var bytesToWrite = i + writeChunkSize > header.PacketLength ? header.PacketLength - i : writeChunkSize; writer.Write(buffer, i, bytesToWrite); first = false; } var chunkSizeMsg = message as ChunkSize; if (chunkSizeMsg != null) writeChunkSize = chunkSizeMsg.Size; }
RtmpEvent ParsePacket(RtmpPacket packet, Func<AmfReader, RtmpEvent> handler) { var memoryStream = new MemoryStream(packet.Buffer, false); var packetReader = new AmfReader(memoryStream, reader.SerializationContext); var header = packet.Header; var message = handler(packetReader); message.Header = header; message.Timestamp = header.Timestamp; return message; }