Exemple #1
0
        public void DownloadFragment(TagsStore tagsStore)
        {
            string fragmentUrl = media.GetFragmentUrl(fragIndex);

            Program.DebugLog("Fragment Url: " + fragmentUrl);

            byte[] data    = HTTP.TryGETData(fragmentUrl, out int retCode, out string status);
            int    retries = 0;

            while (retCode >= 500 && retries <= MaxRetriesLoad)
            {
                System.Threading.Thread.Sleep(1000);
                retries++;
                data = HTTP.TryGETData(fragmentUrl, out retCode, out status);
            }
            if (retCode != 200)
            {
                string msg = "Download fragment failed " + fragIndex + "/" + media.TotalFragments + " code: " + retCode + " status: " + status;
                Program.DebugLog(msg);
                if (Program.verbose)
                {
                    Program.Message(msg);
                }
                if (media.Bootstrap.live)
                {
                    //media.CurrentFragmentIndex = media.TotalFragments;
                    tagsStore.Complete = true;
                    Done(media);
                    return;
                }
                else
                {
                    throw new InvalidOperationException(status);
                }
            }

            Program.DebugLog("Downloaded: fragment=" + fragIndex + "/" + media.TotalFragments + " lenght: " + data.Length);

            var boxes = Box.GetBoxes(data);

            if (boxes.Find(i => i.Type == F4FConstants.BOX_TYPE_MDAT) is MediaDataBox mdat)
            {
                lock (tagsStore) {
                    FLVTag.GetVideoAndAudioTags(tagsStore, mdat.data);
                    tagsStore.ARFA     = boxes.Find(i => i.Type == F4FConstants.BOX_TYPE_AFRA) as AdobeFragmentRandomAccessBox;
                    tagsStore.Complete = true;
                }
                HDSDownloader.LiveIsStalled = false;
            }
            else if (media.Bootstrap.live)
            {
                HDSDownloader.LiveIsStalled = true;
            }
            else
            {
                throw new InvalidOperationException("No found mdat box in fragment " + fragIndex + "/" + media.TotalFragments);
            }

            if (Program.verbose)
            {
                Program.Message(string.Format("Media: {0}  Downloaded: {1}  Data size: {2}", media.label, fragIndex, data.Length));
            }

            media.CurrentFragmentIndex++;
            media.Downloaded++;

            Done(media);
        }
        public byte[] Decrypt(byte[] data, long pos, string baseUrl, string auth)
        {
            if (debug)
            {
                Program.DebugLog("\n----- Akamai Decryption Start -----");
            }
            byte[] decryptedData = new byte[0];
            // Parse packet header
            using (MemoryStream ms = new MemoryStream(data)) {
                ms.Position = pos;
                using (HDSBinaryReader br = new HDSBinaryReader(ms)) {
                    int b = br.ReadByte();
                    ecmVersion = (b >> 4);
                    if (ecmVersion != 11)
                    {
                        ecmVersion = b;
                    }
                    ecmID          = br.ReadInt32();
                    ecmTimestamp   = (uint)br.ReadInt32();
                    kdfVersion     = br.ReadInt16();
                    dccAccReserved = br.ReadByte();

                    if (debug)
                    {
                        Program.DebugLog("ECM Version  : " + ecmVersion + ", ECM ID: " + ecmID + ", ECM Timestamp: " + ecmTimestamp + ", KDF Version: " + kdfVersion + ", DccAccReserved: " + dccAccReserved);
                    }
                    b = br.ReadByte();

                    bool iv  = ((b & 2) > 0);
                    bool key = ((b & 4) > 0);

                    if (iv)
                    {
                        packetIV = br.ReadBytes(16);
                        if (debug)
                        {
                            Program.DebugLog("PacketIV     : " + Hexlify(packetIV));
                        }
                    }

                    if (key)
                    {
                        sessionKeyUrl = br.ReadString();
                        if (debug)
                        {
                            Program.DebugLog("SessionKeyUrl: " + sessionKeyUrl);
                        }
                        string keyPath = sessionKeyUrl.Substring(sessionKeyUrl.LastIndexOf('/'));
                        string keyUrl  = HTTP.JoinUrl(baseUrl, keyPath) + auth;

                        // Download key file if required
                        if (sessionKeyUrl != lastKeyUrl)
                        {
                            if ((baseUrl.Length == 0) && (sessionKey.Length == 0))
                            {
                                if (debug)
                                {
                                    Program.DebugLog("Unable to download session key without manifest url. you must specify it manually using 'adkey' switch.");
                                }
                            }
                            else
                            {
                                if (baseUrl.Length > 0)
                                {
                                    if (debug)
                                    {
                                        Program.DebugLog("Downloading new session key from " + keyUrl);
                                    }
                                    byte[] downloadedData = HTTP.TryGETData(keyUrl, out int retCode, out string status);
                                    if (retCode == 200)
                                    {
                                        sessionID  = "_" + keyPath.Substring("/key_".Length);
                                        sessionKey = downloadedData;
                                    }
                                    else
                                    {
                                        if (debug)
                                        {
                                            Program.DebugLog("Failed to download new session key, Status: " + status + " (" + retCode + ")");
                                        }
                                        sessionID = "";
                                    }
                                }
                            }
                            lastKeyUrl = sessionKeyUrl;
                            if (sessionKey == null || sessionKey.Length == 0)
                            {
                                Program.Quit("Failed to download akamai session decryption key");
                            }
                        }
                    }

                    if (debug)
                    {
                        Program.DebugLog("SessionKey   : " + Hexlify(sessionKey));
                    }

                    if (sessionKey == null || sessionKey.Length < 1)
                    {
                        Program.Quit("ERROR: Fragments can't be decrypted properly without corresponding session key.");
                    }

                    byte reserved; byte[] reservedBlock1, reservedBlock2, encryptedData, lastBlockData;

                    reserved       = br.ReadByte();
                    packetSalt     = br.ReadBytes(32);
                    reservedBlock1 = br.ReadBytes(20);
                    reservedBlock2 = br.ReadBytes(20);
                    if (debug)
                    {
                        Program.DebugLog("ReservedByte : " + reserved + ", ReservedBlock1: " + Hexlify(reservedBlock1) + ", ReservedBlock2: " + Hexlify(reservedBlock2));
                    }

                    // Generate packet decryption key
                    KDF();

                    // Decrypt packet data
                    encryptedData = br.ReadBytes((int)decryptBytes);
                    lastBlockData = br.ReadToEnd();
                    if (decryptBytes > 0)
                    {
                        decryptedData = AesDecrypt(encryptedData, packetKey, packetIV);
                    }
                    decryptedData = F4FOldMethod.AppendBuf(decryptedData, lastBlockData);
                    if (debug)
                    {
                        Program.DebugLog("EncryptedData: " + Hexlify(encryptedData, 64));
                        Program.DebugLog("DecryptedData: " + Hexlify(decryptedData, 64));
                        Program.DebugLog("----- Akamai Decryption End -----\n");
                    }
                } // using (HDSBinaryReader br = new HDSBinaryReader(ms))
            }     // using (MemoryStream ms = new MemoryStream(data))

            return(decryptedData);
        }