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); }
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); }