Esempio n. 1
0
 private void BroadcastStart_Click(object sender, EventArgs args)
 {
   Uri source;
   if (Uri.TryCreate(bcStreamUrl.Text, UriKind.Absolute, out source)) {
     StreamSource = source;
   }
   else {
     StreamSource = null;
   }
   var reader = bcContentType.SelectedItem as ContentReaderItem;
   if (reader!=null) ContentReaderFactory = reader.ContentReaderFactory;
   var yp = bcYP.SelectedItem as YellowPageItem;
   if (yp!=null) YellowPage = yp.YellowPage;
   var info = new AtomCollection();
   int bitrate;
   if (Int32.TryParse(bcBitrate.Text, out bitrate)) {
     info.SetChanInfoBitrate(bitrate);
   }
   info.SetChanInfoName(bcChannelName.Text);
   info.SetChanInfoGenre(bcGenre.Text);
   info.SetChanInfoDesc(bcDescription.Text);
   info.SetChanInfoComment(bcComment.Text);
   info.SetChanInfoURL(bcContactUrl.Text);
   ChannelInfo = new ChannelInfo(info);
   var track = new AtomCollection();
   track.SetChanTrackTitle(bcTrackTitle.Text);
   track.SetChanTrackGenre(bcTrackGenre.Text);
   track.SetChanTrackAlbum(bcAlbum.Text);
   track.SetChanTrackCreator(bcCreator.Text);
   track.SetChanTrackURL(bcTrackURL.Text);
   ChannelTrack = new ChannelTrack(track);
   if (StreamSource!=null && ContentReaderFactory!=null && !String.IsNullOrEmpty(ChannelInfo.Name)) {
     DialogResult = DialogResult.OK;
   }
 }
 private void OnMetaData(DataMessage msg)
 {
   this.metadata = msg;
   var info = new AtomCollection();
   info.SetChanInfoType("FLV");
   info.SetChanInfoStreamType("video/x-flv");
   info.SetChanInfoStreamExt(".flv");
   if (metadata.Arguments[0].Type==AMF.AMFValueType.ECMAArray || metadata.Arguments[0].Type==AMF.AMFValueType.Object){
     var bitrate = 0.0;
     var val = metadata.Arguments[0]["maxBitrate"];
     if (!AMF.AMFValue.IsNull(val)) {
       double maxBitrate;
       string maxBitrateStr = System.Text.RegularExpressions.Regex.Replace((string)val, @"([\d]+)k", "$1");
       if (double.TryParse(maxBitrateStr, out maxBitrate)) {
         bitrate += maxBitrate;
       }
     }
     else if (!AMF.AMFValue.IsNull(val = metadata.Arguments[0]["videodatarate"])) {
       bitrate += (double)val;
     }
     if (!AMF.AMFValue.IsNull(val = metadata.Arguments[0]["audiodatarate"])) {
       bitrate += (double)val;
     }
     info.SetChanInfoBitrate((int)bitrate);
   }
   OnChannelInfoChanged(info);
   OnHeaderChanged(msg);
   OnContentChanged(msg);
 }
Esempio n. 3
0
        private void OnMetaData(DataMessage msg)
        {
            this.metadata = msg;
            var info = new AtomCollection();

            info.SetChanInfoType("FLV");
            info.SetChanInfoStreamType("video/x-flv");
            info.SetChanInfoStreamExt(".flv");
            if (metadata.Arguments[0].Type == AMF.AMFValueType.ECMAArray || metadata.Arguments[0].Type == AMF.AMFValueType.Object)
            {
                var bitrate = 0.0;
                var val     = metadata.Arguments[0]["maxBitrate"];
                if (!AMF.AMFValue.IsNull(val))
                {
                    double maxBitrate;
                    string maxBitrateStr = System.Text.RegularExpressions.Regex.Replace((string)val, @"([\d]+)k", "$1");
                    if (double.TryParse(maxBitrateStr, out maxBitrate))
                    {
                        bitrate += maxBitrate;
                    }
                }
                else if (!AMF.AMFValue.IsNull(val = metadata.Arguments[0]["videodatarate"]))
                {
                    bitrate += (double)val;
                }
                if (!AMF.AMFValue.IsNull(val = metadata.Arguments[0]["audiodatarate"]))
                {
                    bitrate += (double)val;
                }
                info.SetChanInfoBitrate((int)bitrate);
            }
            OnChannelInfoChanged(info);
            OnHeaderChanged(msg);
            OnContentChanged(msg);
        }
Esempio n. 4
0
        static HTTPOutputStream()
        {
            var chaninfo = new AtomCollection();

            chaninfo.SetChanInfoBitrate(0);
            chaninfo.SetChanInfoType("RAW");
            chaninfo.SetChanInfoStreamType("application/octet-stream");
            chaninfo.SetChanInfoStreamExt("");
        }
Esempio n. 5
0
 public ParsedContent Read(Stream stream)
 {
     var chunks = 0;
       var res = new ParsedContent();
       var pos = Channel.ContentPosition;
       try {
     while (chunks<8) {
       var chunk = ASFChunk.Read(stream);
       chunks++;
       switch (chunk.KnownType) {
       case ASFChunk.ChunkType.Header: {
       var header = ASFHeader.Read(chunk);
       var info = new AtomCollection(Channel.ChannelInfo.Extra);
       info.SetChanInfoBitrate(header.Bitrate);
       if (header.Streams.Any(type => type==ASFHeader.StreamType.Video)) {
         info.SetChanInfoType("WMV");
         info.SetChanInfoStreamType("video/x-ms-wmv");
         info.SetChanInfoStreamExt(".wmv");
       }
       else if (header.Streams.Any(type => type==ASFHeader.StreamType.Audio)) {
         info.SetChanInfoType("WMA");
         info.SetChanInfoStreamType("audio/x-ms-wma");
         info.SetChanInfoStreamExt(".wma");
       }
       else {
         info.SetChanInfoType("ASF");
         info.SetChanInfoStreamType("video/x-ms-asf");
         info.SetChanInfoStreamExt(".asf");
       }
       res.ChannelInfo = new ChannelInfo(info);
       streamIndex = Channel.GenerateStreamID();
       streamOrigin = DateTime.Now;
       res.ContentHeader = new Content(streamIndex, TimeSpan.Zero, pos, chunk.ToByteArray());
       pos += chunk.TotalLength;
     }
     break;
       case ASFChunk.ChunkType.Data:
     if (res.Contents==null) res.Contents = new System.Collections.Generic.List<Content>();
     res.Contents.Add(new Content(streamIndex, DateTime.Now-streamOrigin, pos, chunk.ToByteArray()));
     pos += chunk.TotalLength;
     break;
       case ASFChunk.ChunkType.Unknown:
     break;
       }
     }
       }
       catch (EndOfStreamException) {
     if (chunks==0) throw;
       }
       return res;
 }
