예제 #1
0
        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);
        }
예제 #3
0
        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();
        }
예제 #4
0
 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);
 }
예제 #5
0
        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;
        }
예제 #6
0
        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);
        }
예제 #7
0
        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();
        }
예제 #8
0
        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);
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
 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));
     }
 }
예제 #12
0
        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");
            }
        }
예제 #13
0
        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;
        }
예제 #14
0
        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);
        }
예제 #15
0
        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;
        }
예제 #16
0
 public RtmpPacket(RtmpHeader header, RtmpEvent body) : this(header)
 {
     Body   = body;
     Length = header.PacketLength;
 }
예제 #17
0
        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);
        }
예제 #18
0
        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);
            }
        }
예제 #19
0
        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);
        }
예제 #20
0
 public RtmpPacket(RtmpHeader header)
 {
     Header = header;
     Length = header.PacketLength;
     Buffer = new byte[Length];
 }
예제 #21
0
 public RtmpPacket(RtmpHeader header, RtmpEvent body) : this(header)
 {
     Body = body;
     Length = header.PacketLength;
 }
예제 #22
0
 public RtmpPacket(RtmpHeader header)
 {
     Header = header;
     Length = header.PacketLength;
     Buffer = new byte[Length];
 }
예제 #23
0
        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);
            }
        }
예제 #24
0
        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);
            }
        }
예제 #25
0
 public RtmpPacket(RtmpHeader header)
 {
     this.Header = header;
     this.Length = header.PacketLength;
     this.Buffer = new byte[this.Length];
 }