예제 #1
0
        public async Task ReadAsync(
            Stream stream,
            IRTMPContentSink sink,
            CancellationToken cancel_token)
        {
            int len = 0;
            var bin = new byte[13];

            try {
                len += await stream.ReadBytesAsync(bin, len, 13 - len, cancel_token).ConfigureAwait(false);
            }
            catch (EndOfStreamException) {
                return;
            }
            var header = new FLVFileHeader(bin);

            if (!header.IsValid)
            {
                throw new BadDataException();
            }
            sink.OnFLVHeader(header);
            len = 0;

            bool eos = false;

            while (!eos)
            {
                try {
                    len += await stream.ReadBytesAsync(bin, len, 11 - len, cancel_token).ConfigureAwait(false);

                    var read_valid = false;
                    var body       = new FLVTag(this, bin);
                    if (body.IsValidHeader)
                    {
                        if (await body.ReadTagBodyAsync(stream, cancel_token).ConfigureAwait(false))
                        {
                            len        = 0;
                            read_valid = true;
                            switch (body.Type)
                            {
                            case FLVTag.TagType.Audio:
                                sink.OnAudio(body.ToRTMPMessage());
                                break;

                            case FLVTag.TagType.Video:
                                sink.OnVideo(body.ToRTMPMessage());
                                break;

                            case FLVTag.TagType.Script:
                                sink.OnData(new DataAMF0Message(body.ToRTMPMessage()));
                                break;
                            }
                        }
                    }
                    else
                    {
                        len += await stream.ReadBytesAsync(bin, len, 13 - len, cancel_token).ConfigureAwait(false);

                        var new_header = new FLVFileHeader(bin);
                        if (new_header.IsValid)
                        {
                            read_valid = true;
                            sink.OnFLVHeader(header);
                        }
                    }
                    if (!read_valid)
                    {
                        int pos = 1;
                        for (; pos < len; pos++)
                        {
                            var b = bin[pos];
                            if ((b & 0xC0) == 0 && ((b & 0x1F) == 8 || (b & 0x1F) == 9 || (b & 0x1F) == 18))
                            {
                                break;
                            }
                        }
                        if (pos == len)
                        {
                            len = 0;
                        }
                        else
                        {
                            Array.Copy(bin, pos, bin, 0, len - pos);
                            len -= pos;
                        }
                    }
                }
                catch (EndOfStreamException) {
                    eos = true;
                }
            }
        }
예제 #2
0
 public bool Read(Stream stream, IRTMPContentSink sink)
 {
     var processed = false;
     var eos = false;
     while (!eos) {
         retry:
         var start_pos = stream.Position;
         try {
             switch (state) {
             case ReaderState.Header:
                 {
                     var bin = ReadBytes(stream, 13, out eos);
                     if (eos) goto error;
                     var header = new FileHeader(bin);
                     if (header.IsValid) {
                         sink.OnFLVHeader();
                         state = ReaderState.Body;
                     }
                     else {
                         throw new BadDataException();
                     }
                 }
                 break;
             case ReaderState.Body:
                 {
                     var bin = ReadBytes(stream, 11, out eos);
                     if (eos) goto error;
                     var read_valid = false;
                     var body = new FLVTag(this, bin);
                     if (body.IsValidHeader) {
                         if (!body.ReadBody(stream)) { eos = true; goto error; }
                         if (!body.ReadFooter(stream)) {  eos = true; goto error; }
                         if (body.IsValidFooter) {
                             read_valid = true;
                             switch (body.Type) {
                             case FLVTag.TagType.Audio:
                                 sink.OnAudio(body.ToRTMPMessage());
                                 break;
                             case FLVTag.TagType.Video:
                                 sink.OnVideo(body.ToRTMPMessage());
                                 break;
                             case FLVTag.TagType.Script:
                                 sink.OnData(new DataAMF0Message(body.ToRTMPMessage()));
                                 break;
                             }
                         }
                     }
                     else {
                         stream.Position = start_pos;
                         var headerbin = ReadBytes(stream, 13, out eos);
                         if (eos) goto error;
                         var header = new FileHeader(headerbin);
                         if (header.IsValid) {
                             read_valid = true;
                             sink.OnFLVHeader();
                         }
                     }
                     if (!read_valid) {
                         stream.Position = start_pos+1;
                         var b = stream.ReadByte();
                         while (true) {
                             if (b<0) {
                                 eos = true;
                                 goto error;
                             }
                             if ((b & 0xC0)==0 && ((b & 0x1F)==8 || (b & 0x1F)==9 || (b & 0x1F)==18)) {
                                 break;
                             }
                             b = stream.ReadByte();
                         }
                         stream.Position = stream.Position-1;
                         goto retry;
                     }
                 }
                 break;
             }
             processed = true;
         }
         catch (EndOfStreamException) {
             stream.Position = start_pos;
             eos = true;
         }
         catch (BadDataException) {
             stream.Position = start_pos+1;
         }
     error:
         if (eos) {
             stream.Position = start_pos;
             eos = true;
         }
     }
     return processed;
 }