Esempio n. 6
0
        private void UpdateRecvRate(IContentSink sink, double bitrate)
        {
            if (recvRate == 0.0 || (recvRate * 1.2 < bitrate && bitrate < recvRate * 10.0))
            {
                recvRate = bitrate;

                var info = new AtomCollection(Channel.ChannelInfo.Extra);
                info.SetChanInfoType("TS");
                info.SetChanInfoStreamType("video/mp2t");
                info.SetChanInfoStreamExt(".ts");
                info.SetChanInfoBitrate((int)bitrate / 1000);
                sink.OnChannelInfo(new ChannelInfo(info));
            }
        }
Esempio n. 7
0
        private void BroadcastStart_Click(object sender, EventArgs args)
        {
            Uri source;

            if (Uri.TryCreate(bcStreamUrl.Text, UriKind.Absolute, out source))
            {
                StreamSource = source;
            }
            else
            {
                StreamSource = null;
            }
            var reader = bcContentType.SelectedItem as ContentReaderItem;

            if (reader != null)
            {
                ContentReaderFactory = reader.ContentReaderFactory;
            }
            var yp = bcYP.SelectedItem as YellowPageItem;

            if (yp != null)
            {
                YellowPage = yp.YellowPage;
            }
            var info = new AtomCollection();
            int bitrate;

            if (Int32.TryParse(bcBitrate.Text, out bitrate))
            {
                info.SetChanInfoBitrate(bitrate);
            }
            info.SetChanInfoName(bcChannelName.Text);
            info.SetChanInfoGenre(bcGenre.Text);
            info.SetChanInfoDesc(bcDescription.Text);
            info.SetChanInfoComment(bcComment.Text);
            info.SetChanInfoURL(bcContactUrl.Text);
            ChannelInfo = new ChannelInfo(info);
            var track = new AtomCollection();

            track.SetChanTrackTitle(bcTrackTitle.Text);
            track.SetChanTrackGenre(bcTrackGenre.Text);
            track.SetChanTrackAlbum(bcAlbum.Text);
            track.SetChanTrackCreator(bcCreator.Text);
            track.SetChanTrackURL(bcTrackURL.Text);
            ChannelTrack = new ChannelTrack(track);
            if (StreamSource != null && ContentReaderFactory != null && !String.IsNullOrEmpty(ChannelInfo.Name))
            {
                DialogResult = DialogResult.OK;
            }
        }
Esempio n. 8
0
        private ChannelInfo CreateChannelInfo(BroadcastViewModel viewModel)
        {
            var info = new AtomCollection();

            if (viewModel.bitrate.HasValue)
            {
                info.SetChanInfoBitrate(viewModel.bitrate.Value);
            }
            info.SetChanInfoName(viewModel.channelName);
            info.SetChanInfoGenre(viewModel.genre);
            info.SetChanInfoDesc(viewModel.description);
            info.SetChanInfoComment(viewModel.comment);
            info.SetChanInfoURL(viewModel.contactUrl);
            return(new ChannelInfo(info));
        }
Esempio n. 9
0
        public ParsedContent Read(Stream stream)
        {
            var chunks = 0;
            var res    = new ParsedContent();
            var pos    = Channel.ContentPosition;

            try {
                while (chunks < 8)
                {
                    var chunk = ASFChunk.Read(stream);
                    chunks++;
                    switch (chunk.KnownType)
                    {
                    case ASFChunk.ChunkType.Header: {
                        var header = ASFHeader.Read(chunk);
                        var info   = new AtomCollection(Channel.ChannelInfo.Extra);
                        info.SetChanInfoBitrate(header.Bitrate);
                        if (header.Streams.Any(type => type == ASFHeader.StreamType.Video))
                        {
                            info.SetChanInfoType("WMV");
                            info.SetChanInfoStreamType("video/x-ms-wmv");
                            info.SetChanInfoStreamExt(".wmv");
                        }
                        else if (header.Streams.Any(type => type == ASFHeader.StreamType.Audio))
                        {
                            info.SetChanInfoType("WMA");
                            info.SetChanInfoStreamType("audio/x-ms-wma");
                            info.SetChanInfoStreamExt(".wma");
                        }
                        else
                        {
                            info.SetChanInfoType("ASF");
                            info.SetChanInfoStreamType("video/x-ms-asf");
                            info.SetChanInfoStreamExt(".asf");
                        }
                        res.ChannelInfo   = new ChannelInfo(info);
                        res.ContentHeader = new Content(pos, chunk.ToByteArray());
                        pos += chunk.TotalLength;
                    }
                    break;

                    case ASFChunk.ChunkType.Data:
                        if (res.Contents == null)
                        {
                            res.Contents = new System.Collections.Generic.List <Content>();
                        }
                        res.Contents.Add(new Content(pos, chunk.ToByteArray()));
                        pos += chunk.TotalLength;
                        break;

                    case ASFChunk.ChunkType.Unknown:
                        break;
                    }
                }
            }
            catch (EndOfStreamException) {
                if (chunks == 0)
                {
                    throw;
                }
            }
            return(res);
        }
