コード例 #1
0
        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));
            }
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
ファイル: RtmpPacketReader.cs プロジェクト: mfro/LeagueClient
        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));
            }
        }
コード例 #4
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();
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
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);
        }
コード例 #8
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();
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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));
            }
        }
コード例 #11
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();
        }
コード例 #12
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();
            Interlocked.Exchange(ref packetAvailable, 1);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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;
            }
        }
コード例 #15
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));
     }
 }
コード例 #16
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;
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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;
        }
コード例 #19
0
        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;
        }
コード例 #20
0
        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;
        }
コード例 #21
0
ファイル: RtmpPacketReader.cs プロジェクト: mfro/LeagueClient
        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;
        }