Пример #1
0
        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);
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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);
                }
            }
        }
Пример #4
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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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.");
        }
Пример #7
0
        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;
        }
Пример #8
0
        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
                }
            }
        }
Пример #9
0
 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--;
 }
Пример #10
0
        // 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
        }
Пример #11
0
        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;
        }
Пример #12
0
        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);
            }
        }