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