public static async Task <bool> IsValidUrl(string url) { if (!Regex.IsMatch(url, NomalizedPattern)) { return(false); } var hp = new HttpHelper(); string html = null; if (!NetCache.HasCache(url)) { html = await hp.GET(url, encoding : Encoding.UTF8); NetCache.Set(url, html); } else { html = NetCache.Get(url); } if (!html.IsEmpty(true) && Regex.IsMatch(html, TitlePattern)) { return(!Regex.Match(html, TitlePattern).Groups[1].Value.AnyEquals("Youtube")); } return(false); }
public static async Task <VideoData[]> Extract(string url) { string vUrl; if (UrlResolver.TryNomalize(url, out vUrl)) { string html; if (!await UrlResolver.IsValidUrl(vUrl)) { throw new InvalidUrlException(); } // 캐싱 if (NetCache.HasCache(vUrl)) { html = NetCache.Get(vUrl); } else { var hp = new HttpHelper(); html = await hp.GET(vUrl); NetCache.Set(vUrl, html); } // 정지된 유튜브 체크 if (IsVideoUnavailable(html)) { throw new UnableVideoException(); } // 스트림및 영상 데이터 var obj = JObject.Parse(ParseVideoData(html)); return(await ParseDownloadUrls(obj)); } else { throw new InvalidUrlException(); } }
public static async Task <string> Decrypt(string cipher, string jsUrl) { string js; if (NetCache.HasCache(jsUrl)) { js = NetCache.Get(jsUrl); } else { js = await(new HttpHelper()).GET(jsUrl); NetCache.Set(jsUrl, js); } string functNamePattern = @"\.sig\s*\|\|([a-zA-Z0-9\$]+)\("; var funcName = Regex.Match(js, functNamePattern).Groups[1].Value; if (funcName.Contains("$")) { funcName = "\\" + funcName; } string funcPattern = @"(?!h\.)" + @funcName + @"=function\(\w+\)\{.*?\}"; var funcBody = Regex.Match(js, funcPattern, RegexOptions.Singleline).Value; var lines = funcBody.Split(';'); string idReverse = "", idSlice = "", idCharSwap = ""; string functionIdentifier = ""; string operations = ""; foreach (var line in lines.Skip(1).Take(lines.Length - 2)) { if (!string.IsNullOrEmpty(idReverse) && !string.IsNullOrEmpty(idSlice) && !string.IsNullOrEmpty(idCharSwap)) { break; } functionIdentifier = GetFunctionFromLine(line); string reReverse = string.Format(@"{0}:\bfunction\b\(\w+\)", functionIdentifier); string reSlice = string.Format(@"{0}:\bfunction\b\([a],b\).(\breturn\b)?.?\w+\.", functionIdentifier); string reSwap = string.Format(@"{0}:\bfunction\b\(\w+\,\w\).\bvar\b.\bc=a\b", functionIdentifier); if (Regex.Match(js, reReverse).Success) { idReverse = functionIdentifier; } if (Regex.Match(js, reSlice).Success) { idSlice = functionIdentifier; } if (Regex.Match(js, reSwap).Success) { idCharSwap = functionIdentifier; } } foreach (var line in lines.Skip(1).Take(lines.Length - 2)) { Match m; functionIdentifier = GetFunctionFromLine(line); if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success && functionIdentifier == idCharSwap) { operations += "w" + m.Groups["index"].Value + " "; } if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success && functionIdentifier == idSlice) { operations += "s" + m.Groups["index"].Value + " "; } if (functionIdentifier == idReverse) { operations += "r "; } } operations = operations.Trim(); return(DecipherWithOperations(cipher, operations)); }