Esempio n. 10
0
        public ParsedContent Read(Stream stream)
        {
            var res       = new ParsedContent();
            var bodies    = new List <Element>();
            var info      = new AtomCollection(Channel.ChannelInfo.Extra);
            var processed = false;
            var eos       = false;

            while (!eos)
            {
                var start_pos = stream.Position;
                try {
                    var elt = Element.ReadHeader(stream);
                    if (ebml.MaxIDLength < elt.ID.Length ||
                        ebml.MaxSizeLength < elt.Size.Length)
                    {
                        throw new BadDataException();
                    }
                    switch (state)
                    {
                    case ReaderState.EBML:
                        if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            elt.ReadBody(stream);
                            ebml  = new EBML(elt);
                            state = ReaderState.Segment;
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                        break;

                    case ReaderState.Segment:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            segment = new Segment(elt);
                            state   = ReaderState.EndOfHeader;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.EBML;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Void) ||
                                 elt.ID.BinaryEquals(Elements.CRC32))
                        {
                            elt.ReadBody(stream);
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                        break;

                    case ReaderState.EndOfHeader:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Segment;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.EBML;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Cluster;
                            clusters.Clear();
                            MemoryStream header;
                            using (header = new MemoryStream()) {
                                ebml.Element.Write(header);
                                segment.Element.Write(header);
                                foreach (var c in segment.HeaderElements)
                                {
                                    c.Write(header);
                                }
                            }
                            res.ContentHeader = new Content(0, header.ToArray());
                            if (ebml.DocType == "webm")
                            {
                                info.SetChanInfoType("WEBM");
                                info.SetChanInfoStreamType("video/webm");
                                info.SetChanInfoStreamExt(".webm");
                            }
                            else
                            {
                                info.SetChanInfoType("MKV");
                                info.SetChanInfoStreamType("video/x-matroska");
                                info.SetChanInfoStreamExt(".mkv");
                            }
                            res.ChannelInfo = new ChannelInfo(info);
                        }
                        else
                        {
                            elt.ReadBody(stream);
                            segment.AddHeader(elt);
                        }
                        break;

                    case ReaderState.Cluster:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Segment;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.EBML;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            if (clusters.Count > 0)
                            {
                                var timespan = clusters.Sum(c => c.Timespan);
                                if (timespan >= 30.0)
                                {
                                    var sz   = clusters.Sum(c => c.Timespan > 0 ? c.BlockSize : 0);
                                    var kbps = (int)((sz * 8 / timespan + 900) / 1000.0);
                                    info.SetChanInfoBitrate(kbps);
                                    res.ChannelInfo = new ChannelInfo(info);
                                    while (clusters.Count > 1)
                                    {
                                        clusters.RemoveFirst();
                                    }
                                }
                            }
                            var cluster = new Cluster(elt);
                            clusters.AddLast(cluster);
                            bodies.Add(elt);
                            state = ReaderState.Timecode;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Void) ||
                                 elt.ID.BinaryEquals(Elements.CRC32))
                        {
                            elt.ReadBody(stream);
                            bodies.Add(elt);
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                        break;

                    case ReaderState.Timecode:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Segment;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.EBML;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Cluster;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Timecode))
                        {
                            elt.ReadBody(stream);
                            if (clusters.Last != null)
                            {
                                clusters.Last.Value.Timecode =
                                    Element.ReadUInt(new MemoryStream(elt.Data), elt.Data.Length) * (segment.TimecodeScale / 1000000000.0);
                                if (clusters.Count > 1)
                                {
                                    clusters.Last.Previous.Value.Timespan = clusters.Last.Value.Timecode - clusters.Last.Previous.Value.Timecode;
                                }
                            }
                            bodies.Add(elt);
                            state = ReaderState.Block;
                        }
                        else if (elt.ID.BinaryEquals(Elements.SimpleBlock) ||
                                 elt.ID.BinaryEquals(Elements.BlockGroup))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Block;
                            continue;
                        }
                        else
                        {
                            elt.ReadBody(stream);
                            bodies.Add(elt);
                        }
                        break;

                    case ReaderState.Block:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Segment;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.EBML;
                            continue;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Cluster;
                            continue;
                        }
                        else if ((elt.ID.BinaryEquals(Elements.SimpleBlock) ||
                                  elt.ID.BinaryEquals(Elements.BlockGroup)) &&
                                 (clusters.Last.Value.BlockID == null ||
                                  elt.ID.BinaryEquals(clusters.Last.Value.BlockID)))
                        {
                            elt.ReadBody(stream);
                            clusters.Last.Value.BlockSize += elt.Size.Value;
                            clusters.Last.Value.BlockID    = elt.ID.Binary;
                            bodies.Add(elt);
                        }
                        else if (clusters.Last.Value.BlockID == null)
                        {
                            elt.ReadBody(stream);
                            bodies.Add(elt);
                        }
                        else
                        {
                            stream.Position = elt.Position;
                            state           = ReaderState.Cluster;
                            continue;
                        }
                        break;
                    }
                    processed = true;
                }
                catch (EndOfStreamException) {
                    if (!processed)
                    {
                        throw;
                    }
                    stream.Position = start_pos;
                    eos             = true;
                }
                catch (BadDataException) {
                    stream.Position = start_pos + 1;
                }
            }
            if (res.ContentHeader != null)
            {
                position =
                    res.ContentHeader.Position +
                    res.ContentHeader.Data.Length;
            }
            if (bodies.Count > 0)
            {
                res.Contents = new List <Content>();
                foreach (var body in bodies)
                {
                    MemoryStream s;
                    using (s = new MemoryStream()) {
                        body.Write(s);
                    }
                    var data = s.ToArray();
                    res.Contents.Add(new Content(position, data));
                    position += data.Length;
                }
            }
            return(res);
        }
Esempio n. 11
0
 private ChannelInfo CreateChannelInfo(BroadcastViewModel viewModel)
 {
     var info = new AtomCollection();
       if (viewModel.bitrate.HasValue) info.SetChanInfoBitrate(viewModel.bitrate.Value);
       info.SetChanInfoName(viewModel.channelName);
       info.SetChanInfoGenre(viewModel.genre);
       info.SetChanInfoDesc(viewModel.description);
       info.SetChanInfoComment(viewModel.comment);
       info.SetChanInfoURL(viewModel.contactUrl);
       return new ChannelInfo(info);
 }
