public async Task <Tag> GetNextTag(Stream stream) { Tag t = new Tag(); byte[] header = new byte[11]; byte[] remainder = new byte[4]; stream.Read(header, 0, 11); t.Type = header[0]; t.PacketSize = header[1] << 16 | header[2] << 8 | header[3] & 255; t.TimeStamp = (header[7] << 24 | header[4] << 16 | header[5] << 8 | header[6] & 255) & 0x7FFFFFFF; t.Remainder = new byte[3]; Array.Copy(header, 8, t.Remainder, 0, 3); byte[] data = new byte[t.PacketSize]; stream.Read(data, 0, t.PacketSize); stream.Read(remainder, 0, 4); Array.Reverse(remainder); t.TotalSize = BitConverter.ToInt32(remainder, 0); t.NeedDecryption = false; if (t.Type == 10 || t.Type == 11) { t.Type -= 2; byte tp = data[12]; int pos = 13; if ((tp & 2) > 0) { pos += 16; } if ((tp & 4) > 0) { StringBuilder bld = new StringBuilder(); byte b = data[pos++]; while (b != 0) { bld.Append((char)b); b = data[pos++]; } string nurl = bld.ToString(); if (nurl != KeyUrl) { Uri bas = new Uri(baseurl); string url = string.Format(FormatKey, bas.Scheme + "://" + bas.Host + nurl, guid, manifest.Pv20.Substring(1) + "&hdcore=3.2.0"); int idx = nurl.IndexOf("_"); keydata = nurl.Substring(idx); WebStream ws = await GetStream(url); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ws?.Dispose(); throw new IOException("Error " + ws.StatusCode + " trying to download fragment"); } KeyData = new byte[ws.ContentLength]; await ws.ReadAsync(KeyData, 0, (int)ws.ContentLength); ws.Dispose(); KeyUrl = nurl; } } t.NeedDecryption = true; t.Key = KeyData; } t.Packet = data; t.PacketSize = data.Length; return(t); }