Пример #1
0
        /// <summary>
        /// Parses the given packet contained in the byte buffer array and returns
        /// a list of packets
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static LinkedList <AMFDataType> getPacketVars(byte[] buffer, int length, int offset)
        {
            //the linked list of packet vars
            LinkedList <AMFDataType> packetVars = new LinkedList <AMFDataType>();

            //read the header byte to determine size
            MemoryStream packetStream = new MemoryStream(buffer, offset, length);

            byte header = (byte)packetStream.ReadByte();

            header &= 0xC0; // isolate the size information

            //seek into the packet
            packetStream.Seek(AMFHeader.getHeaderSize(header) - 1, SeekOrigin.Current);

            while (packetStream.Position < length)
            {
                byte type = (byte)packetStream.ReadByte();
                Console.WriteLine("Looking at type: " + type);
                AMFDataType var = findAppropriateReader(type);
                var.read(packetStream);
                packetVars.AddLast(var);
            }


            return(packetVars);
        }
Пример #2
0
        /// <summary>
        /// Reads the header information from the given byte[] data.
        /// </summary>
        /// <param name="offset">The offset in the data buffer to look at</param>
        /// <param name="data">The data to look at</param>
        /// <returns>null if the data is not valid, or an AMFHeader object representing
        /// the information</returns>
        public static AMFHeader readHeader(int offset, byte[] data)
        {
            AMFHeader header = new AMFHeader(0, 0);

            header.ChannelId      = (byte)(data[offset] & 0x3F);
            header.HeaderTypeSize = (byte)(data[offset] & 0xC0);
            offset++;
            if (header.getHeaderSize() > 4)
            {
                //read the timestamp portion
                header.TimeStamp |= data[offset] << 16;
                header.TimeStamp |= data[offset + 1] << 8;
                header.TimeStamp |= data[offset + 2];
                offset           += 3;
            }

            if (header.getHeaderSize() > 8)
            {
                //read the AMF body size
                header.BodySize |= data[offset] << 16;
                header.BodySize |= data[offset + 1] << 8;
                header.BodySize |= data[offset + 2];
                offset          += 3;
            }

            if (header.getHeaderSize() > 8)
            {
                //read the AMF type
                header.RTMPType = data[offset];
                offset++;
            }

            if (header.getHeaderSize() > 12)
            {
                //write the endpoint bytes ( or stream ID if video )
                header.endPoint |= data[offset];
                header.endPoint |= (data[offset + 1] << 8);
                header.endPoint |= (data[offset + 2] << 16);
                header.endPoint |= (data[offset + 3] << 24);
            }

            return(header);
        }
Пример #3
0
        /// <summary>
        /// Reads the header information from the given byte[] data.
        /// </summary>
        /// <param name="offset">The offset in the data buffer to look at</param>
        /// <param name="data">The data to look at</param>
        /// <returns>null if the data is not valid, or an AMFHeader object representing
        /// the information</returns>
        public static AMFHeader readHeader(int offset, byte[] data)
        {
            AMFHeader header = new AMFHeader(0, 0);
            header.ChannelId = (byte)(data[offset] & 0x3F);
            header.HeaderTypeSize = (byte)(data[offset] & 0xC0);
            offset++;
            if (header.getHeaderSize() > 4)
            {
                //read the timestamp portion
                header.TimeStamp |= data[offset] << 16;
                header.TimeStamp |= data[offset + 1] << 8;
                header.TimeStamp |= data[offset + 2];
                offset += 3;

            }

            if (header.getHeaderSize() > 8)
            {
                //read the AMF body size
                header.BodySize |= data[offset] << 16;
                header.BodySize |= data[offset + 1] << 8;
                header.BodySize |= data[offset + 2];
                offset += 3;
            }

            if (header.getHeaderSize() > 8)
            {
                //read the AMF type
                header.RTMPType = data[offset];
                offset++;
            }

            if (header.getHeaderSize() > 12)
            {
                //write the endpoint bytes ( or stream ID if video )
                header.endPoint |= data[offset];
                header.endPoint |= (data[offset + 1] << 8);
                header.endPoint |= (data[offset + 2] << 16);
                header.endPoint |= (data[offset + 3] << 24);

            }

            return header;
        }
Пример #4
0
        /// <summary>
        /// Sends the current buffer using data_buffer as the source of data. The size
        /// is determined from the position in outputBuff.
        /// </summary>
        /// <param name="header">The header to prepend to the amf packet.</param>
        private void chunkBufferAndSend(AMFHeader header)
        {
            //the size remaining in the data buffer
            int size = (int)outputBuff.Position;

            //the position in the data buffer (from which to start sending bytes)
            int position = 0;

            //reset the chunkBuff position
            chunkBuff.Position = 0;

            //write the header to the chunk buffer
            header.writeHeader(chunkBuff);

            //copy <= 128 bytes from the data buffer into the chunk buffer to send.
            Array.Copy(dataBuffer, 0, chunk_buffer, header.getHeaderSize(),
                size > 128 ? 128 : size);
            //send the first packet of information
            connectionSocket.Send(chunk_buffer,
                (header.getHeaderSize() + (size > 128 ? 128 : size)),
                SocketFlags.None);

            size -= 128;
            position += 128;


            while (size > 0)
            {
                //add a header byte
                dataBuffer[position - 1] = header.get_1_HeaderByte();

                //send out the data
                connectionSocket.Send(dataBuffer, position - 1,
                    size > 128 ? 129 : size + 1, SocketFlags.None);

                

                position += 128;
                size -= 128;
            }
        }
Пример #5
0
        /// <summary>
        /// Sends the flv tag to the RTMP server.
        /// </summary>
        /// <param name="tagData"></param>
        /// <param name="tag"></param>
        public override bool sendFLVTag(byte[] tagData, FLVTag tag)
        {
      
            if (!isConnected)
                return false;
            outputBuff.Position = 0;
            chunkBuff.Position = 0;

            AMFHeader header = new AMFHeader(AMFHeader.HEADER_12, 0x8);
            header.RTMPType = AMFHeader.RTMP_TYPE_VIDEO;
            header.TimeStamp = tag.TimeStamp;
            header.EndPoint = 0x00000001;
            header.BodySize = tag.getTagSizeInBytes() - 11;

            //write the header to teh chunkbuffer
            header.writeHeader(chunkBuff);

            //the size remaining in the data buffer
            int size = tag.getTagSizeInBytes() - 11;

            //the position in the data buffer (from which to start sending bytes)
            int position = 0;

            //write the header to the chunk buffer
            header.writeHeader(chunkBuff);

            //copy <= 128 bytes from the tagData into the chunk buffer to send.
            Array.Copy(tagData, 11, chunk_buffer, header.getHeaderSize(),
                size > 128 ? 128 : size);
            //send the first packet of information
            connectionSocket.Send(chunk_buffer,
                (header.getHeaderSize() + (size > 128 ? 128 : size)),
                SocketFlags.None);

            size -= 128;
            position += 128 + 11;

            //while there is still bytes
            while (size > 0)
            {

                //add a header byte
                byte t = tagData[position - 1];
                tagData[position - 1] = header.get_1_HeaderByte();

                //send out the data
                connectionSocket.Send(tagData, position - 1,
                    size > 128 ? 129 : size + 1, SocketFlags.None);
                

                //restore where the header was
                tagData[position - 1] = t;
                position += 128;
                size -= 128;

            }

            return true;

        }