private RtmpHeader ReadHeader() { int num1 = (int)this._reader.ReadByte(); AmfReader reader = this._reader; int chunkStreamId = RtmpPacketReader.GetChunkStreamId((byte)num1, reader); int num2 = 6; ChunkMessageHeaderType messageHeaderType = (ChunkMessageHeaderType)(num1 >> num2); RtmpHeader rtmpHeader1 = new RtmpHeader(); rtmpHeader1.StreamId = chunkStreamId; int num3 = (uint)messageHeaderType > 0U ? 1 : 0; rtmpHeader1.IsTimerRelative = num3 != 0; RtmpHeader rtmpHeader2 = rtmpHeader1; RtmpHeader rtmpHeader3; if (!this._rtmpHeaders.TryGetValue(chunkStreamId, out rtmpHeader3) && messageHeaderType != ChunkMessageHeaderType.New) { rtmpHeader3 = rtmpHeader2.Clone(); } switch (messageHeaderType) { case ChunkMessageHeaderType.New: rtmpHeader2.Timestamp = this._reader.ReadUInt24(); rtmpHeader2.PacketLength = this._reader.ReadUInt24(); rtmpHeader2.MessageType = (MessageType)this._reader.ReadByte(); rtmpHeader2.MessageStreamId = this._reader.ReadReverseInt(); break; case ChunkMessageHeaderType.SameSource: rtmpHeader2.Timestamp = this._reader.ReadUInt24(); rtmpHeader2.PacketLength = this._reader.ReadUInt24(); rtmpHeader2.MessageType = (MessageType)this._reader.ReadByte(); rtmpHeader2.MessageStreamId = rtmpHeader3.MessageStreamId; break; case ChunkMessageHeaderType.TimestampAdjustment: rtmpHeader2.Timestamp = this._reader.ReadUInt24(); rtmpHeader2.PacketLength = rtmpHeader3.PacketLength; rtmpHeader2.MessageType = rtmpHeader3.MessageType; rtmpHeader2.MessageStreamId = rtmpHeader3.MessageStreamId; break; case ChunkMessageHeaderType.Continuation: rtmpHeader2.Timestamp = rtmpHeader3.Timestamp; rtmpHeader2.PacketLength = rtmpHeader3.PacketLength; rtmpHeader2.MessageType = rtmpHeader3.MessageType; rtmpHeader2.MessageStreamId = rtmpHeader3.MessageStreamId; rtmpHeader2.IsTimerRelative = rtmpHeader3.IsTimerRelative; break; default: throw new SerializationException("Unexpected header type: " + (object)(int)messageHeaderType); } if (rtmpHeader2.Timestamp == 16777215) { rtmpHeader2.Timestamp = this._reader.ReadInt32(); } return(rtmpHeader2); }
static RtmpEvent ReadCommandOrData(AmfReader r, Command command, RtmpHeader header = null) { var methodName = (string)r.ReadAmf0Item(); object temp = r.ReadAmf0Item(); if (header != null && methodName == "@setDataFrame") { command.ConnectionParameters = temp; } else { command.InvokeId = Convert.ToInt32(temp); command.ConnectionParameters = r.ReadAmf0Item(); } var parameters = new List <object>(); while (r.DataAvailable) { parameters.Add(r.ReadAmf0Item()); } command.MethodCall = new Method(methodName, parameters.ToArray()); return(command); }
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(); }
private static ChunkMessageHeaderType GetMessageHeaderType(RtmpHeader header, RtmpHeader previousHeader) { if (previousHeader == null || header.MessageStreamId != previousHeader.MessageStreamId || !header.IsTimerRelative) { return(ChunkMessageHeaderType.New); } if (header.PacketLength != previousHeader.PacketLength || header.MessageType != previousHeader.MessageType) { return(ChunkMessageHeaderType.SameSource); } return(header.Timestamp == previousHeader.Timestamp ? ChunkMessageHeaderType.Continuation : ChunkMessageHeaderType.TimestampAdjustment); }
static ChunkMessageHeaderType GetMessageHeaderType(RtmpHeader header, RtmpHeader previousHeader) { if (previousHeader == null || header.MessageStreamId != previousHeader.MessageStreamId || !header.IsTimerRelative) return ChunkMessageHeaderType.New; if (header.PacketLength != previousHeader.PacketLength || header.MessageType != previousHeader.MessageType) return ChunkMessageHeaderType.SameSource; if (header.Timestamp != previousHeader.Timestamp) return ChunkMessageHeaderType.TimestampAdjustment; return ChunkMessageHeaderType.Continuation; }
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(); }
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); }
void WriteMessageHeaderAsync(RtmpHeader header, RtmpHeader previousHeader) { var headerType = GetMessageHeaderType(header, previousHeader); WriteBasicHeaderAsync(headerType, header.StreamId); var uint24Timestamp = header.Timestamp < 0xFFFFFF ? header.Timestamp : 0xFFFFFF; switch (headerType) { case ChunkMessageHeaderType.New: writer.WriteUInt24Async(uint24Timestamp); writer.WriteUInt24Async(header.PacketLength); writer.WriteByteAsync((byte)header.MessageType); writer.WriteReverseIntAsync(header.MessageStreamId); break; case ChunkMessageHeaderType.SameSource: writer.WriteUInt24Async(uint24Timestamp); writer.WriteUInt24Async(header.PacketLength); writer.WriteByteAsync((byte)header.MessageType); break; case ChunkMessageHeaderType.TimestampAdjustment: writer.WriteUInt24Async(uint24Timestamp); break; case ChunkMessageHeaderType.Continuation: break; default: throw new ArgumentException("headerType"); } if (uint24Timestamp >= 0xFFFFFF) { writer.WriteInt32Async(header.Timestamp); } }
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 WriteMessageHeader(RtmpHeader header, RtmpHeader previousHeader) { ChunkMessageHeaderType messageHeaderType = RtmpPacketWriter.GetMessageHeaderType(header, previousHeader); this.WriteBasicHeader(messageHeaderType, header.StreamId); int num = header.Timestamp < 16777215 ? header.Timestamp : 16777215; switch (messageHeaderType) { case ChunkMessageHeaderType.New: this._writer.WriteUInt24(num); this._writer.WriteUInt24(header.PacketLength); this._writer.WriteByte((byte)header.MessageType); this._writer.WriteReverseInt(header.MessageStreamId); goto case ChunkMessageHeaderType.Continuation; case ChunkMessageHeaderType.SameSource: this._writer.WriteUInt24(num); this._writer.WriteUInt24(header.PacketLength); this._writer.WriteByte((byte)header.MessageType); goto case ChunkMessageHeaderType.Continuation; case ChunkMessageHeaderType.TimestampAdjustment: this._writer.WriteUInt24(num); goto case ChunkMessageHeaderType.Continuation; case ChunkMessageHeaderType.Continuation: if (num < 16777215) { break; } this._writer.WriteInt32(header.Timestamp); break; default: throw new ArgumentException("headerType"); } }
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; }
RtmpHeader ReadHeader() { // first byte of the chunk basic header var chunkBasicHeaderByte = reader.ReadByte(); var chunkStreamId = GetChunkStreamId(chunkBasicHeaderByte, reader); var chunkMessageHeaderType = (ChunkMessageHeaderType)(chunkBasicHeaderByte >> 6); var header = new RtmpHeader() { StreamId = chunkStreamId, IsTimerRelative = chunkMessageHeaderType != ChunkMessageHeaderType.New }; RtmpHeader previousHeader; // don't need to clone if new header, as it contains all info if (!rtmpHeaders.TryGetValue(chunkStreamId, out previousHeader) && chunkMessageHeaderType != ChunkMessageHeaderType.New) { previousHeader = header.Clone(); } switch (chunkMessageHeaderType) { // 11 bytes case ChunkMessageHeaderType.New: header.Timestamp = reader.ReadUInt24(); header.PacketLength = reader.ReadUInt24(); header.MessageType = (MessageType)reader.ReadByte(); header.MessageStreamId = reader.ReadReverseInt(); break; // 7 bytes case ChunkMessageHeaderType.SameSource: header.Timestamp = reader.ReadUInt24(); header.PacketLength = reader.ReadUInt24(); header.MessageType = (MessageType)reader.ReadByte(); header.MessageStreamId = previousHeader.MessageStreamId; break; // 3 bytes case ChunkMessageHeaderType.TimestampAdjustment: header.Timestamp = reader.ReadUInt24(); header.PacketLength = previousHeader.PacketLength; header.MessageType = previousHeader.MessageType; header.MessageStreamId = previousHeader.MessageStreamId; break; // 0 bytes case ChunkMessageHeaderType.Continuation: header.Timestamp = previousHeader.Timestamp; header.PacketLength = previousHeader.PacketLength; header.MessageType = previousHeader.MessageType; header.MessageStreamId = previousHeader.MessageStreamId; header.IsTimerRelative = previousHeader.IsTimerRelative; break; default: throw new SerializationException("Unexpected header type: " + (int)chunkMessageHeaderType); } // extended timestamp if (header.Timestamp == 0xFFFFFF) { header.Timestamp = reader.ReadInt32(); } return(header); }
RtmpHeader ReadHeader() { // first byte of the chunk basic header var chunkBasicHeaderByte = reader.ReadByte(); var chunkStreamId = GetChunkStreamId(chunkBasicHeaderByte, reader); var chunkMessageHeaderType = (ChunkMessageHeaderType)(chunkBasicHeaderByte >> 6); var header = new RtmpHeader() { StreamId = chunkStreamId, IsTimerRelative = chunkMessageHeaderType != ChunkMessageHeaderType.New }; RtmpHeader previousHeader; // don't need to clone if new header, as it contains all info if (!rtmpHeaders.TryGetValue(chunkStreamId, out previousHeader) && chunkMessageHeaderType != ChunkMessageHeaderType.New) previousHeader = header.Clone(); switch (chunkMessageHeaderType) { // 11 bytes case ChunkMessageHeaderType.New: header.Timestamp = reader.ReadUInt24(); header.PacketLength = reader.ReadUInt24(); header.MessageType = (MessageType)reader.ReadByte(); header.MessageStreamId = reader.ReadReverseInt(); break; // 7 bytes case ChunkMessageHeaderType.SameSource: header.Timestamp = reader.ReadUInt24(); header.PacketLength = reader.ReadUInt24(); header.MessageType = (MessageType)reader.ReadByte(); header.MessageStreamId = previousHeader.MessageStreamId; break; // 3 bytes case ChunkMessageHeaderType.TimestampAdjustment: header.Timestamp = reader.ReadUInt24(); header.PacketLength = previousHeader.PacketLength; header.MessageType = previousHeader.MessageType; header.MessageStreamId = previousHeader.MessageStreamId; break; // 0 bytes case ChunkMessageHeaderType.Continuation: header.Timestamp = previousHeader.Timestamp; header.PacketLength = previousHeader.PacketLength; header.MessageType = previousHeader.MessageType; header.MessageStreamId = previousHeader.MessageStreamId; header.IsTimerRelative = previousHeader.IsTimerRelative; break; default: throw new SerializationException("Unexpected header type: " + (int)chunkMessageHeaderType); } // extended timestamp if (header.Timestamp == 0xFFFFFF) header.Timestamp = reader.ReadInt32(); return header; }
public RtmpPacket(RtmpHeader header, RtmpEvent body) : this(header) { Body = body; Length = header.PacketLength; }
void WriteMessageHeader(RtmpHeader header, RtmpHeader previousHeader) { var headerType = GetMessageHeaderType(header, previousHeader); WriteBasicHeader(headerType, header.StreamId); var uint24Timestamp = header.Timestamp < 0xFFFFFF ? header.Timestamp : 0xFFFFFF; switch (headerType) { case ChunkMessageHeaderType.New: writer.WriteUInt24(uint24Timestamp); writer.WriteUInt24(header.PacketLength); writer.WriteByte((byte)header.MessageType); writer.WriteReverseInt(header.MessageStreamId); break; case ChunkMessageHeaderType.SameSource: writer.WriteUInt24(uint24Timestamp); writer.WriteUInt24(header.PacketLength); writer.WriteByte((byte)header.MessageType); break; case ChunkMessageHeaderType.TimestampAdjustment: writer.WriteUInt24(uint24Timestamp); break; case ChunkMessageHeaderType.Continuation: break; default: throw new ArgumentException("headerType"); } if (uint24Timestamp >= 0xFFFFFF) writer.WriteInt32(header.Timestamp); }
byte[] GetMessageBytes(RtmpHeader header, RtmpEvent message) { switch (header.MessageType) { case MessageType.SetChunkSize: return GetMessageBytes(message, (w, o) => w.WriteInt32(((ChunkSize)o).Size)); case MessageType.AbortMessage: return GetMessageBytes(message, (w, o) => w.WriteInt32(((Abort)o).StreamId)); case MessageType.Acknowledgement: return GetMessageBytes(message, (w, o) => w.WriteInt32(((Acknowledgement)o).BytesRead)); case MessageType.UserControlMessage: return GetMessageBytes(message, (w, o) => { var m = (UserControlMessage)o; w.WriteUInt16((ushort)m.EventType); foreach (var v in m.Values) w.WriteInt32(v); }); case MessageType.WindowAcknowledgementSize: return GetMessageBytes(message, (w, o) => w.WriteInt32(((WindowAcknowledgementSize)o).Count)); case MessageType.SetPeerBandwith: return GetMessageBytes(message, (w, o) => { var m = (PeerBandwith)o; w.WriteInt32(m.AcknowledgementWindowSize); w.WriteByte((byte)m.LimitType); }); case MessageType.Audio: case MessageType.Video: return GetMessageBytes(message, (w, o) => w.WriteBytes(((ByteData)o).Data)); case MessageType.DataAmf0: return GetMessageBytes(message, (w, o) => WriteData(w, o, ObjectEncoding.Amf0)); case MessageType.SharedObjectAmf0: return new byte[0]; // TODO: `SharedObject`s case MessageType.CommandAmf0: return GetMessageBytes(message, (w, o) => WriteCommandOrData(w, o, ObjectEncoding.Amf0)); case MessageType.DataAmf3: return GetMessageBytes(message, (w, o) => WriteData(w, o, ObjectEncoding.Amf3)); case MessageType.SharedObjectAmf3: return new byte[0]; // TODO: `SharedObject`s case MessageType.CommandAmf3: return GetMessageBytes(message, (w, o) => { w.WriteByte(0); WriteCommandOrData(w, o, ObjectEncoding.Amf3); }); case MessageType.Aggregate: // TODO: Aggregate messages System.Diagnostics.Debugger.Break(); return new byte[0]; // TODO: `Aggregate` default: throw new ArgumentOutOfRangeException("Unknown RTMP message type: " + (int)header.MessageType); } }
RtmpHeader ReadHeader() { if (reader.underlying.BaseStream is NetworkStream) { var orig_stream = (NetworkStream)reader.underlying.BaseStream; if (!orig_stream.DataAvailable) { return(null); } } if (reader.underlying.BaseStream is SslStream) { var orig_stream = (SslStream)reader.underlying.BaseStream; throw new NotImplementedException(); } if (reader.underlying.BaseStream is WebsocketStream) { return(null); //var orig_stream = (WebsocketStream)reader.underlying.BaseStream; //if (!orig_stream.DataAvailable) //{ // return null; //} } // first byte of the chunk basic header var chunkBasicHeaderByte = reader.ReadByte(); var chunkStreamId = GetChunkStreamId(chunkBasicHeaderByte, reader); var chunkMessageHeaderType = (ChunkMessageHeaderType)(chunkBasicHeaderByte >> 6); var header = new RtmpHeader() { StreamId = chunkStreamId, IsTimerRelative = chunkMessageHeaderType != ChunkMessageHeaderType.New }; RtmpHeader previousHeader; // don't need to clone if new header, as it contains all info if (!rtmpHeaders.TryGetValue(chunkStreamId, out previousHeader) && chunkMessageHeaderType != ChunkMessageHeaderType.New) { previousHeader = header.Clone(); } switch (chunkMessageHeaderType) { // 11 bytes case ChunkMessageHeaderType.New: header.Timestamp = reader.ReadUInt24(); header.PacketLength = reader.ReadUInt24(); header.MessageType = (MessageType)reader.ReadByte(); header.MessageStreamId = reader.ReadReverseInt(); break; // 7 bytes case ChunkMessageHeaderType.SameSource: header.Timestamp = reader.ReadUInt24(); header.PacketLength = reader.ReadUInt24(); header.MessageType = (MessageType)reader.ReadByte(); header.MessageStreamId = previousHeader.MessageStreamId; break; // 3 bytes case ChunkMessageHeaderType.TimestampAdjustment: header.Timestamp = reader.ReadUInt24(); header.PacketLength = previousHeader.PacketLength; header.MessageType = previousHeader.MessageType; header.MessageStreamId = previousHeader.MessageStreamId; break; // 0 bytes case ChunkMessageHeaderType.Continuation: header.Timestamp = previousHeader.Timestamp; header.PacketLength = previousHeader.PacketLength; header.MessageType = previousHeader.MessageType; header.MessageStreamId = previousHeader.MessageStreamId; header.IsTimerRelative = previousHeader.IsTimerRelative; break; default: throw new SerializationException("Unexpected header type: " + (int)chunkMessageHeaderType); } // extended timestamp if (header.Timestamp == 0xFFFFFF) { header.Timestamp = reader.ReadInt32(); } return(header); }
public RtmpPacket(RtmpHeader header) { Header = header; Length = header.PacketLength; Buffer = new byte[Length]; }
private byte[] GetMessageBytes(RtmpHeader header, RtmpEvent message) { switch (header.MessageType) { case MessageType.SetChunkSize: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => w.WriteInt32(((ChunkSize)o).Size)))); case MessageType.AbortMessage: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => w.WriteInt32(((Abort)o).StreamId)))); case MessageType.Acknowledgement: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => w.WriteInt32(((Acknowledgement)o).BytesRead)))); case MessageType.UserControlMessage: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => { UserControlMessage userControlMessage = (UserControlMessage)o; w.WriteUInt16((ushort)userControlMessage.EventType); foreach (int num in userControlMessage.Values) { w.WriteInt32(num); } }))); case MessageType.WindowAcknowledgementSize: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => w.WriteInt32(((WindowAcknowledgementSize)o).Count)))); case MessageType.SetPeerBandwidth: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => { PeerBandwidth peerBandwidth = (PeerBandwidth)o; w.WriteInt32(peerBandwidth.AcknowledgementWindowSize); w.WriteByte((byte)peerBandwidth.LimitType); }))); case MessageType.Audio: case MessageType.Video: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => w.WriteBytes(((ByteData)o).Data)))); case MessageType.DataAmf3: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => this.WriteData(w, o, ObjectEncoding.Amf3)))); case MessageType.SharedObjectAmf3: return(new byte[0]); case MessageType.CommandAmf3: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => { w.WriteByte((byte)0); this.WriteCommandOrData(w, o, ObjectEncoding.Amf3); }))); case MessageType.DataAmf0: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => this.WriteData(w, o, ObjectEncoding.Amf0)))); case MessageType.SharedObjectAmf0: return(new byte[0]); case MessageType.CommandAmf0: return(this.GetMessageBytes(message, (Action <AmfWriter, RtmpEvent>)((w, o) => this.WriteCommandOrData(w, o, ObjectEncoding.Amf0)))); case MessageType.Aggregate: Debugger.Break(); return(new byte[0]); default: throw new ArgumentOutOfRangeException("Unknown RTMP message type: " + (object)(int)header.MessageType); } }
byte[] GetMessageBytes(RtmpHeader header, RtmpEvent message) { switch (header.MessageType) { case MessageType.SetChunkSize: return(GetMessageBytes(message, (w, o) => w.WriteInt32(((ChunkSize)o).Size))); case MessageType.AbortMessage: return(GetMessageBytes(message, (w, o) => w.WriteInt32(((Abort)o).StreamId))); case MessageType.Acknowledgement: return(GetMessageBytes(message, (w, o) => w.WriteInt32(((Acknowledgement)o).BytesRead))); case MessageType.UserControlMessage: return(GetMessageBytes(message, (w, o) => { var m = (UserControlMessage)o; w.WriteUInt16((ushort)m.EventType); foreach (var v in m.Values) { w.WriteInt32(v); } })); case MessageType.WindowAcknowledgementSize: return(GetMessageBytes(message, (w, o) => w.WriteInt32(((WindowAcknowledgementSize)o).Count))); case MessageType.SetPeerBandwith: return(GetMessageBytes(message, (w, o) => { var m = (PeerBandwidth)o; w.WriteInt32(m.AcknowledgementWindowSize); w.WriteByte((byte)m.LimitType); })); case MessageType.Audio: case MessageType.Video: return(GetMessageBytes(message, (w, o) => WriteData(w, o, ObjectEncoding.Amf0))); case MessageType.DataAmf0: return(GetMessageBytes(message, (w, o) => WriteCommandOrData(w, o, ObjectEncoding.Amf0))); case MessageType.SharedObjectAmf0: return(new byte[0]); // todo: `SharedObject`s case MessageType.CommandAmf0: return(GetMessageBytes(message, (w, o) => WriteCommandOrData(w, o, ObjectEncoding.Amf0))); case MessageType.DataAmf3: return(GetMessageBytes(message, (w, o) => WriteData(w, o, ObjectEncoding.Amf3))); case MessageType.SharedObjectAmf3: return(new byte[0]); // todo: `SharedObject`s case MessageType.CommandAmf3: return(GetMessageBytes(message, (w, o) => { w.WriteByte(0); WriteCommandOrData(w, o, ObjectEncoding.Amf3); })); case MessageType.Aggregate: // todo: Aggregate messages System.Diagnostics.Debugger.Break(); return(new byte[0]); // todo: `Aggregate` default: throw new ArgumentOutOfRangeException("Unknown RTMP message type: " + (int)header.MessageType); } }
public RtmpPacket(RtmpHeader header) { this.Header = header; this.Length = header.PacketLength; this.Buffer = new byte[this.Length]; }