예제 #3
0
        public bool Read(Stream stream, IRTMPContentSink sink)
        {
            var processed = false;
            var eos       = false;

            while (!eos)
            {
retry:
                var start_pos = stream.Position;
                try {
                    switch (state)
                    {
                    case ReaderState.Header:
                    {
                        var bin = ReadBytes(stream, 13, out eos);
                        if (eos)
                        {
                            goto error;
                        }
                        var header = new FLVFileHeader(bin);
                        if (header.IsValid)
                        {
                            sink.OnFLVHeader(header);
                            state = ReaderState.Body;
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                    }
                    break;

                    case ReaderState.Body:
                    {
                        var bin = ReadBytes(stream, 11, out eos);
                        if (eos)
                        {
                            goto error;
                        }
                        var read_valid = false;
                        var body       = new FLVTag(this, bin);
                        if (body.IsValidHeader)
                        {
                            if (!body.ReadBody(stream))
                            {
                                eos = true; goto error;
                            }
                            if (!body.ReadFooter(stream))
                            {
                                eos = true; goto error;
                            }
                            if (body.IsValidFooter)
                            {
                                read_valid = true;
                                switch (body.Type)
                                {
                                case FLVTag.TagType.Audio:
                                    sink.OnAudio(body.ToRTMPMessage());
                                    break;

                                case FLVTag.TagType.Video:
                                    sink.OnVideo(body.ToRTMPMessage());
                                    break;

                                case FLVTag.TagType.Script:
                                    sink.OnData(new DataAMF0Message(body.ToRTMPMessage()));
                                    break;
                                }
                            }
                        }
                        else
                        {
                            stream.Position = start_pos;
                            var headerbin = ReadBytes(stream, 13, out eos);
                            if (eos)
                            {
                                goto error;
                            }
                            var header = new FLVFileHeader(headerbin);
                            if (header.IsValid)
                            {
                                read_valid = true;
                                sink.OnFLVHeader(header);
                            }
                        }
                        if (!read_valid)
                        {
                            stream.Position = start_pos + 1;
                            var b = stream.ReadByte();
                            while (true)
                            {
                                if (b < 0)
                                {
                                    eos = true;
                                    goto error;
                                }
                                if ((b & 0xC0) == 0 && ((b & 0x1F) == 8 || (b & 0x1F) == 9 || (b & 0x1F) == 18))
                                {
                                    break;
                                }
                                b = stream.ReadByte();
                            }
                            stream.Position = stream.Position - 1;
                            goto retry;
                        }
                    }
                    break;
                    }
                    processed = true;
                }
                catch (EndOfStreamException) {
                    stream.Position = start_pos;
                    eos             = true;
                }
                catch (BadDataException) {
                    stream.Position = start_pos + 1;
                }
error:
                if (eos)
                {
                    stream.Position = start_pos;
                    eos             = true;
                }
            }
            return(processed);
        }
예제 #4
0
    public async Task ReadAsync(
      Stream stream,
      IRTMPContentSink sink,
      CancellationToken cancel_token)
    {
      int len = 0;
      var bin = new byte[13];
      try {
        len += await stream.ReadBytesAsync(bin, len, 13-len, cancel_token);
      }
      catch (EndOfStreamException) {
        return;
      }
      var header = new FileHeader(bin);
      if (!header.IsValid) throw new BadDataException();
      sink.OnFLVHeader();
      len = 0;

      bool eos = false;
      while (!eos) {
        try {
          len += await stream.ReadBytesAsync(bin, len, 11-len, cancel_token);
          var read_valid = false;
          var body = new FLVTag(this, bin);
          if (body.IsValidHeader) {
            if (await body.ReadTagBodyAsync(stream, cancel_token)) {
              len = 0;
              read_valid = true;
              switch (body.Type) {
              case FLVTag.TagType.Audio:
                sink.OnAudio(body.ToRTMPMessage());
                break;
              case FLVTag.TagType.Video:
                sink.OnVideo(body.ToRTMPMessage());
                break;
              case FLVTag.TagType.Script:
                sink.OnData(new DataAMF0Message(body.ToRTMPMessage()));
                break;
              }
            }
          }
          else {
            len += await stream.ReadBytesAsync(bin, len, 13-len, cancel_token);
            var new_header = new FileHeader(bin);
            if (new_header.IsValid) {
              read_valid = true;
              sink.OnFLVHeader();
            }
          }
          if (!read_valid) {
            int pos = 1;
            for (; pos<len; pos++) {
              var b = bin[pos];
              if ((b & 0xC0)==0 && ((b & 0x1F)==8 || (b & 0x1F)==9 || (b & 0x1F)==18)) {
                break;
              }
            }
            if (pos==len) {
              len = 0;
            }
            else {
              Array.Copy(bin, pos, bin, 0, len-pos);
              len -= pos;
            }
          }
        }
        catch (EndOfStreamException) {
          eos = true;
        }
      }

    }