Esempio n. 12
0
 public ParsedContent Read(Stream stream)
 {
     var res = new ParsedContent();
       var bodies = new List<Element>();
       var info = new AtomCollection(Channel.ChannelInfo.Extra);
       var processed = false;
       var eos = false;
       while (!eos) {
     var start_pos = stream.Position;
     try {
       var elt = Element.ReadHeader(stream);
       if (ebml.MaxIDLength  <elt.ID.Length ||
       ebml.MaxSizeLength<elt.Size.Length) {
     throw new BadDataException();
       }
       switch (state) {
       case ReaderState.EBML:
     if (elt.ID.BinaryEquals(Elements.EBML)) {
       elt.ReadBody(stream);
       ebml = new EBML(elt);
       state = ReaderState.Segment;
     }
     else {
       throw new BadDataException();
     }
     break;
       case ReaderState.Segment:
     if (elt.ID.BinaryEquals(Elements.Segment)) {
       segment = new Segment(elt);
       state = ReaderState.EndOfHeader;
     }
     else if (elt.ID.BinaryEquals(Elements.EBML)) {
       stream.Position = elt.Position;
       state = ReaderState.EBML;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.Void) ||
              elt.ID.BinaryEquals(Elements.CRC32)) {
       elt.ReadBody(stream);
     }
     else {
       throw new BadDataException();
     }
     break;
       case ReaderState.EndOfHeader:
     if (elt.ID.BinaryEquals(Elements.Segment)) {
       stream.Position = elt.Position;
       state = ReaderState.Segment;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.EBML)) {
       stream.Position = elt.Position;
       state = ReaderState.EBML;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.Cluster)) {
       stream.Position = elt.Position;
       state = ReaderState.Cluster;
       clusters.Clear();
       MemoryStream header;
       using (header=new MemoryStream()) {
         ebml.Element.Write(header);
         segment.Element.Write(header);
         foreach (var c in segment.HeaderElements) {
           c.Write(header);
         }
       }
       streamIndex = Channel.GenerateStreamID();
       streamOrigin = DateTime.Now;
       res.ContentHeader = new Content(streamIndex, TimeSpan.Zero, 0, header.ToArray());
       if (ebml.DocType=="webm") {
         info.SetChanInfoType("WEBM");
         info.SetChanInfoStreamType("video/webm");
         info.SetChanInfoStreamExt(".webm");
       }
       else {
         info.SetChanInfoType("MKV");
         info.SetChanInfoStreamType("video/x-matroska");
         info.SetChanInfoStreamExt(".mkv");
       }
       res.ChannelInfo = new ChannelInfo(info);
     }
     else {
       elt.ReadBody(stream);
       segment.AddHeader(elt);
     }
     break;
       case ReaderState.Cluster:
     if (elt.ID.BinaryEquals(Elements.Segment)) {
       stream.Position = elt.Position;
       state = ReaderState.Segment;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.EBML)) {
       stream.Position = elt.Position;
       state = ReaderState.EBML;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.Cluster)) {
       if (clusters.Count>0) {
         var timespan = clusters.Sum(c => c.Timespan);
         if (timespan>=30.0) {
           var sz = clusters.Sum(c => c.Timespan>0 ? c.BlockSize : 0);
           var kbps = (int)((sz*8/timespan+900) / 1000.0);
           info.SetChanInfoBitrate(kbps);
           res.ChannelInfo = new ChannelInfo(info);
           while (clusters.Count>1) clusters.RemoveFirst();
         }
       }
       var cluster = new Cluster(elt);
       clusters.AddLast(cluster);
       bodies.Add(elt);
       state = ReaderState.Timecode;
     }
     else if (elt.ID.BinaryEquals(Elements.Void) ||
              elt.ID.BinaryEquals(Elements.CRC32)) {
       elt.ReadBody(stream);
       bodies.Add(elt);
     }
     else {
       throw new BadDataException();
     }
     break;
       case ReaderState.Timecode:
     if (elt.ID.BinaryEquals(Elements.Segment)) {
       stream.Position = elt.Position;
       state = ReaderState.Segment;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.EBML)) {
       stream.Position = elt.Position;
       state = ReaderState.EBML;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.Cluster)) {
       stream.Position = elt.Position;
       state = ReaderState.Cluster;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.Timecode)) {
       elt.ReadBody(stream);
       if (clusters.Last!=null) {
         clusters.Last.Value.Timecode =
           Element.ReadUInt(new MemoryStream(elt.Data), elt.Data.Length)*(segment.TimecodeScale/1000000000.0);
         if (clusters.Count>1) {
           clusters.Last.Previous.Value.Timespan = clusters.Last.Value.Timecode - clusters.Last.Previous.Value.Timecode;
         }
       }
       bodies.Add(elt);
       state = ReaderState.Block;
     }
     else if (elt.ID.BinaryEquals(Elements.SimpleBlock) ||
              elt.ID.BinaryEquals(Elements.BlockGroup)) {
       stream.Position = elt.Position;
       state = ReaderState.Block;
       continue;
     }
     else {
       elt.ReadBody(stream);
       bodies.Add(elt);
     }
     break;
       case ReaderState.Block:
     if (elt.ID.BinaryEquals(Elements.Segment)) {
       stream.Position = elt.Position;
       state = ReaderState.Segment;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.EBML)) {
       stream.Position = elt.Position;
       state = ReaderState.EBML;
       continue;
     }
     else if (elt.ID.BinaryEquals(Elements.Cluster)) {
       stream.Position = elt.Position;
       state = ReaderState.Cluster;
       continue;
     }
     else if ((elt.ID.BinaryEquals(Elements.SimpleBlock) ||
               elt.ID.BinaryEquals(Elements.BlockGroup)) &&
              (clusters.Last.Value.BlockID==null ||
               elt.ID.BinaryEquals(clusters.Last.Value.BlockID))) {
       elt.ReadBody(stream);
       clusters.Last.Value.BlockSize += elt.Size.Value;
       clusters.Last.Value.BlockID    = elt.ID.Binary;
       bodies.Add(elt);
     }
     else if (clusters.Last.Value.BlockID==null) {
       elt.ReadBody(stream);
       bodies.Add(elt);
     }
     else {
       stream.Position = elt.Position;
       state = ReaderState.Cluster;
       continue;
     }
     break;
       }
       processed = true;
     }
     catch (EndOfStreamException) {
       if (!processed) throw;
       stream.Position = start_pos;
       eos = true;
     }
     catch (BadDataException) {
       stream.Position = start_pos+1;
     }
       }
       if (res.ContentHeader!=null) {
     position =
       res.ContentHeader.Position +
       res.ContentHeader.Data.Length;
       }
       if (bodies.Count>0) {
     res.Contents = new List<Content>();
     foreach (var body in bodies) {
       MemoryStream s;
       using (s=new MemoryStream()) {
     body.Write(s);
       }
       var data = s.ToArray();
       res.Contents.Add(new Content(streamIndex, DateTime.Now-streamOrigin, position, data));
       position += data.Length;
     }
       }
       return res;
 }
        public async Task ReadAsync(IContentSink sink, Stream stream, CancellationToken cancel_token)
        {
            var state          = ReaderState.EBML;
            var position       = 0L;
            var stream_index   = -1;
            var stream_origin  = DateTime.Now;
            var timecode_scale = 1000000.0;
            var ebml           = new EBML();
            var clusters       = new LinkedList <Cluster>();
            var headers        = new List <Element>();

            var eos = false;

            while (!eos)
            {
                try {
                    var elt = await Element.ReadHeaderAsync(stream, cancel_token).ConfigureAwait(false);

                    if (ebml.MaxIDLength < elt.ID.Length ||
                        ebml.MaxSizeLength < elt.Size.Length)
                    {
                        throw new BadDataException();
                    }
parse_retry:
                    switch (state)
                    {
                    case ReaderState.EBML:
                        if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            headers.Clear();
                            headers.Add(elt);
                            ebml  = new EBML(elt);
                            state = ReaderState.Segment;
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                        break;

                    case ReaderState.Segment:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            headers.Add(elt);
                            state = ReaderState.EndOfHeader;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            state = ReaderState.EBML;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Void) ||
                                 elt.ID.BinaryEquals(Elements.CRC32))
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            headers.Add(elt);
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                        break;

                    case ReaderState.EndOfHeader:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            state = ReaderState.Segment;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            state = ReaderState.EBML;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            clusters.Clear();
                            MemoryStream header;
                            using (header = new MemoryStream()) {
                                foreach (var c in headers)
                                {
                                    c.Write(header);
                                }
                            }
                            headers.Clear();

                            stream_index  = Channel.GenerateStreamID();
                            stream_origin = DateTime.Now;
                            position      = 0;
                            sink.OnContentHeader(
                                new Content(stream_index, TimeSpan.Zero, 0, header.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += header.ToArray().LongLength;
                            var info = new AtomCollection();
                            if (ebml.DocType == "webm")
                            {
                                info.SetChanInfoType("WEBM");
                                info.SetChanInfoStreamType("video/webm");
                                info.SetChanInfoStreamExt(".webm");
                            }
                            else
                            {
                                info.SetChanInfoType("MKV");
                                info.SetChanInfoStreamType("video/x-matroska");
                                info.SetChanInfoStreamExt(".mkv");
                            }
                            sink.OnChannelInfo(new ChannelInfo(info));

                            state = ReaderState.Cluster;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Info))
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            var s = new MemoryStream(elt.Data);
                            while (s.Position < s.Length)
                            {
                                var child = Element.ReadHeader(s);
                                if (child.ID.BinaryEquals(Elements.TimecodeScale))
                                {
                                    timecode_scale = Element.ReadUInt(s, child.Size.Value) * 1.0;
                                }
                                else
                                {
                                    child.ReadBody(s);
                                }
                            }
                            headers.Add(elt);
                        }
                        else
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            headers.Add(elt);
                        }
                        break;

                    case ReaderState.Cluster:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            state = ReaderState.Segment;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            state = ReaderState.EBML;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            if (clusters.Count > 0)
                            {
                                var timespan = clusters.Sum(c => c.Timespan);
                                if (timespan >= 30.0)
                                {
                                    var sz   = clusters.Sum(c => c.Timespan > 0 ? c.BlockSize : 0);
                                    var kbps = (int)((sz * 8 / timespan + 900) / 1000.0);
                                    var info = new AtomCollection();
                                    info.SetChanInfoBitrate(kbps);
                                    sink.OnChannelInfo(new ChannelInfo(info));
                                    while (clusters.Count > 1)
                                    {
                                        clusters.RemoveFirst();
                                    }
                                }
                            }
                            var cluster = new Cluster(elt);
                            clusters.AddLast(cluster);
                            sink.OnContent(
                                new Content(stream_index, DateTime.Now - stream_origin, position, elt.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += elt.ByteSize;
                            state     = ReaderState.Timecode;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Void) ||
                                 elt.ID.BinaryEquals(Elements.CRC32))
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            sink.OnContent(
                                new Content(stream_index, DateTime.Now - stream_origin, position, elt.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += elt.ByteSize;
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                        break;

                    case ReaderState.Timecode:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            state = ReaderState.Segment;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            state = ReaderState.EBML;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            state = ReaderState.Cluster;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.SimpleBlock) ||
                                 elt.ID.BinaryEquals(Elements.BlockGroup))
                        {
                            state = ReaderState.Block;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Timecode))
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            if (clusters.Last != null)
                            {
                                clusters.Last.Value.Timecode =
                                    Element.ReadUInt(new MemoryStream(elt.Data), elt.Data.Length) * (timecode_scale / 1000000000.0);
                                if (clusters.Count > 1)
                                {
                                    clusters.Last.Previous.Value.Timespan = clusters.Last.Value.Timecode - clusters.Last.Previous.Value.Timecode;
                                }
                            }
                            sink.OnContent(
                                new Content(stream_index, DateTime.Now - stream_origin, position, elt.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += elt.ByteSize;
                            state     = ReaderState.Block;
                        }
                        else
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            sink.OnContent(
                                new Content(stream_index, DateTime.Now - stream_origin, position, elt.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += elt.ByteSize;
                        }
                        break;

                    case ReaderState.Block:
                        if (elt.ID.BinaryEquals(Elements.Segment))
                        {
                            state = ReaderState.Segment;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.EBML))
                        {
                            state = ReaderState.EBML;
                            goto parse_retry;
                        }
                        else if (elt.ID.BinaryEquals(Elements.Cluster))
                        {
                            state = ReaderState.Cluster;
                            goto parse_retry;
                        }
                        else if ((elt.ID.BinaryEquals(Elements.SimpleBlock) ||
                                  elt.ID.BinaryEquals(Elements.BlockGroup)) &&
                                 (clusters.Last.Value.BlockID == null ||
                                  elt.ID.BinaryEquals(clusters.Last.Value.BlockID)))
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            clusters.Last.Value.BlockSize += elt.Size.Value;
                            clusters.Last.Value.BlockID    = elt.ID.Binary;
                            sink.OnContent(
                                new Content(stream_index, DateTime.Now - stream_origin, position, elt.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += elt.ByteSize;
                        }
                        else if (clusters.Last.Value.BlockID == null)
                        {
                            await elt.ReadBodyAsync(stream, cancel_token).ConfigureAwait(false);

                            sink.OnContent(
                                new Content(stream_index, DateTime.Now - stream_origin, position, elt.ToArray(), PCPChanPacketContinuation.None)
                                );
                            position += elt.ByteSize;
                        }
                        else
                        {
                            state = ReaderState.Cluster;
                            goto parse_retry;
                        }
                        break;
                    }
                }
                catch (EndOfStreamException) {
                    eos = true;
                }
                catch (BadDataException) {
                }
            }
        }
