private async static Task <JObject> LoadJson(string url) { int i = 0; string pageSource = await HttpHelper.DownloadString(url); if (IsVideoUnavailable(pageSource)) { throw new VideoNotAvailableException(); } //while (i < 6) //{ // pageSource = pageSource.Substring(pageSource.IndexOf("<script>") + 8); // i++; //} //int index1 = pageSource.IndexOf("ytplayer.config"); //pageSource = pageSource.Substring(index1); //int index = pageSource.IndexOf("</script>"); //pageSource = pageSource.Substring(0, index); //pageSource = pageSource.Substring(0, pageSource.Length / 2); //int index = pageSource.IndexOf("ytplayer.config"); //int lastIndex = pageSource.IndexOf("}());", index); //string extractedJson=pageSource.Substring(index,lastIndex-index); var dataRegex = new Regex(@"ytplayer\.config\s*=\s*(\{.+?\});", RegexOptions.Multiline); string extractedJson = dataRegex.Match(pageSource).Result("$1"); //string extractedJson = "ytplayer.config = {\"url_v9as2\": \"https://s.ytimg.com/yts/swfbin/player-vfllVed9W/cps.swf\", \"attrs\": {\"id\": \"movie_player\"}, \"args\": {\"eventid\": \"JADmU6OxBdH84QLYloGwAg\", \"timestamp\": 1407582244, \"url_encoded_fmt_stream_map\": \"type=video%2Fmp4%3B+codecs%3D%22avc1.64001F%2C+mp4a.40.2%22\u0026quality=hd720\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Fid%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26upn%3DWDviZUt2v4o%26key%3Dyt5%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26ratebypass%3Dyes%26mt%3D1407581698%26sver%3D3%26itag%3D22%26sparams%3Dcp%252Cid%252Cip%252Cipbits%252Citag%252Cratebypass%252Crequiressl%252Csource%252Cupn%252Cexpire%26signature%3D902AE11563D8271D7066EFDD1014E1F6899F6853.84F25E4FB08F881F545E4B57D63302CCB74E0192%26mm%3D30%26source%3Dyoutube%26expire%3D1407603844%26mws%3Dyes%26mv%3Du%26ipbits%3D8%26ip%3D117.222.223.185\u0026fallback_host=tc.v5.cache3.c.youtube.com\u0026itag=22,type=video%2Fmp4%3B+codecs%3D%22avc1.42001E%2C+mp4a.40.2%22\u0026quality=medium\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Fid%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26upn%3DWDviZUt2v4o%26key%3Dyt5%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26ratebypass%3Dyes%26mt%3D1407581698%26sver%3D3%26itag%3D18%26sparams%3Dcp%252Cid%252Cip%252Cipbits%252Citag%252Cratebypass%252Crequiressl%252Csource%252Cupn%252Cexpire%26signature%3DDADFBF372249B009D77BC5F49BD0F253211BE05F.D5545FC5A5622AF0E70CC6B85C240EAC2C0A7F50%26mm%3D30%26source%3Dyoutube%26expire%3D1407603844%26mws%3Dyes%26mv%3Du%26ipbits%3D8%26ip%3D117.222.223.185\u0026fallback_host=tc.v19.cache6.c.youtube.com\u0026itag=18\", \"ytfocEnabled\": \"1\", \"fexp\": \"901454,902408,927622,931983,934024,934030,946022\", \"referrer\": null, \"rmktPingThreshold\": 0, \"plid\": \"AAUAMEem16xOD4Ma\", \"ldpj\": \"-6\", \"watermark\": \",https://s.ytimg.com/yts/img/watermark/youtube_watermark-vflHX6b6E.png,https://s.ytimg.com/yts/img/watermark/youtube_hd_watermark-vflAzLcD6.png\", \"enablejsapi\": 1, \"cr\": \"IN\", \"length_seconds\": 41, \"baseUrl\": \"https://googleads.g.doubleclick.net/pagead/viewthroughconversion/962985656/\", \"cbr\": \"IE\", \"iv_load_policy\": 1, \"iv_module\": \"https://s.ytimg.com/yts/swfbin/player-vfl8MfiIN/iv_module.swf\", \"adaptive_fmts\": \"index=713-840\u0026clen=6992259\u0026bitrate=2189770\u0026lmt=1407060637275561\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.640028%22\u0026init=0-712\u0026size=1920x1080\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407060637275561%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.921%26clen%3D6992259%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D137%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D64D2B755390DEB7B6E1E7BD2840AB69946F279C1.CEE9B089BFBFC08583AD7962D91D91AE2C463BC0%26source%3Dyoutube\u0026itag=137,index=235-365\u0026clen=5281776\u0026bitrate=1316961\u0026lmt=1406988184312555\u0026type=video%2Fwebm%3B+codecs%3D%22vp9%22\u0026init=0-234\u0026size=1920x1080\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1406988184312555%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.960%26clen%3D5281776%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D248%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D3C2F8A0D3137103B2BE5B51F960675CC9CE5CEEC.A84A1274927174AFB2AB260F79F319EA1EF87EFA%26source%3Dyoutube\u0026itag=248,index=711-838\u0026clen=3618877\u0026bitrate=1076065\u0026lmt=1407060579277365\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.4d401f%22\u0026init=0-710\u0026size=1280x720\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407060579277365%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.921%26clen%3D3618877%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D136%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D425D170B4DD076D650BB0D72DC06B6D187315539.44E9A77DBD7CB0FC02D0067A94385F7830969B4B%26source%3Dyoutube\u0026itag=136,index=235-365\u0026clen=2690636\u0026bitrate=692405\u0026lmt=1406988159038149\u0026type=video%2Fwebm%3B+codecs%3D%22vp9%22\u0026init=0-234\u0026size=1280x720\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1406988159038149%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.960%26clen%3D2690636%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D247%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D0C0554ACED375007D48F3C466477390085AFDD52.6539EC339BC511F0464E96BDC321EAEA6C0965DE%26source%3Dyoutube\u0026itag=247,index=710-837\u0026clen=1791833\u0026bitrate=545044\u0026lmt=1407060576811008\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.4d401e%22\u0026init=0-709\u0026size=854x480\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407060576811008%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.921%26clen%3D1791833%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D135%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D9B2F0993995F062F8394EB57F543F70691474854.73F1916FFC76469C9C25B64ADD52A2C25D090A86%26source%3Dyoutube\u0026itag=135,index=235-365\u0026clen=1348217\u0026bitrate=381768\u0026lmt=1406988149531287\u0026type=video%2Fwebm%3B+codecs%3D%22vp9%22\u0026init=0-234\u0026size=854x480\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1406988149531287%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.960%26clen%3D1348217%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D244%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D9BB9B21D63374916D987CDFB6D7D135BA5DDD422.944878C1AE389CA36DD1E0901C690605E8E9589A%26source%3Dyoutube\u0026itag=244,index=710-837\u0026clen=857989\u0026bitrate=263967\u0026lmt=1407060566758168\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.4d401e%22\u0026init=0-709\u0026size=640x360\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407060566758168%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.921%26clen%3D857989%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D134%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D86A0C9B892692BA85E5035DF44004794FD32FCCB.A6FED7B19A939DFDCCCE3255CA99DDC4966C58AD%26source%3Dyoutube\u0026itag=134,index=235-365\u0026clen=726599\u0026bitrate=200515\u0026lmt=1406988129350400\u0026type=video%2Fwebm%3B+codecs%3D%22vp9%22\u0026init=0-234\u0026size=640x360\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1406988129350400%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.960%26clen%3D726599%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D243%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D4849C1F7D0A9D328A9C37D44005363F419199C66.33714C0BCC72152E13927E4699F4DD839C5AA2C0%26source%3Dyoutube\u0026itag=243,index=675-802\u0026clen=1216250\u0026bitrate=256877\u0026lmt=1407061280695949\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.4d4015%22\u0026init=0-674\u0026size=426x240\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407061280695949%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.921%26clen%3D1216250%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D133%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D207E22B2695B4A2808A92C6CAAC0BE4D0DEEEE00.44709BCC00111AFE30A9FEE7426D89F3F129284E%26source%3Dyoutube\u0026itag=133,index=234-363\u0026clen=381811\u0026bitrate=102555\u0026lmt=1406988117738772\u0026type=video%2Fwebm%3B+codecs%3D%22vp9%22\u0026init=0-233\u0026size=426x240\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1406988117738772%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.960%26clen%3D381811%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D242%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3DD63EA98BCA34C7FB523B283E0966DD833BF28379.B2203F3897AC82C1B8CD92D0E8AB8286C1E735E0%26source%3Dyoutube\u0026itag=242,index=672-799\u0026clen=540369\u0026bitrate=114216\u0026lmt=1407060538544413\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.4d400c%22\u0026init=0-671\u0026size=256x144\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407060538544413%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.921%26clen%3D540369%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D160%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3DB0F9D951933ECE5870B88D7C368D35F48AB13BBA.D1138DEC11D05EB7422E39E612300172863FE3B2%26source%3Dyoutube\u0026itag=160,index=592-683\u0026clen=643755\u0026bitrate=145565\u0026lmt=1407060474261684\u0026type=audio%2Fmp4%3B+codecs%3D%22mp4a.40.2%22\u0026init=0-591\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1407060474261684%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D40.054%26clen%3D643755%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D140%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3DD894482A8D078A88E1C9F49696BB5F7BA7167EA2.C9169F62F48F89769C14FF8F46D9691F827C00AB%26source%3Dyoutube\u0026itag=140,index=4452-4518\u0026clen=476486\u0026bitrate=115582\u0026lmt=1406988101266808\u0026type=audio%2Fwebm%3B+codecs%3D%22vorbis%22\u0026init=0-4451\u0026url=https%3A%2F%2Fr1---sn-cvh7zn7z.c.youtube.com%2Fvideoplayback%3Flmt%3D1406988101266808%26key%3Dyt5%26fexp%3D901454%252C902408%252C927622%252C931983%252C934024%252C934030%252C946022%26sver%3D3%26gir%3Dyes%26expire%3D1407603844%26mws%3Dyes%26upn%3DswJfsAW6COc%26mv%3Du%26ipbits%3D8%26id%3Do-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8%26dur%3D39.995%26clen%3D476486%26cp%3DU0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ%26ms%3Dnxu%26requiressl%3Dyes%26mt%3D1407581698%26itag%3D171%26sparams%3Dclen%252Ccp%252Cdur%252Cgir%252Cid%252Cip%252Cipbits%252Citag%252Clmt%252Crequiressl%252Csource%252Cupn%252Cexpire%26mm%3D30%26ip%3D117.222.223.185%26signature%3D0B933DC31F9078C60AFA1824AF3B5BB91D14D0F0.A7440FC207C27D4464B3D4AD4DE3950D861EB382%26source%3Dyoutube\u0026itag=171\", \"focEnabled\": \"1\", \"enablecsi\": \"1\", \"pltype\": \"contentugc\", \"ptk\": \"youtube_none\", \"uid\": \"yvOJDBxhi1yqW97hXw3BDw\", \"tmi\": \"1\", \"video_id\": \"KDFDawjXsXg\", \"keywords\": \"new,latest,movie,Bollywood,Film,Indian,2013,update,behind,the,scene,Clip,Promo,trailers,Teasers,interview,stars,shooting,entertainment,Aamir Khan (Film Actor),Anushka Sharma (Award Winner),Sanjay Dutt (Film Actor),Boman Irani (Film Actor),Sushant Singh Rajput (Award Winner),Saurabh Shukla (Film Director),Rajkumar Hirani (Film Director),Vidhu Vinod Chopra (Film Director),Peekay (Film),Poster (Collection Category),Official,motion poster\", \"idpj\": \"-8\", \"c\": \"WEB\", \"ssl\": 1, \"account_playback_token\": \"QUFFLUhqbEk3a0ZYMmpDN3BZdGJNcFFBaUZrMkxXWjROd3xBQ3Jtc0tscUQwWF9lY3doWnh6LUVvNDZxV0EySFg0dFRlSE1OV2ZrSDBFOXgteFEwZVNadmNKUHVCMkw3SkN1TGxMY3YzV1BPa3pzeXZvczRYbUtUd1AtTkIyTTdoSUpEWWZKcHNnZWFPWVVEa2wwSHZld0NuYw==\", \"cbrver\": \"11.0\", \"iv3_module\": \"1\", \"loaderUrl\": \"https://www.youtube.com/watch?v=KDFDawjXsXg\", \"t\": \"1\", \"dashmpd\": \"https://www.youtube.com/api/manifest/dash/playback_host/r1---sn-cvh7zn7z.c.youtube.com/fexp/901454%2C902408%2C927622%2C931983%2C934024%2C934030%2C946022/mv/u/cmbypass/yes/ipbits/8/id/o-AB6PBmjGxBUzAy95o_3DDAGtZZsunDtsGaRo9mLMGCH8/cp/U0lPTFZLUV9JTkNPOV9ORVVJOnNpdTd4dHpBbUlJ/ms/nxu/requiressl/yes/mt/1407581698/itag/0/sparams/as%2Ccmbypass%2Ccp%2Cgcr%2Cid%2Cip%2Cipbits%2Citag%2Cplayback_host%2Crequiressl%2Csource%2Cexpire/mm/30/ip/117.222.223.185/key/yt5/sver/3/expire/1407603844/mws/yes/as/fmp4_audio_clear%2Cwebm_audio_clear%2Cfmp4_sd_hd_clear%2Cwebm_sd_hd_clear%2Cwebm2_sd_hd_clear/upn/g-7iQezqxL8/gcr/in/source/youtube/signature/9D60793C8CAC94902A6CBF97D78DE60683384C92.ED9AF14BD03E808222954A470FC7BF03CC3D9DF6\", \"remarketing_url\": \"https://googleads.g.doubleclick.net/pagead/viewthroughconversion/962985656/?cver=unknown\u0026ptype=view\u0026data=backend%3Ds_monetization_data%3Bcname%3DWEB%3Bcver%3Dunknown%3Bptype%3Dview%3Btype%3Dview%3Butuid%3DyvOJDBxhi1yqW97hXw3BDw%3Butvid%3DKDFDawjXsXg\u0026backend=s_monetization_data\u0026label=followon_view\u0026foc_id=yvOJDBxhi1yqW97hXw3BDw\u0026cname=WEB\u0026aid=P-qHlGrAeBw\", \"host_language\": \"en\", \"ucid\": \"UCyvOJDBxhi1yqW97hXw3BDw\", \"csi_page_type\": \"watch,watch7_html5\", \"storyboard_spec\": \"https://i.ytimg.com/sb/KDFDawjXsXg/storyboard3_L$L/$N.jpg|48#27#100#10#10#0#default#gRStUqBkx2yWEcyn03wADmBIMa4|80#45#41#10#10#1000#M$M#__3moJ-hvBXCrHt1szgrMYSXpAQ|160#90#41#5#5#1000#M$M#ZGvVeybKFNSO7xVj8HzYmkoJL0s|320#180#41#3#3#1000#M$M#VGN40S3l-I5nkvoWOxtWceE6s5Y\", \"vid\": \"KDFDawjXsXg\", \"no_get_video_log\": \"1\", \"fmt_list\": \"22/1280x720/9/0/115,18/640x360/9/0/115\", \"cos\": \"Windows\", \"hl\": \"en_US\", \"atc\": \"a=3\u0026b=5jKxXsYo5aBs5XFuwfARl7ZoSPM\u0026c=1407582244\u0026d=1\u0026e=KDFDawjXsXg\u0026c3a=16\u0026c1a=1\u0026hh=CB1Cj0aRtWVFz_azfWzFftkTLag\", \"cosver\": \"6.3\", \"title\": \"PK Official Motion Poster I Releasing December 19, 2014\", \"advideo\": \"1\", \"sw\": \"1.0\", \"aid\": \"P-KwzTuRh-E\", \"rmktEnabled\": \"1\", \"vq\": \"auto\", \"dash\": \"1\", \"iv_invideo_url\": \"https://www.youtube.com/annotations_invideo?cap_hist=1\u0026cta=2\u0026video_id=KDFDawjXsXg\"}, \"assets\": {\"js\": \"//s.ytimg.com/yts/jsbin/html5player-en_US-vflArxUZc/html5player.js\", \"css\": \"//s.ytimg.com/yts/cssbin/www-player-vflZFrHj6.css\", \"html\": \"/html5_player_template\"}, \"html5\": true, \"min_version\": \"8.0.0\", \"url\": \"https://s.ytimg.com/yts/swfbin/player-vfllVed9W/watch_as3.swf\", \"params\": {\"allowscriptaccess\": \"always\", \"allowfullscreen\": \"true\", \"bgcolor\": \"#000000\"}, \"sts\": 16289, \"url_v8\": \"https://s.ytimg.com/yts/swfbin/player-vfllVed9W/cps.swf\"};(function() {if (!!window.yt) {yt.player.Application.create(\"player-api\", ytplayer.config);ytplayer.config.loaded = true;}}());"; return(JObject.Parse(extractedJson)); }
private static string GetHtml5PlayerVersion(string url) { string str = HttpHelper.DownloadString(url); Regex regex = new Regex("\"assets\":.+?\"js\":\\s*\"([^\"]+)\""); return(regex.Match(str).Result("$1").Replace("\\/", "/")); }
private static string GetJs(string cipherVersion) { string[] formats = { "https://www.youtube.com/s/player{0}.js", "http://s.ytimg.com/yts/jsbin/player{0}.js", }; var exceptions = new List <Exception>(); foreach (var format in formats) { try { var jsUrl = string.Format(format, cipherVersion); string js = HttpHelper.DownloadString(jsUrl); return(js); } catch (Exception ex) { exceptions.Add(ex); } } throw new Exception(string.Join("\n--------\n", exceptions.Select(ex => ex.ToString()).ToArray())); }
private static void ParseDashManifest(string dashManifestUrl, List <VideoInfo> previousFormats, string videoTitle) { string pageSource = HttpHelper.DownloadString(dashManifestUrl); XmlDocument doc = new XmlDocument(); XmlNamespaceManager docNamespace = new XmlNamespaceManager(doc.NameTable); docNamespace.AddNamespace("urn", "urn:mpeg:DASH:schema:MPD:2011"); docNamespace.AddNamespace("yd", "http://youtube.com/yt/2012/10/10"); doc.LoadXml(pageSource); XmlNodeList ManifestList = doc.SelectNodes("//urn:Representation", docNamespace); foreach (XmlElement item in ManifestList) { int FormatCode = int.Parse(item.GetAttribute("id")); XmlNode BaseUrl = item.GetElementsByTagName("BaseURL").Item(0); VideoInfo info = GetSingleVideoInfo(FormatCode, BaseUrl.InnerText, videoTitle, false); if (item.HasAttribute("height")) { info.Resolution = int.Parse(item.GetAttribute("height")); } if (item.HasAttribute("frameRate")) { info.FrameRate = int.Parse(item.GetAttribute("frameRate")); } VideoInfo DeleteItem = previousFormats.SingleOrDefault(v => v.FormatCode == FormatCode); if (DeleteItem != null) { previousFormats.Remove(DeleteItem); } previousFormats.Add(info); } }
public static string DecipherWithVersion(string cipher, string cipherVersion) { string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/player-{0}.js", cipherVersion); string js = HttpHelper.DownloadString(jsUrl); return(DecipherJson(js, cipher)); }
private static YoutubePage LoadJson(string url) { var page = new YoutubePage(); page.Source = HttpHelper.DownloadString(url); if (IsVideoUnavailable(page.Source)) { throw new VideoNotAvailableException(); } //var dataRegex = new Regex(@"ytplayer\.config\s*=\s*(\{.+?\});", RegexOptions.Multiline); var dataRegex = new Regex(@"ytInitialPlayerResponse\s*=\s*(\{.+?\});", RegexOptions.Multiline); var extractedJson = dataRegex.Match(page.Source).Result("$1"); page.PlayerConfigJson = JObject.Parse(extractedJson); var regex2 = new Regex(@"ytcfg.set\((\{.+?\})\);", RegexOptions.Multiline); var json2 = regex2.Match(page.Source).Result("$1"); page.ConfigJson2 = JObject.Parse(json2); return(page); }
public static string DecipherWithVersion(string cipher, string cipherVersion) { string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/player-{0}.js", cipherVersion); string js = HttpHelper.DownloadString(jsUrl); var decodeArray = FindSignatureCode(js); return(DecryptSignature(cipher, decodeArray)); }
private static JObject LoadJson(string url) { string str = HttpHelper.DownloadString(url); if (DownloadUrlResolver.IsVideoUnavailable(str)) { throw new VideoNotAvailableException(); } return(JObject.Parse(new Regex("ytplayer\\.config\\s*=\\s*(\\{.+?\\});", RegexOptions.Multiline).Match(str).Result("$1"))); }
public static string DecipherWithVersion(string cipher, string cipherVersion) { string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/player{0}.js", cipherVersion); string baseJs = HttpHelper.DownloadString(jsUrl); // Find the name of the function that handles deciphering var fnname = Regex.Match(baseJs, @"yt\.akamaized\.net.*encodeURIComponent\((\w+)").Groups[1].Value; var _argnamefnbodyresult = Regex.Match(baseJs, fnname + @"=function\((.+?)\){(.+?)}"); var helpername = Regex.Match(_argnamefnbodyresult.Groups[2].Value, @";(.+?)\..+?\(").Groups[1].Value; var helperresult = Regex.Match(baseJs, "var " + helpername + "={[\\s\\S]+?};"); var result = helperresult.Groups[0].Value; MatchCollection matches = Regex.Matches(result, @"[A-Za-z0-9]+:function\s*([A-z0-9]+)?\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*\{(?:[^}{]+|\{(?:[^}{]+|\{[^}{]*\})*\})*\}"); var funcs = _argnamefnbodyresult.Groups[2].Value.Split(';'); var sign = cipher.ToCharArray(); foreach (string func in funcs) { foreach (Match group in matches) { if (group.Value.Contains("reverse")) { var test = Regex.Match(group.Value, "^(.*?):").Groups[1].Value; if (func.Contains(test)) { sign = ReverseFunction(sign); } } else if (group.Value.Contains("splice")) { var test = Regex.Match(group.Value, "^(.*?):").Groups[1].Value; if (func.Contains(test)) { sign = SpliceFunction(sign, GetOpIndex(func)); } } else { var test = Regex.Match(group.Value, "^(.*?):").Groups[1].Value; if (func.Contains(test)) { sign = SwapFunction(sign, GetOpIndex(func)); } } } } return(new string(sign)); }
private static YoutubeModel LoadModel(string videoUrl) { var videoId = videoUrl.Replace("https://youtube.com/watch?v=", ""); var url = $"https://www.youtube.com/watch?v={videoId}&gl=US&hl=en&has_verified=1&bpctr=9999999999"; var pageSource = HttpHelper.DownloadString(url); var player_response = string.Empty; if (Regex.IsMatch(pageSource, @"[""\']status[""\']\s*:\s*[""\']LOGIN_REQUIRED")) { url = $"https://www.youtube.com/get_video_info?video_id={videoId}&eurl=https://youtube.googleapis.com/v/{videoId}"; pageSource = HttpHelper.DownloadString(url); player_response = HttpHelper.ParseQueryString(pageSource)["player_response"]; player_response = HttpHelper.UrlDecode(player_response); return(YoutubeModel.FromJson(player_response)); } var dataRegex = new Regex(@"ytplayer\.config\s*=\s*(\{.+?\});", RegexOptions.Multiline); var dataMatch = dataRegex.Match(pageSource); if (dataMatch.Success) { string extractedJson = dataMatch.Result("$1"); if (!extractedJson.Contains("raw_player_response:ytInitialPlayerResponse")) //https://www.youtube.com/watch?v=9Y7TRMISkGE { player_response = JObject.Parse(extractedJson)["args"]["player_response"].ToString(); return(YoutubeModel.FromJson(player_response)); } } dataRegex = new Regex(@"ytInitialPlayerResponse\s*=\s*({.+?})\s*;\s*(?:var\s+meta|</script|\n)", RegexOptions.Multiline); dataMatch = dataRegex.Match(pageSource); if (dataMatch.Success) { player_response = dataMatch.Result("$1"); return(YoutubeModel.FromJson(player_response)); } dataRegex = new Regex(@"ytInitialPlayerResponse\s*=\s*({.+?})\s*;", RegexOptions.Multiline); dataMatch = dataRegex.Match(pageSource); if (dataMatch.Success) { player_response = dataMatch.Result("$1"); return(YoutubeModel.FromJson(player_response)); } ThrowYoutubeParseException(new VideoNotAvailableException("Unable to extract video data"), videoUrl); return(null); }
private static string GetHtml5PlayerVersion(string url) { if (string.IsNullOrEmpty(url)) { return(null); } string str = HttpHelper.DownloadString(url); Regex regex = new Regex(@"""jsUrl""\s*:\s*""([^""]+)"""); return(regex.Match(str).Result("$1").Replace("\\/", "/")); }
/// <summary> /// Gets a list of <see cref="VideoInfo"/>s for the specified URL. /// </summary> /// <param name="videoUrl">The URL of the YouTube video.</param> /// <returns>A list of <see cref="VideoInfo"/>s that can be used to download the video.</returns> /// <exception cref="ArgumentNullException">The <paramref name="videoUrl"/> parameter is <c>null</c>.</exception> /// <exception cref="ArgumentException">The <paramref name="videoUrl"/> parameter is not a valid YouTube URL.</exception> /// <exception cref="VideoNotAvailableException">The video is not available.</exception> /// <exception cref="WebException">An error occurred while downloading the YouTube page html.</exception> /// <exception cref="YoutubeParseException">The Youtube page could not be parsed.</exception> public static IEnumerable <VideoInfo> GetDownloadUrls(string videoUrl) { if (videoUrl == null) { throw new ArgumentNullException("videoUrl"); } videoUrl = NormalizeYoutubeUrl(videoUrl); string pageSource = HttpHelper.DownloadString(videoUrl); string videoTitle = GetVideoTitle(pageSource); string id = HttpHelper.ParseQueryString(videoUrl)["v"]; string requestUrl = String.Format("http://www.youtube.com/get_video_info?&video_id={0}&el=detailpage&ps=default&eurl=&gl=US&hl=en", id); string source = HttpHelper.DownloadString(requestUrl); IDictionary <string, string> queries = HttpHelper.ParseQueryString(source); string status; if (queries.TryGetValue("status", out status) && status == "fail") { throw new VideoNotAvailableException(queries["reason"]); } try { IEnumerable <Uri> downloadUrls = ExtractDownloadUrls(source); return(GetVideoInfos(downloadUrls, videoTitle)); } catch (Exception ex) { ThrowYoutubeParseException(ex); } if (IsVideoUnavailable(pageSource)) { throw new VideoNotAvailableException(); } // If everything else fails, throw a generic YoutubeParseException ThrowYoutubeParseException(null); return(null); // Will never happen, but the compiler requires it }
private static JObject LoadJson(string url) { string pageSource = HttpHelper.DownloadString(url); if (IsVideoUnavailable(pageSource)) { throw new VideoNotAvailableException(); } var dataRegex = new Regex(@"ytplayer\.config\s*=\s*(\{.+?\});", RegexOptions.Multiline); string extractedJson = dataRegex.Match(pageSource).Result("$1"); return(JObject.Parse(extractedJson)); }
public static string DecipherWithVersion(string cipher, string cipherVersion) { // NB: We intentionally don't cache the operations as it seems that the same operation // doesn't work if the URL below isn't called string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/html5player-{0}.js", cipherVersion); string js = HttpHelper.DownloadString(jsUrl); //Find "C" in this: var A = B.sig||C (B.s) string functNamePattern = @"\.sig\s*\|\|(\w+)\("; var funcName = Regex.Match(js, functNamePattern).Groups[1].Value; //Match nested angle braces string funcBodyPattern = @"(?<brace>{([^{}]| ?(brace))*})"; //Match the function function_name (that has one argument) string funcPattern = string.Format(@"{0}\(\w+\){1}", funcName, funcBodyPattern); var funcBody = Regex.Match(js, funcPattern).Groups["brace"].Value; var lines = funcBody.Split(';'); string operations = ""; foreach (var line in lines.Skip(1).Take(lines.Length - 2)) { Match m; if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success) { //calling a two argument function (swap) operations += "w" + m.Groups["index"].Value + " "; } else if ((m = Regex.Match(line, @"slice\((?<index>\d+)\)")).Success) { //calling slice operations += "s" + m.Groups["index"].Value + " "; } else if ((m = Regex.Match(line, @"reverse\(\)")).Success) { //calling reverse operations += "r "; } } operations = operations.Trim(); return(DecipherWithOperations(cipher, operations)); }
private static string LocateThumbnail(string videoUrl) { string pageSource = HttpHelper.DownloadString(videoUrl); int start = pageSource.IndexOf("og:image"); if (start > 0) { string t = pageSource.Substring(start + 10); int eind = t.IndexOf(">"); t = t.Substring(0, eind); t = t.Trim().Replace("content=\"", "").Replace("\"", ""); return(t); // } else { return(""); } }
public static string DecipherWithVersion(string cipher, string cipherVersion) { string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/html5player-{0}.js", cipherVersion); string js = HttpHelper.DownloadString(jsUrl); //Find "C" in this: var A = B.sig||C (B.s) string functNamePattern = @"\.sig\s*\|\|(\w+)\("; var funcName = Regex.Match(js, functNamePattern).Groups[1].Value; string funcBodyPattern = @"(?<brace>{([^{}]| ?(brace))*})"; //Match nested angle braces string funcPattern = string.Format(@"{0}\(\w+\){1}", funcName, funcBodyPattern); var funcBody = Regex.Match(js, funcPattern).Groups["brace"].Value; //Entire sig function var lines = funcBody.Split(';'); //Each line in sig function string idReverse = "", idSlice = "", idCharSwap = ""; //Hold name for each cipher method string functionIdentifier = ""; string operations = ""; foreach (var line in lines.Skip(1).Take(lines.Length - 2)) //Matches the funcBody with each cipher method. Only runs till all three are defined. { if (!string.IsNullOrEmpty(idReverse) && !string.IsNullOrEmpty(idSlice) && !string.IsNullOrEmpty(idCharSwap)) { break; //Break loop if all three cipher methods are defined } functionIdentifier = GetFunctionFromLine(line); string reReverse = string.Format(@"{0}:\bfunction\b\(\w+\)", functionIdentifier); //Regex for reverse (one parameter) string reSlice = string.Format(@"{0}:\bfunction\b\([a],b\).(\breturn\b)?.?\w+\.", functionIdentifier); //Regex for slice (return or not) string reSwap = string.Format(@"{0}:\bfunction\b\(\w+\,\w\).\bvar\b.\bc=a\b", functionIdentifier); //Regex for the char swap. if (Regex.Match(js, reReverse).Success) { idReverse = functionIdentifier; //If def matched the regex for reverse then the current function is a defined as the reverse } if (Regex.Match(js, reSlice).Success) { idSlice = functionIdentifier; //If def matched the regex for slice then the current function is defined as the slice. } if (Regex.Match(js, reSwap).Success) { idCharSwap = functionIdentifier; //If def matched the regex for charSwap then the current function is defined as swap. } } 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 + " "; //operation is a swap (w) } if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success && functionIdentifier == idSlice) { operations += "s" + m.Groups["index"].Value + " "; //operation is a slice } if (functionIdentifier == idReverse) //No regex required for reverse (reverse method has no parameters) { operations += "r "; //operation is a reverse } } operations = operations.Trim(); return(DecipherWithOperations(cipher, operations)); }
public static string DecipherWithVersion(string cipher, string cipherVersion) { string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/player_ias-{0}.js", cipherVersion); string js = HttpHelper.DownloadString(jsUrl); //Find "C" in this: var A = B.sig||C (B.s) string functNamePattern = @"\""signature"",\s?([a-zA-Z0-9\$]+)\("; //Regex Formed To Find Word or DollarSign var funcName = Regex.Match(js, functNamePattern).Groups[1].Value; if (funcName.Contains("$")) { funcName = "\\" + funcName; //Due To Dollar Sign Introduction, Need To Escape } string funcPattern = @"(?!h\.)" + @funcName + @"=function\(\w+\)\{.*?\}"; //Escape funcName string var funcBody = Regex.Match(js, funcPattern, RegexOptions.Singleline).Value; //Entire sig function var lines = funcBody.Split(';'); //Each line in sig function string idReverse = "", idSlice = "", idCharSwap = ""; //Hold name for each cipher method string functionIdentifier = ""; string operations = ""; foreach (var line in lines.Skip(1).Take(lines.Length - 2)) //Matches the funcBody with each cipher method. Only runs till all three are defined. { if (!string.IsNullOrEmpty(idReverse) && !string.IsNullOrEmpty(idSlice) && !string.IsNullOrEmpty(idCharSwap)) { break; //Break loop if all three cipher methods are defined } functionIdentifier = GetFunctionFromLine(line); string reReverse = string.Format(@"{0}:\bfunction\b\(\w+\)", functionIdentifier); //Regex for reverse (one parameter) string reSlice = string.Format(@"{0}:\bfunction\b\([a],b\).(\breturn\b)?.?\w+\.", functionIdentifier); //Regex for slice (return or not) string reSwap = string.Format(@"{0}:\bfunction\b\(\w+\,\w\).\bvar\b.\bc=a\b", functionIdentifier); //Regex for the char swap. if (Regex.Match(js, reReverse).Success) { idReverse = functionIdentifier; //If def matched the regex for reverse then the current function is a defined as the reverse } if (Regex.Match(js, reSlice).Success) { idSlice = functionIdentifier; //If def matched the regex for slice then the current function is defined as the slice. } if (Regex.Match(js, reSwap).Success) { idCharSwap = functionIdentifier; //If def matched the regex for charSwap then the current function is defined as swap. } } 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 + " "; //operation is a swap (w) } if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success && functionIdentifier == idSlice) { operations += "s" + m.Groups["index"].Value + " "; //operation is a slice } if (functionIdentifier == idReverse) //No regex required for reverse (reverse method has no parameters) { operations += "r "; //operation is a reverse } } operations = operations.Trim(); return(DecipherWithOperations(cipher, operations)); }
public static string DecipherWithVersion(string cipher, string cipherVersion) { string input = HttpHelper.DownloadString(string.Format("http://s.ytimg.com/yts/jsbin/player-{0}.js", cipherVersion)); string pattern1 = "\\.sig\\s*\\|\\|([a-zA-Z0-9\\$]+)\\("; string str1 = Regex.Match(input, pattern1).Groups[1].Value; if (str1.Contains("$")) { str1 = "\\" + str1; } string pattern2 = str1 + "=function\\(\\w+\\)\\{.*?\\},"; string[] strArray = Regex.Match(input, pattern2, RegexOptions.Singleline).Value.Split(';'); string str2 = ""; string str3 = ""; string str4 = ""; string str5 = ""; IEnumerator <string> enumerator1 = ((IEnumerable <string>)Enumerable.Take <string>(Enumerable.Skip <string>(strArray, 1), strArray.Length - 2)).GetEnumerator(); try { while (((IEnumerator)enumerator1).MoveNext()) { string current = enumerator1.Current; if (!string.IsNullOrEmpty(str2) && !string.IsNullOrEmpty(str3)) { if (!string.IsNullOrEmpty(str4)) { break; } } string functionFromLine = Decipherer.GetFunctionFromLine(current); string pattern3 = string.Format("{0}:\\bfunction\\b\\(\\w+\\)", functionFromLine); string pattern4 = string.Format("{0}:\\bfunction\\b\\([a],b\\).(\\breturn\\b)?.?\\w+\\.", functionFromLine); string pattern5 = string.Format("{0}:\\bfunction\\b\\(\\w+\\,\\w\\).\\bvar\\b.\\bc=a\\b", functionFromLine); if (Regex.Match(input, pattern3).Success) { str2 = functionFromLine; } if (Regex.Match(input, pattern4).Success) { str3 = functionFromLine; } if (Regex.Match(input, pattern5).Success) { str4 = functionFromLine; } } } finally { if (enumerator1 != null) { ((IDisposable)enumerator1).Dispose(); } } IEnumerator <string> enumerator2 = ((IEnumerable <string>)Enumerable.Take <string>(Enumerable.Skip <string>(strArray, 1), strArray.Length - 2)).GetEnumerator(); try { while (((IEnumerator)enumerator2).MoveNext()) { string current = enumerator2.Current; string functionFromLine = Decipherer.GetFunctionFromLine(current); string pattern3 = "\\(\\w+,(?<index>\\d+)\\)"; Match match1; if ((match1 = Regex.Match(current, pattern3)).Success && functionFromLine == str4) { str5 = str5 + "w" + match1.Groups["index"].Value + " "; } string pattern4 = "\\(\\w+,(?<index>\\d+)\\)"; Match match2; if ((match2 = Regex.Match(current, pattern4)).Success && functionFromLine == str3) { str5 = str5 + "s" + match2.Groups["index"].Value + " "; } if (functionFromLine == str2) { str5 += "r "; } } } finally { if (enumerator2 != null) { ((IDisposable)enumerator2).Dispose(); } } string operations = str5.Trim(); return(Decipherer.DecipherWithOperations(cipher, operations)); }
private static JObject LoadJson(string url) { string pageSource = HttpHelper.DownloadString(url); return(ParseJson(pageSource)); }
private static YoutubeModel LoadModel(string videoUrl) { var videoId = videoUrl.Replace("https://youtube.com/watch?v=", ""); var url = $"https://www.youtube.com/get_video_info?video_id={videoId}&eurl=https://youtube.googleapis.com/v/{videoId}"; return(YoutubeModel.FromJson(HttpHelper.UrlDecode(HttpHelper.ParseQueryString(HttpHelper.DownloadString(url))["player_response"]))); }
public async static Task <string> DecipherWithVersion(string cipher, string cipherVersion) { // NB: We intentionally don't cache the operations as it seems that the same operation // doesn't work if the URL below isn't called string jsUrl = string.Format("http://s.ytimg.com/yts/jsbin/html5player-{0}.js", cipherVersion); string js = await HttpHelper.DownloadString(jsUrl); //Find "C" in this: var A = B.sig||C (B.s) string functNamePattern = @"\.sig\s*\|\|(\w+)\("; var funcName = Regex.Match(js, functNamePattern).Groups[1].Value; //Match nested angle braces string funcBodyPattern = @"(?<brace>{([^{}]| ?(brace))*})"; //Match the function function_name (that has one argument) string funcPattern = string.Format(@"{0}\(\w+\){1}", funcName, funcBodyPattern); var funcBody = Regex.Match(js, funcPattern).Groups["brace"].Value; var lines = funcBody.Split(';'); string operations = ""; //CYNAO - 07/08/2014, Test Fix /* The previous algoritms used a.splice(), where the decipher used the method (.splice()), however it seems the new algoritm * renames the method to random but unique characters (example ab.dc() = splice). This code determines what each method code is, * as it is defined once using the original name. */ string id_Reverse = "", id_Slice = "", id_CharSwap = ""; //Holds the new method name for each. string functionIdentifier = ""; string functIDPattern = @"\w+:\bfunction\b"; //Define as "NB:function(a,b)" where nb can be the three ciphers var funcID = Regex.Match(js, functIDPattern).Groups[1].Value; ///CODE ADDITION: Get the three ciphers by finding the definition foreach (var line in lines.Skip(1).Take(lines.Length - 2)) { string newVarName; //Previous algoritms used to be just "a." - now stores temp var name as its uneccessary int locOfDot, locOfBracket, functionIDLength; locOfDot = line.IndexOf("."); // NB.AC( - gets location of the dot. locOfBracket = line.IndexOf("("); //NB.AC( - gets location of the bracet functionIDLength = locOfBracket - (locOfDot + 1); newVarName = line.Substring(0, locOfDot); functionIdentifier = line.Substring(locOfDot + 1, functionIDLength); //leaving us with the function AC //This is what the definitions currently look like, could be changed so the regex needs improving. Messy fix. string tempReverse = string.Format(@"{0}:\bfunction\b\(\w+\)", functionIdentifier); //Reverse only one that doesnt have two parameters string tempSlice = string.Format(@"{0}:\bfunction\b\([a],b\).(\breturn\b)?.?\w+\.", functionIdentifier); //Regex for slice (return or not) string tempCharSwap = string.Format(@"{0}:\bfunction\b\(\w+\,\w\).\bvar\b.\bc=a\b", functionIdentifier); //Regex for the char swap. Match me; if ((me = Regex.Match(js, tempReverse)).Success) { id_Reverse = functionIdentifier; } //If def matched the regex for reverse then the current function is a defined as the reverse cipher if ((me = Regex.Match(js, tempSlice)).Success) { id_Slice = functionIdentifier; } //If def matched the regex for slice then the current function is defined as the slice cipher. if ((me = Regex.Match(js, tempCharSwap)).Success) { id_CharSwap = functionIdentifier; } //If def matched the regex for charSwap then the current function is defined as swap cipher. } foreach (var line in lines.Skip(1).Take(lines.Length - 2)) { Match m; ///DUPLICATE CODE! Improve. int locOfDot; int locOfBracket; int functionIDLength; locOfDot = line.IndexOf("."); locOfBracket = line.IndexOf("("); functionIDLength = locOfBracket - (locOfDot + 1); functionIdentifier = line.Substring(locOfDot + 1, functionIDLength); //Just needed this (define it as a member?) string newSliceIDRegex = string.Format(@"(?<index>\d+)\)+", functionIdentifier); if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success && functionIdentifier == id_CharSwap) { operations += "w" + m.Groups["index"].Value + " "; } //Character swap regex appears to be the same as before if ((m = Regex.Match(line, @"\(\w+,(?<index>\d+)\)")).Success && functionIdentifier == id_Slice) { operations += "s" + m.Groups["index"].Value + " "; } //Slice appears to have changed the index location??? //Could be wrong and the regex needs improving, seems to work on the latest algorithm though. if (functionIdentifier == id_Reverse) { operations += "r "; } //Reverse operation, no regex required } operations = operations.Trim(); return(DecipherWithOperations(cipher, operations)); }