Beispiel #1
0
        public async Task <bool> WriteFragmentAsync(byte[] frag)
        {
            var br = new BoxReader(frag);

            while (br.GetBoxType() != "mdat")
            {
                br.SkipBox();
            }
            br.SkipBoxHeader();

            br.Skip(4);
            int tsFrag = br.ReadByte() << 0x10 | br.ReadByte() << 0x8 | br.ReadByte() | br.ReadByte() << 0x18;

            br.Skip(-8);
            if (tsFrag < GetLastTagTimestamp()) // don't write aleady written fragment
            {
                return(false);
            }
            _fs.Seek(0, SeekOrigin.End);
            await _fs.WriteAsync(frag, br.Position, frag.Length - br.Position);

            return(true);
        }
Beispiel #2
0
        public static Segment GetSegmentFromBootstrapInfo(byte[] bootstrapInfo)
        {
            // parse bootstrap info box (abst)
            var bootstrap = new BoxReader(bootstrapInfo);

            // skip useless stuff
            bootstrap.SkipBoxHeader();
            bootstrap.Skip(1 + 3 + 4 + 1 + 4 + 8 + 8);
            bootstrap.SkipString();
            byte serverEntryCount = bootstrap.ReadByte();

            for (byte _ = 0; _ < serverEntryCount; _++)
            {
                bootstrap.SkipString();
            }
            byte qualityEntryCount = bootstrap.ReadByte();

            for (byte _ = 0; _ < qualityEntryCount; _++)
            {
                bootstrap.SkipString();
            }
            bootstrap.SkipString();
            bootstrap.SkipString();

            // get and parse (skip) segment run table (asrt) boxes
            // MEH: there COULD be more than 1 asrt box, ignoring them for now
            byte segmentRunTableCount = bootstrap.ReadByte();

            for (byte _ = 0; _ < segmentRunTableCount; _++)
            {
                bootstrap.SkipBox();
            }

            // get and parse fragment run table (afrt) boxes (MEH: keep only the last one)
            Segment segment = new Segment {
                Id = 1
            };
            byte fragmentRunTableCount = bootstrap.ReadByte();

            for (byte _ = 0; _ < fragmentRunTableCount; _++)
            {
                bootstrap.SkipBoxHeader();
                bootstrap.Skip(1 + 3 + 4);
                byte qualitySegmentUrlModifiers = bootstrap.ReadByte(); // hopefully this is 0 or 1
                for (byte __ = 0; __ < qualitySegmentUrlModifiers; __++)
                {
                    bootstrap.SkipString();
                }
                // this isn't really a segment, but whatever.
                var frags = new List <Fragment> {
                    new Fragment(0, 0, 0)
                };
                uint fragRuns = bootstrap.ReadUInt32();
                for (uint __ = 0; __ < fragRuns; __++)
                {
                    var      readFrag = new Fragment(bootstrap.ReadUInt32(), bootstrap.ReadUInt64(), bootstrap.ReadUInt32());
                    Fragment last     = frags.Last();
                    // hopefully they are already sorted by id
                    for (uint i = last.Id + 1; i < readFrag.Id; i++)
                    {
                        frags.Add(last = new Fragment(i, last.TimestampEnd.TotalMilliseconds, last.Duration));
                    }
                    if (readFrag.Id != 0)
                    {
                        frags.Add(readFrag);
                    }
                }
                segment.Fragments = frags.ToArray();
            }
            return(segment);
        }