Esempio n. 14
0
    public async Task ReadAsync(IContentSink sink, Stream stream, CancellationToken cancel_token)
    {
      var state = ReaderState.EBML;
      var position = 0L;
      var stream_index = -1;
      var stream_origin = DateTime.Now;
      var timecode_scale = 1000000.0;
      var ebml     = new EBML();
      var clusters = new LinkedList<Cluster>();
      var headers  = new List<Element>();

      var eos = false;
      while (!eos) {
        try {
          var elt = await Element.ReadHeaderAsync(stream, cancel_token);
          if (ebml.MaxIDLength  <elt.ID.Length ||
              ebml.MaxSizeLength<elt.Size.Length) {
            throw new BadDataException();
          }
        parse_retry:
          switch (state) {
          case ReaderState.EBML:
            if (elt.ID.BinaryEquals(Elements.EBML)) {
              await elt.ReadBodyAsync(stream, cancel_token);
              headers.Clear();
              headers.Add(elt);
              ebml = new EBML(elt);
              state = ReaderState.Segment;
            }
            else {
              throw new BadDataException();
            }
            break;
          case ReaderState.Segment:
            if (elt.ID.BinaryEquals(Elements.Segment)) {
              headers.Add(elt);
              state = ReaderState.EndOfHeader;
            }
            else if (elt.ID.BinaryEquals(Elements.EBML)) {
              state = ReaderState.EBML;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Void) ||
                     elt.ID.BinaryEquals(Elements.CRC32)) {
              await elt.ReadBodyAsync(stream, cancel_token);
              headers.Add(elt);
            }
            else {
              throw new BadDataException();
            }
            break;
          case ReaderState.EndOfHeader:
            if (elt.ID.BinaryEquals(Elements.Segment)) {
              state = ReaderState.Segment;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.EBML)) {
              state = ReaderState.EBML;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Cluster)) {
              clusters.Clear();
              MemoryStream header;
              using (header=new MemoryStream()) {
                foreach (var c in headers) {
                  c.Write(header);
                }
              }
              headers.Clear();

              stream_index  = Channel.GenerateStreamID();
              stream_origin = DateTime.Now;
              position = 0;
              sink.OnContentHeader(
                new Content(stream_index, TimeSpan.Zero, 0, header.ToArray())
              );
              position += header.ToArray().LongLength;
              var info = new AtomCollection();
              if (ebml.DocType=="webm") {
                info.SetChanInfoType("WEBM");
                info.SetChanInfoStreamType("video/webm");
                info.SetChanInfoStreamExt(".webm");
              }
              else {
                info.SetChanInfoType("MKV");
                info.SetChanInfoStreamType("video/x-matroska");
                info.SetChanInfoStreamExt(".mkv");
              }
              sink.OnChannelInfo(new ChannelInfo(info));

              state = ReaderState.Cluster;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Info)) {
              await elt.ReadBodyAsync(stream, cancel_token);
              var s = new MemoryStream(elt.Data);
              while (s.Position<s.Length) {
                var child = Element.ReadHeader(s);
                if (child.ID.BinaryEquals(Elements.TimecodeScale)) {
                  timecode_scale = Element.ReadUInt(s, child.Size.Value) * 1.0;
                }
                else {
                  child.ReadBody(s);
                }
              }
              headers.Add(elt);
            }
            else {
              await elt.ReadBodyAsync(stream, cancel_token);
              headers.Add(elt);
            }
            break;
          case ReaderState.Cluster:
            if (elt.ID.BinaryEquals(Elements.Segment)) {
              state = ReaderState.Segment;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.EBML)) {
              state = ReaderState.EBML;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Cluster)) {
              if (clusters.Count>0) {
                var timespan = clusters.Sum(c => c.Timespan);
                if (timespan>=30.0) {
                  var sz = clusters.Sum(c => c.Timespan>0 ? c.BlockSize : 0);
                  var kbps = (int)((sz*8/timespan+900) / 1000.0);
                  var info = new AtomCollection();
                  info.SetChanInfoBitrate(kbps);
                  sink.OnChannelInfo(new ChannelInfo(info));
                  while (clusters.Count>1) clusters.RemoveFirst();
                }
              }
              var cluster = new Cluster(elt);
              clusters.AddLast(cluster);
              sink.OnContent(
                new Content(stream_index, DateTime.Now-stream_origin, position, elt.ToArray())
              );
              position += elt.ByteSize;
              state = ReaderState.Timecode;
            }
            else if (elt.ID.BinaryEquals(Elements.Void) ||
                     elt.ID.BinaryEquals(Elements.CRC32)) {
              await elt.ReadBodyAsync(stream, cancel_token);
              sink.OnContent(
                new Content(stream_index, DateTime.Now-stream_origin, position, elt.ToArray())
              );
              position += elt.ByteSize;
            }
            else {
              throw new BadDataException();
            }
            break;
          case ReaderState.Timecode:
            if (elt.ID.BinaryEquals(Elements.Segment)) {
              state = ReaderState.Segment;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.EBML)) {
              state = ReaderState.EBML;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Cluster)) {
              state = ReaderState.Cluster;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.SimpleBlock) ||
                     elt.ID.BinaryEquals(Elements.BlockGroup)) {
              state = ReaderState.Block;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Timecode)) {
              await elt.ReadBodyAsync(stream, cancel_token);
              if (clusters.Last!=null) {
                clusters.Last.Value.Timecode =
                  Element.ReadUInt(new MemoryStream(elt.Data), elt.Data.Length)*(timecode_scale/1000000000.0);
                if (clusters.Count>1) {
                  clusters.Last.Previous.Value.Timespan = clusters.Last.Value.Timecode - clusters.Last.Previous.Value.Timecode;
                }
              }
              sink.OnContent(
                new Content(stream_index, DateTime.Now-stream_origin, position, elt.ToArray())
              );
              position += elt.ByteSize;
              state = ReaderState.Block;
            }
            else {
              await elt.ReadBodyAsync(stream, cancel_token);
              sink.OnContent(
                new Content(stream_index, DateTime.Now-stream_origin, position, elt.ToArray())
              );
              position += elt.ByteSize;
            }
            break;
          case ReaderState.Block:
            if (elt.ID.BinaryEquals(Elements.Segment)) {
              state = ReaderState.Segment;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.EBML)) {
              state = ReaderState.EBML;
              goto parse_retry;
            }
            else if (elt.ID.BinaryEquals(Elements.Cluster)) {
              state = ReaderState.Cluster;
              goto parse_retry;
            }
            else if ((elt.ID.BinaryEquals(Elements.SimpleBlock) ||
                      elt.ID.BinaryEquals(Elements.BlockGroup)) &&
                     (clusters.Last.Value.BlockID==null ||
                      elt.ID.BinaryEquals(clusters.Last.Value.BlockID))) {
              await elt.ReadBodyAsync(stream, cancel_token);
              clusters.Last.Value.BlockSize += elt.Size.Value;
              clusters.Last.Value.BlockID    = elt.ID.Binary;
              sink.OnContent(
                new Content(stream_index, DateTime.Now-stream_origin, position, elt.ToArray())
              );
              position += elt.ByteSize;
            }
            else if (clusters.Last.Value.BlockID==null) {
              await elt.ReadBodyAsync(stream, cancel_token);
              sink.OnContent(
                new Content(stream_index, DateTime.Now-stream_origin, position, elt.ToArray())
              );
              position += elt.ByteSize;
            }
            else {
              state = ReaderState.Cluster;
              goto parse_retry;
            }
            break;
          }
        }
        catch (EndOfStreamException) {
          eos = true;
        }
        catch (BadDataException) {
        }
      }

    }
        public async Task ReadAsync(IContentSink sink, Stream stream, CancellationToken cancel_token)
        {
            int      streamIndex     = -1;
            DateTime streamOrigin    = DateTime.Now;
            long     contentPosition = 0;
            bool     eof             = false;

            do
            {
                ASFChunk chunk = null;
                try {
                    chunk = await ASFChunk.ReadAsync(stream, cancel_token).ConfigureAwait(false);
                }
                catch (EndOfStreamException) {
                    eof = true;
                    continue;
                }
                switch (chunk.KnownType)
                {
                case ASFChunk.ChunkType.Header:
                {
                    var header = ASFHeader.Read(chunk);
                    var info   = new AtomCollection(Channel.ChannelInfo.Extra);
                    info.SetChanInfoBitrate(header.Bitrate);
                    if (header.Streams.Any(type => type == ASFHeader.StreamType.Video))
                    {
                        info.SetChanInfoType("WMV");
                        info.SetChanInfoStreamType("video/x-ms-wmv");
                        info.SetChanInfoStreamExt(".wmv");
                    }
                    else if (header.Streams.Any(type => type == ASFHeader.StreamType.Audio))
                    {
                        info.SetChanInfoType("WMA");
                        info.SetChanInfoStreamType("audio/x-ms-wma");
                        info.SetChanInfoStreamExt(".wma");
                    }
                    else
                    {
                        info.SetChanInfoType("ASF");
                        info.SetChanInfoStreamType("video/x-ms-asf");
                        info.SetChanInfoStreamExt(".asf");
                    }
                    sink.OnChannelInfo(new ChannelInfo(info));
                    streamIndex     = Channel.GenerateStreamID();
                    streamOrigin    = DateTime.Now;
                    contentPosition = 0;
                    var data = chunk.ToByteArray();
                    sink.OnContentHeader(new Content(streamIndex, TimeSpan.Zero, contentPosition, data, PCPChanPacketContinuation.None));
                    contentPosition += data.Length;
                    break;
                }

                case ASFChunk.ChunkType.Data:
                {
                    var data = chunk.ToByteArray();
                    sink.OnContent(
                        new Content(streamIndex, DateTime.Now - streamOrigin, contentPosition, chunk.ToByteArray(), PCPChanPacketContinuation.None)
                        );
                    contentPosition += data.Length;
                }
                break;

                case ASFChunk.ChunkType.Unknown:
                    break;
                }
            } while (!eof);
        }
