예제 #1
0
        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);
        }