PeerCastStation.FLV.FLVFileParser.Read C# (CSharp) Method

Read() public method

public Read ( Stream stream, IRTMPContentSink sink ) : bool
stream Stream
sink IRTMPContentSink
return bool
		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;
		}

Usage Example

Beispiel #1
0
            private async Task ProcessMessagesAsync(IContentSink targetSink, CancellationToken cancellationToken)
            {
                var bufferStream  = new MemoryStream();
                var context       = new FLVToMPEG2TS.Context(bufferStream);
                var contentBuffer = new MemoryStream();
                var fileParser    = new FLVFileParser();
                var msg           = await msgQueue.DequeueAsync(cancellationToken).ConfigureAwait(false);

                while (msg.Type != ContentMessage.MessageType.Stop)
                {
                    switch (msg.Type)
                    {
                    case ContentMessage.MessageType.ChannelInfo:
                        targetSink.OnChannelInfo(msg.ChannelInfo);
                        break;

                    case ContentMessage.MessageType.ChannelTrack:
                        targetSink.OnChannelTrack(msg.ChannelTrack);
                        break;

                    case ContentMessage.MessageType.ContentHeader:
                    {
                        var buffer = contentBuffer;
                        var pos    = buffer.Position;
                        buffer.Seek(0, SeekOrigin.End);
                        buffer.Write(msg.Content.Data.Span);
                        buffer.Position = pos;
                        fileParser.Read(buffer, context);
                        if (buffer.Position != 0)
                        {
                            var new_buf  = new MemoryStream();
                            var trim_pos = buffer.Position;
                            buffer.Close();
                            var buf = buffer.ToArray();
                            new_buf.Write(buf, (int)trim_pos, (int)(buf.Length - trim_pos));
                            new_buf.Position = 0;
                            contentBuffer    = new_buf;
                        }
                        if (bufferStream.Position != 0)
                        {
                            targetSink.OnContentHeader(
                                new Content(
                                    msg.Content.Stream,
                                    msg.Content.Timestamp,
                                    msg.Content.Position,
                                    bufferStream.ToArray(),
                                    msg.Content.ContFlag
                                    )
                                );
                            bufferStream.SetLength(0);
                        }
                    }
                    break;

                    case ContentMessage.MessageType.ContentBody:
                    {
                        var buffer = contentBuffer;
                        var pos    = buffer.Position;
                        buffer.Seek(0, SeekOrigin.End);
                        buffer.Write(msg.Content.Data.Span);
                        buffer.Position = pos;
                        fileParser.Read(buffer, context);
                        if (buffer.Position != 0)
                        {
                            var new_buf  = new MemoryStream();
                            var trim_pos = buffer.Position;
                            buffer.Close();
                            var buf = buffer.ToArray();
                            new_buf.Write(buf, (int)trim_pos, (int)(buf.Length - trim_pos));
                            new_buf.Position = 0;
                            contentBuffer    = new_buf;
                        }
                        if (bufferStream.Position != 0)
                        {
                            targetSink.OnContent(
                                new Content(
                                    msg.Content.Stream,
                                    msg.Content.Timestamp,
                                    msg.Content.Position,
                                    bufferStream.ToArray(),
                                    msg.Content.ContFlag
                                    )
                                );
                            bufferStream.SetLength(0);
                        }
                    }
                    break;
                    }
                    msg = await msgQueue.DequeueAsync(cancellationToken).ConfigureAwait(false);
                }
                targetSink.OnStop(msg.StopReason);
            }