Esempio n. 16
0
        public ParsedContent Read(Stream stream)
        {
            var res       = new ParsedContent();
            var info      = new AtomCollection(Channel.ChannelInfo.Extra);
            var processed = false;
            var eos       = false;

            while (!eos)
            {
                var start_pos = stream.Position;
                try {
                    switch (state)
                    {
                    case ReaderState.Header:
                    {
                        var bin    = ReadBytes(stream, 13);
                        var header = new FileHeader(bin);
                        if (header.IsValid)
                        {
                            Logger.Info("FLV Header found");
                            fileHeader        = header;
                            bin               = header.Binary;
                            res.ContentHeader = new Content(position, bin);
                            res.Contents      = null;
                            info.SetChanInfoType("FLV");
                            info.SetChanInfoStreamType("video/x-flv");
                            info.SetChanInfoStreamExt(".flv");
                            res.ChannelInfo = new ChannelInfo(info);
                            position        = bin.Length;
                            tags.Clear();
                            state = ReaderState.Body;
                        }
                        else
                        {
                            throw new BadDataException();
                        }
                    }
                    break;

                    case ReaderState.Body:
                    {
                        var bin        = ReadBytes(stream, 11);
                        var read_valid = false;
                        var body       = new FLVTag(bin);
                        if (body.IsValidHeader)
                        {
                            body.ReadBody(stream);
                            body.ReadFooter(stream);
                            if (body.IsValidFooter)
                            {
                                read_valid = true;
                                bin        = body.Binary;
                                if (res.Contents == null)
                                {
                                    res.Contents = new List <Content>();
                                }
                                res.Contents.Add(new Content(position, bin));
                                tags.AddLast(new TagDesc {
                                        Timestamp = body.Timestamp / 1000.0, DataSize = body.DataSize
                                    });
                                var timespan = tags.Last.Value.Timestamp - tags.First.Value.Timestamp;
                                if (timespan >= 30.0)
                                {
                                    var sz = tags.Take(tags.Count - 1).Sum(t => t.DataSize);
                                    info.SetChanInfoBitrate((int)(sz * 8 / timespan + 900) / 1000);
                                    res.ChannelInfo = new ChannelInfo(info);
                                    while (tags.Count > 1)
                                    {
                                        tags.RemoveFirst();
                                    }
                                }
                                position += bin.Length;
                            }
                        }
                        if (!read_valid)
                        {
                            stream.Position = start_pos;
                            var header = new FileHeader(ReadBytes(stream, 13));
                            if (header.IsValid)
                            {
                                Logger.Info("New FLV Header found");
                                read_valid        = true;
                                fileHeader        = header;
                                bin               = header.Binary;
                                res.ContentHeader = new Content(0, bin);
                                res.Contents      = null;
                                info.SetChanInfoType("FLV");
                                info.SetChanInfoStreamType("video/x-flv");
                                info.SetChanInfoStreamExt(".flv");
                                res.ChannelInfo = new ChannelInfo(info);
                                tags.Clear();
                                position = bin.Length;
                            }
                        }
                        if (!read_valid)
                        {
                            throw new BadDataException();
                        }
                    }
                    break;
                    }
                    processed = true;
                }
                catch (EndOfStreamException) {
                    if (!processed)
                    {
                        throw;
                    }
                    stream.Position = start_pos;
                    eos             = true;
                }
                catch (BadDataException) {
                    stream.Position = start_pos + 1;
                }
            }
            return(res);
        }
