public XmlNodeEx LoadXml(string manifestUrl) { string xmlText = ""; if (string.IsNullOrEmpty(postData)) { xmlText = HTTP.GET(manifestUrl); } else { xmlText = HTTP.POST(manifestUrl, postData); } if (Program.RegExMatch(@"<r>\s*?<to>(.*?)</to>", xmlText, out string sDomain)) { if (Program.RegExMatch(@"^.*?://.*?/.*?/(.*)", manifestUrl, out manifestUrl)) { manifestUrl = sDomain + manifestUrl; xmlText = HTTP.GET(manifestUrl); } } xmlText = XmlValidate(xmlText); XmlDocumentEx xmldoc = new XmlDocumentEx(); try { xmldoc.LoadXml(xmlText); } catch (Exception e) { if (Regex.IsMatch(xmlText, @"<html.*?<body", RegexOptions.Singleline)) { throw new XmlException("Error loading manifest. Url redirected to html page. Check the manifest url.", e); } else { throw new XmlException("Error loading manifest. It's no valid xml file.", e); } } return((XmlNodeEx)xmldoc.DocumentElement); }
private static void GetLink_Rutube(string sLink) { string sData, sID = ""; Match m; m = Regex.Match(sLink, "/(\\d+)(/|$|\\?)"); if (m.Success) { sID = m.Groups[1].Value; } else { Quit("No id in rutube link"); } sLink = "http://rutube.ru/play/embed/" + sID; HTTP.Referer = sLink; sData = HTTP.GET("http://rutube.ru/api/play/options/" + sID + "/?format=json&sqr4374_compat=1&no_404=true&referer=" + Uri.EscapeDataString(sLink) + "&_=" + new Random()); m = Regex.Match(sData, "(http[^\">']+f4m[^\"}>']+)"); if (m.Success) { manifestUrl = m.Groups[1].Value; } }
private static void Check4KnownLinks(string sLink) { Match m; if (RegExMatch(@"radio-canada.ca.*?[Mm]edia[-=](\d+)", sLink, out string id)) { sLink = @"http://api.radio-canada.ca/validationMedia/v1/Validation.html?connectionType=broadband&output=json&multibitrate=true&deviceType=flashhd&appCode=medianet&idMedia=" + id + "&claims=null"; string text = HTTP.GET(sLink); RegExMatch("\"url\":\"(.*?)\"", text, out manifestUrl); } else if (Regex.IsMatch(sLink, "(moon.hdkinoteatr.com|moonwalk.\\w+)/\\w+/\\w+/iframe")) { GetLink_Moonwalk(sLink); } else if (Regex.IsMatch(sLink, "/megogo.net/")) { GetLink_Megogo(sLink); } else if (Regex.IsMatch(sLink, "/rutube.ru/")) { GetLink_Rutube(sLink); } else if (Regex.IsMatch(sLink, "spbtv.com/v1/channels/(.*?)/")) { m = Regex.Match(sLink, "spbtv.com/v1/channels/(.*?)/"); GetLink_spbtv(m.Groups[1].Value); } else if (Regex.IsMatch(sLink, "spbtv.online/channels/")) { string html = HTTP.GET(sLink); m = Regex.Match(html, "channelId\\s*:\\s*'(.*?)'"); if (m.Success) { GetLink_spbtv(m.Groups[1].Value); } } }
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); }
public void DownloadFragments(string manifestUrl) { HTTP cc = new HTTP(!Program.fproxy); this.ParseManifest(manifestUrl); this.segNum = this.segStart; this.fragNum = this.fragStart; if (this.start > 0) { this.segNum = this.GetSegmentFromFragment(start); this.fragNum = this.start - 1; this.segStart = this.segNum; this.fragStart = this.fragNum; } string remaining = ""; string sDuration = ""; int downloaded = 0; this.filesize = 0; bool usedThreads = (this.threads > 1) && !this.live; int retCode; byte[] fragmentData = new byte[0]; this.lastFrag = this.fragNum; if (this.fragNum >= this.fragCount) Program.Quit("<c:Red>No fragment available for downloading"); if (isHttpUrl(this.selectedMedia.url)) this.fragUrl = this.selectedMedia.url; else this.fragUrl = NormalizePath(this.baseUrl + "/" + this.selectedMedia.url); this.fragmentsComplete = this.fragNum; Program.DebugLog("Downloading Fragments:"); this.InitDecoder(); DateTime startTime = DateTime.Now; if (usedThreads) { this.Fragments2Download = new Fragment2Dwnld[this.fragCount]; int curSegNum, curFragNum; for (int i = 0; i < this.fragCount; i++) { curFragNum = i + 1; curSegNum = this.GetSegmentFromFragment(curFragNum); this.Fragments2Download[i].url = GetFragmentUrl(curSegNum, i + 1); this.Fragments2Download[i].ready = (curFragNum < this.fragNum); // if start > 0 skip this.Fragments2Download[i].running = false; } Thread MainThread = new Thread(ThreadDownload); MainThread.IsBackground = true; MainThread.Start(); } // --------------- MAIN LOOP DOWNLOADING FRAGMENTS ---------------- int fragsToDownload = this.fragCount - this.fragNum; while (this.fragNum < this.fragCount) { this.fragNum++; this.segNum = this.GetSegmentFromFragment(this.fragNum); //if (this.duration > 0) int ts = (int)Math.Round((double)this.currentTS / 1000); sDuration = string.Format("<c:DarkCyan>Current timestamp: </c>{0:00}:{1:00}:{2:00} ", ts / 3600, (ts / 60) % 60, ts % 60); if (Program.showtime && !this.live) { TimeSpan timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (fragsToDownload - (downloaded + 1)) / (downloaded + 1)); remaining = String.Format("<c:DarkCyan>Time remaining: </c>{0:00}<c:Cyan>:</c>{1:00}<c:Cyan>:</c>{2:00}", timeRemaining.Hours, timeRemaining.Minutes, timeRemaining.Seconds); } Program.Message(String.Format("{0,-46} {1}{2}\r", "Downloading <c:White>" + fragNum + "</c>/" + this.fragCount + " fragments", sDuration, remaining)); int fragIndex = FindFragmentInTabe(this.fragNum); if (fragIndex >= 0) this.discontinuity = this.fragTable[fragIndex].discontinuityIndicator; else { // search closest for (int i = 0; i < this.fragTable.Count; i++) { if (this.fragTable[i].firstFragment < this.fragNum) continue; this.discontinuity = this.fragTable[i].discontinuityIndicator; break; } } if (this.discontinuity != 0) { Program.DebugLog("Skipping fragment " + this.fragNum.ToString() + " due to discontinuity, Type: " + this.discontinuity.ToString()); continue; } if (usedThreads) { // use threads DateTime DataTimeOut = DateTime.Now.AddSeconds(200); while (!this.Fragments2Download[this.fragNum - 1].ready) { System.Threading.Thread.Sleep(2000); if (DateTime.Now > DataTimeOut) break; } if (!this.Fragments2Download[this.fragNum - 1].ready) { Program.Quit("<c:Red>Timeout downloading fragment " + this.fragNum + " ".PadLeft(38)); } fragmentData = this.Fragments2Download[this.fragNum - 1].data; Program.DebugLog("threads fragment loaded: " + this.Fragments2Download[this.fragNum - 1].url); } else { Program.DebugLog("Fragment Url: " + GetFragmentUrl(this.segNum, this.fragNum)); retCode = cc.get(GetFragmentUrl(this.segNum, this.fragNum)); if (retCode != 200) { if ((retCode == 403) && !String.IsNullOrEmpty(HTTP.Proxy) && !Program.fproxy) { string msg = "<c:Red>Access denied for downloading fragment <c:White>" + this.fragNum.ToString() + "</c>. (Request status: <c:Magenta>" + cc.Status + "</c>)"; msg += "\nTry switch <c:Green>--fproxy</c>."; Program.Quit(msg); } else Program.Quit("<c:Red>Failed to download fragment <c:White>" + this.fragNum.ToString() + "</c>. (Request status: <c:Magenta>" + cc.Status + "</c>)"); } else fragmentData = cc.ResponseData; } WriteFragment(ref fragmentData, this.fragNum); /* Resync with latest available fragment when we are left behind due to slow * * connection and short live window on streaming server. make sure to reset * * the last written fragment. */ if (this.live && (this.fragNum >= this.fragCount)) { Program.DebugLog("Trying to resync with latest available fragment"); this.UpdateBootstrapInfo(this.bootstrapUrl); //this.fragNum = this.fragCount - 1; this.lastFrag = this.fragNum; } downloaded++; Program.DebugLog("Downloaded: serment=" + this.segNum + " fragment=" + this.fragNum + "/" + this.fragCount + " lenght: " + fragmentData.Length); fragmentData = null; if (usedThreads) this.Fragments2Download[this.fragNum - 1].data = null; if ((this.duration > 0) && (this.currentDuration >= this.duration)) break; if ((this.filesize > 0) && (this.currentFilesize >= this.filesize)) break; } sDuration = string.Format("\n<c:DarkCyan>Downloaded duration: </c>{0:00}:{1:00}:{2:00} ", this.currentDuration / 3600, (this.currentDuration / 60) % 60, this.currentDuration % 60); Program.Message(sDuration); Program.DebugLog("\nAll fragments downloaded successfully."); }
public static bool Check4KnownLinks(string sLink) { string sVideoId = ""; if (RegExMatch(@"megogo.net/../view/(\d+)", sLink, out sVideoId)) { HTTP req = new HTTP(); sLink = "http://megogo.net/b/info/?s=0&e=0&p=0&t=&m=-1&i=" + sVideoId; req.get(sLink); if (!RegExMatch("<src>(.*?)</src>", req.responseText, out manifest)) Program.Quit("Cannot get the manifest from link megogo.net."); } else if (sLink.IndexOf("now.ru/item/") > 0) { HTTP req = new HTTP(); req.get(sLink); if (RegExMatch("\"smil\"\\s*?:\\s*?\"(.*?)\"", req.responseText, out sLink)) { sLink = sLink.Replace(@"\/", "/"); req.get(sLink); if (!RegExMatch("<httpds[^>]+src=\"(.*?)\"", req.responseText, out manifest)) Program.Quit("<c:Red>Cannot get the manifest from link <c:White>now.ru</c>."); } } return false; }
private void UpdateBootstrapInfo(string bootstrapUrl) { int fragNum = this.fragCount; int retries = 0; HTTP cc = new HTTP(); cc.Headers.Add("Cache-Control: no-cache"); cc.Headers.Add("Pragma: no-cache"); while ((fragNum == this.fragCount) && (retries < 30)) { long bootstrapPos = 0; long boxSize = 0; string boxType = ""; Program.DebugLog("Updating bootstrap info, Available fragments: " + this.fragCount.ToString()); if (cc.get(bootstrapUrl) != 200) Program.Quit("<c:Red>Failed to refresh bootstrap info"); ReadBoxHeader(ref cc.ResponseData, ref bootstrapPos, ref boxType, ref boxSize); if (boxType == "abst") this.ParseBootstrapBox(ref cc.ResponseData, bootstrapPos); else Program.Quit("<c:Red>Failed to parse bootstrap info"); Program.DebugLog("Update complete, Available fragments: " + this.fragCount.ToString()); if (fragNum == this.fragCount) { retries++; Program.Message(String.Format("{0,-80}\r", "<c:DarkCyan>Updating bootstrap info, Retries: " + retries.ToString())); Thread.Sleep(2000); // 2 sec } } }
private void StartNewThread2DownloadFragment() { if (this.fragNum < 1) return; this.threadsRun++; for (int i=this.fragNum-1; i < this.fragCount; i++) { if ((this.fragmentsComplete - this.fragNum) > 5) break; if (!this.Fragments2Download[i].running) { this.Fragments2Download[i].running = true; HTTP cc = new HTTP(!Program.fproxy); if (cc.get(this.Fragments2Download[i].url) != 200) { this.Fragments2Download[i].running = false; this.Fragments2Download[i].ready = false; Program.DebugLog("Error download fragment " + (i + 1) + " in thread. Status: " + cc.Status); } else { this.Fragments2Download[i].data = cc.ResponseData; this.Fragments2Download[i].ready = true; this.fragmentsComplete++; } break; }; } this.threadsRun--; }
// Get manifest and parse - extract medias info and select quality private void ParseManifest(string manifestUrl) { #pragma warning disable 0219 string baseUrl = "", defaultQuality = ""; int i = 0; Program.Message("Processing manifest info...."); XmlElement xml = this.GetManifest(ref manifestUrl); XmlNode node = xml.SelectSingleNode("/ns:manifest/ns:baseURL", nsMgr); if (node != null) baseUrl = node.InnerText.Trim(); if (baseUrl == "") baseUrl = ExtractBaseUrl(manifestUrl); if ((baseUrl == "") && !isHttpUrl(manifestUrl)) Program.Quit("<c:Red>Not found <c:Magenta>baseURL</c> value in manifest or in parameter <c:White>--urlbase</c>."); XmlNodeList nodes = xml.SelectNodes("/ns:manifest/ns:media[@*]", nsMgr); Dictionary<string, Manifest> manifests = new Dictionary<string, Manifest>(); int countBitrate = 0; bool readChildManifests = false; if (nodes.Count > 0) readChildManifests = AttrExist(nodes[0], "href"); if (readChildManifests) { foreach (XmlNode ManifestNode in nodes) { if (!AttrExist(ManifestNode, "bitrate")) countBitrate++; Manifest manifest = new Manifest(); manifest.bitrate = GetNodeProperty(ManifestNode, "bitrate", countBitrate.ToString()); manifest.url = NormalizePath(baseUrl + "/" + GetNodeProperty(ManifestNode, "href")); manifest.xml = this.GetManifest(ref manifest.url); manifests[manifest.bitrate] = manifest; } } else { Manifest manifest = new Manifest(); manifest.bitrate = "0"; manifest.url = manifestUrl; manifest.xml = xml; manifests[manifest.bitrate] = manifest; defaultQuality = manifest.bitrate; } countBitrate = 0; foreach (KeyValuePair<string, Manifest> pair in manifests) { Manifest manifest = pair.Value; string sBitrate = ""; // Extract baseUrl from manifest url node = manifest.xml.SelectSingleNode("/ns:manifest/ns:baseURL", nsMgr); if (node != null) baseUrl = node.InnerText.Trim(); else baseUrl = ExtractBaseUrl(manifest.url); XmlNodeList MediaNodes = manifest.xml.SelectNodes("/ns:manifest/ns:media", nsMgr); foreach (XmlNode stream in MediaNodes) { if (AttrExist(stream, "bitrate")) sBitrate = GetNodeProperty(stream, "bitrate"); else if (Int32.Parse(manifest.bitrate)>0) sBitrate = manifest.bitrate; else sBitrate = (countBitrate++).ToString(); while (this.media.ContainsKey(sBitrate)) sBitrate = (Int32.Parse(sBitrate)+1).ToString(); Media mediaEntry = new Media(); mediaEntry.baseUrl = baseUrl; mediaEntry.url = GetNodeProperty(stream, "url"); if (isRtmpUrl(mediaEntry.baseUrl) || isRtmpUrl(mediaEntry.url)) Program.Quit("<c:Red>Provided manifest is not a valid HDS manifest. (Media url is <c:Magenta>rtmp</c>?)"); if (AttrExist(stream, "bootstrapInfoId")) node = manifest.xml.SelectSingleNode("/ns:manifest/ns:bootstrapInfo[@id='" + GetNodeProperty(stream, "bootstrapInfoId") + "']", nsMgr); else node = manifest.xml.SelectSingleNode("/ns:manifest/ns:bootstrapInfo", nsMgr); if (node != null) { if (AttrExist(node, "url")) { mediaEntry.bootstrapUrl = NormalizePath(mediaEntry.baseUrl + "/" + GetNodeProperty(node, "url")); HTTP cc = new HTTP(); if (cc.get(mediaEntry.bootstrapUrl) != 200) Program.Quit("<c:Red>Failed to download bootstrap info. (Request status: <c:Magenta>" + cc.Status + "</c>)\n\r<c:DarkCyan>bootstrapUrl: <c:DarkRed>" + mediaEntry.bootstrapUrl); mediaEntry.bootstrap = cc.ResponseData; } else mediaEntry.bootstrap = System.Convert.FromBase64String(node.InnerText.Trim()); } node = manifest.xml.SelectSingleNode("/ns:manifest/ns:media[@url='" + mediaEntry.url + "']/ns:metadata", nsMgr); if (node != null) mediaEntry.metadata = System.Convert.FromBase64String(node.InnerText.Trim()); else mediaEntry.metadata = null; this.media[sBitrate] = mediaEntry; } } // Available qualities if (this.media.Count < 1) Program.Quit("<c:Red>No media entry found"); Program.DebugLog("Manifest Entries:\n"); Program.DebugLog(String.Format(" {0,-8}{1}", "Bitrate", "URL")); string sBitrates = " "; foreach (KeyValuePair<string, Media> pair in this.media) { sBitrates += pair.Key + " "; Program.DebugLog(String.Format(" {0,-8}{1}", pair.Key, pair.Value.url)); } Program.DebugLog(""); // Sort quality keys - from high to low string[] keys = new string[this.media.Keys.Count]; this.media.Keys.CopyTo(keys, 0); Array.Sort(keys, delegate(string b, string a) { int x = 0; int y = 0; if (Int32.TryParse(a, out x) && Int32.TryParse(b, out y)) return x - y; else return a.CompareTo(b); }); string sQuality = defaultQuality; // Quality selection if (this.media.ContainsKey(this.quality)) sQuality = this.quality; else { this.quality = this.quality.ToLower(); switch (this.quality) { case "low": this.quality = keys[keys.Length-1]; // last break; case "medium": this.quality = keys[keys.Length/2]; break; default: this.quality = keys[0]; // first break; } int iQuality = Convert.ToInt32(this.quality); while (iQuality>=0) { if (this.media.ContainsKey(iQuality.ToString())) break; iQuality--; } sQuality = iQuality.ToString(); } this.selectedMedia = this.media[sQuality]; int n = sBitrates.IndexOf(sQuality); sBitrates = sBitrates.Replace(" " + sQuality + " ", " <c:Cyan>" + sQuality + "</c> "); Program.Message("Quality Selection:"); Program.Message("Available:"+sBitrates); Program.Message("Selected : <c:Cyan>" + sQuality.PadLeft(n + sQuality.Length-1)); this.baseUrl = this.selectedMedia.baseUrl; if (!String.IsNullOrEmpty(this.selectedMedia.bootstrapUrl)) { this.bootstrapUrl = this.selectedMedia.bootstrapUrl; this.UpdateBootstrapInfo(this.bootstrapUrl); } else { long pos = 0; long boxSize = 0; string boxType = ""; ReadBoxHeader(ref this.selectedMedia.bootstrap, ref pos, ref boxType, ref boxSize); if (boxType == "abst") this.ParseBootstrapBox(ref this.selectedMedia.bootstrap, pos); else Program.Quit("<c:Red>Failed to parse bootstrap info."); } if (this.fragsPerSeg == 0) this.fragsPerSeg = this.fragCount; if (this.live) { this.threads = 1; this.fromTimestamp = -1; Program.Message("<c:Magenta>[Live stream]"); } #pragma warning restore 0219 }
private XmlElement GetManifest(ref string manifestUrl) { string sDomain = ""; HTTP cc = new HTTP(); int statusCode = cc.get(manifestUrl); CheckRequestRerutnCode(statusCode, cc.Status); if (Program.RegExMatch(@"<r>\s*?<to>(.*?)</to>", cc.responseText, out sDomain)) { if (Program.RegExMatch(@"^.*?://.*?/.*?/(.*)", manifestUrl, out manifestUrl)) { manifestUrl = sDomain + manifestUrl; statusCode = cc.get(manifestUrl); CheckRequestRerutnCode(statusCode, cc.Status); } } string xmlText = ValidateXML(cc.responseText); if (xmlText.IndexOf("</") < 0) Program.Quit("<c:Red>Error loading manifest: <c:Green>" + manifestUrl); XmlDocument xmldoc = new XmlDocument(); try { xmldoc.LoadXml(xmlText); } catch (Exception e) { if (Regex.IsMatch(xmlText, @"<html.*?<body", RegexOptions.Singleline)) { Program.Quit("<c:Red>Error loading manifest. Url redirected to html page. Check the manifest url."); } else { Program.Quit("<c:Red>Error loading manifest. It's no valid xml file.\n"+e.Message); } } nsMgr = new XmlNamespaceManager(xmldoc.NameTable); nsMgr.AddNamespace("ns", xmldoc.DocumentElement.NamespaceURI); return xmldoc.DocumentElement; }
private static void GetLink_Moonwalk(string sLink) { string sHtml, sData, sPost; Match m; HTTP.Referer = sLink; sLink = sLink.Replace("moonwalk.co", "moonwalk.cc"); sLink = sLink.Replace("moonwalk.pw", "moonwalk.cc"); sHtml = HTTP.GET(sLink); if (Regex.IsMatch(sHtml, "<iframe[^>]+src=\"(http.*?)\"", RegexOptions.Singleline)) { sLink = sLink.Replace("moonwalk.co", "moonwalk.cc"); sLink = sLink.Replace("moonwalk.pw", "moonwalk.cc"); sHtml = HTTP.GET(sLink); } m = Regex.Match(sHtml, "\"csrf-token\"\\s+content=\"(.*?)\""); if (m.Success) { HTTP.Headers.Set("X-CSRF-Token", m.Groups[1].Value); } foreach (Match match in Regex.Matches(sHtml, "Set-Cookie:\\s*([^;]+)")) { HTTP.Cookies += " " + match.Groups[1].Value + ";"; } string server = Regex.Match(sLink, "^(.*?//.*?)/").Groups[1].Value; HTTP.Headers.Set("Origin", server); HTTP.Headers.Set("X-Requested-With", "XMLHttpRequest"); HTTP.Headers.Set("Pragma", "no-cache"); m = Regex.Match(sHtml, "ajaxSetup\\([^)]+headers:(.*?)}", RegexOptions.Singleline); if (m.Success) { foreach (Match match in Regex.Matches(m.Groups[1].Value, "[\"']([\\w-_]+)[\"']\\s*?:\\s*?[\"'](\\w+)[\"']")) { HTTP.Headers.Set(match.Groups[1].Value, match.Groups[2].Value); } } m = Regex.Match(sHtml, "window\\[[^]]+]\\s*=\\s*\\{(.*?)\\}", RegexOptions.Singleline); if (!m.Success) { Quit("Not found post parameters in moonwalk iframe"); } sPost = m.Groups[1].Value.Replace("\n", "").Replace(" ", "").Replace("'", ""); sPost = sPost.Replace(':', '=').Replace(',', '&').Replace(':', '=').Replace(':', '=').Replace("condition_detected?1=", ""); foreach (Match match in Regex.Matches(sPost, ".=(\\w+)")) { m = Regex.Match(sHtml, "var\\s" + match.Groups[1].Value + "\\s*=\\s*['\"](.*?)['\"]"); if (m.Success) { sPost = sPost.Replace("=" + match.Groups[1].Value, "=" + m.Groups[1].Value); } } foreach (Match match in Regex.Matches(sHtml, "post_method\\.(\\w+)\\s*=\\s*(\\w+)")) { m = Regex.Match(sHtml, "var\\s" + match.Groups[1].Value + "\\s*=\\s*['\"](.*?)['\"]"); if (m.Success) { sPost += "&" + match.Groups[1].Value + "=" + m.Groups[1].Value; } } foreach (Match match in Regex.Matches(sHtml, "\\['(\\w+)'\\]\\s*=\\s*'(.*?)'")) { sPost += "&" + match.Groups[1].Value + "=" + match.Groups[2].Value; } foreach (Match match in Regex.Matches(sHtml, "window\\[[^\\]]+\\]\\[(.*?)\\]\\s*=\\s*(.*?);")) { string sVar = match.Groups[1].Value.Replace("+", "").Replace(" ", "").Replace("'", ""); string sVal = match.Groups[2].Value.Replace("+", "").Replace(" ", "").Replace("'", ""); sPost += "&" + sVar + "=" + sVal; } m = Regex.Match(sHtml, "'(/manifests/.*?)'"); if (!m.Success) { Quit("Not found url for POST query in moonwalk iframe"); } sData = HTTP.POST(server + m.Groups[1].Value, sPost); m = Regex.Match(sData, "\"manifest_f4m\"\\s*?:\\s*?\"(.*?)\""); if (m.Success) { manifestUrl = Regex.Unescape(m.Groups[1].Value); } }