Esempio n. 17
0
 public ParsedContent Read(Stream stream)
 {
     var res = new ParsedContent();
       var info = new AtomCollection(Channel.ChannelInfo.Extra);
       var processed = false;
       var eos = false;
       while (!eos) {
     var start_pos = stream.Position;
     try {
       switch (state) {
       case ReaderState.Header:
     {
       var bin = ReadBytes(stream, 13);
       var header = new FileHeader(bin);
       if (header.IsValid) {
         Logger.Info("FLV Header found");
         fileHeader = header;
         bin = header.Binary;
         res.ContentHeader = new Content(position, bin);
         res.Contents = null;
         info.SetChanInfoType("FLV");
         info.SetChanInfoStreamType("video/x-flv");
         info.SetChanInfoStreamExt(".flv");
         res.ChannelInfo = new ChannelInfo(info);
         position = bin.Length;
         tags.Clear();
         state = ReaderState.Body;
       }
       else {
         throw new BadDataException();
       }
     }
     break;
       case ReaderState.Body:
     {
       var bin = ReadBytes(stream, 11);
       var read_valid = false;
       var body = new FLVTag(bin);
       if (body.IsValidHeader) {
         body.ReadBody(stream);
         body.ReadFooter(stream);
         if (body.IsValidFooter) {
           read_valid = true;
           bin = body.Binary;
           if (res.Contents==null) res.Contents = new List<Content>();
           res.Contents.Add(new Content(position, bin));
           tags.AddLast(new TagDesc { Timestamp=body.Timestamp/1000.0, DataSize=body.DataSize });
           var timespan = tags.Last.Value.Timestamp-tags.First.Value.Timestamp;
           if (timespan>=30.0) {
             var sz = tags.Take(tags.Count-1).Sum(t => t.DataSize);
             info.SetChanInfoBitrate((int)(sz*8/timespan+900)/1000);
             res.ChannelInfo = new ChannelInfo(info);
             while (tags.Count>1) tags.RemoveFirst();
           }
           position += bin.Length;
         }
       }
       if (!read_valid) {
         stream.Position = start_pos;
         var header = new FileHeader(ReadBytes(stream, 13));
         if (header.IsValid) {
           Logger.Info("New FLV Header found");
           read_valid = true;
           fileHeader = header;
           bin = header.Binary;
           res.ContentHeader = new Content(0, bin);
           res.Contents = null;
           info.SetChanInfoType("FLV");
           info.SetChanInfoStreamType("video/x-flv");
           info.SetChanInfoStreamExt(".flv");
           res.ChannelInfo = new ChannelInfo(info);
           tags.Clear();
           position = bin.Length;
         }
       }
       if (!read_valid) throw new BadDataException();
     }
     break;
       }
       processed = true;
     }
     catch (EndOfStreamException) {
       if (!processed) throw;
       stream.Position = start_pos;
       eos = true;
     }
     catch (BadDataException) {
       stream.Position = start_pos+1;
     }
       }
       return res;
 }