public static async Task <WebStream> Post(string url, Dictionary <string, string> postdata, string encoding, string uagent = null, NameValueCollection headers = null, CookieCollection cookies = null, int timeout = 10000, bool redirect = true, string referer = null, IWebProxy proxy = null) { string pdata = postdata.PostFromDictionary(); return(await CreateStream(url, pdata, encoding, "application/x-www-form-urlencoded", uagent, headers, cookies, timeout, redirect, referer, proxy)); }
public async Task <ISession> Authenticate(Dictionary <string, object> authenticationmetadata) { CrunchySession session = new CrunchySession(); try { Response r = await _info.VerifyBaseAuthentication(authenticationmetadata); if (r.Status != ResponseStatus.Ok) { r.PropagateError(session); return(session); } Dictionary <string, string> form = new Dictionary <string, string>(); form.Add("formname", "RpcApiUser_Login"); form.Add("fail_url", "http://www.crunchyroll.com/login"); form.Add("name", authenticationmetadata.GetStringFromMetadata(DownloadPluginInfo.Username)); form.Add("password", authenticationmetadata.GetStringFromMetadata(DownloadPluginInfo.Password)); string postdata = form.PostFromDictionary(); WebStream ws = await WebStream.Post("https://www.crunchyroll.com/?a=formhandler", form, null, LibSet[UserAgentS], null, null, SocketTimeout, false, null, _info.ProxyFromGlobalRequirements(_global)); if (ws != null && ws.StatusCode == HttpStatusCode.Found) { ws.Cookies = await SetLocale(LocaleFromString(authenticationmetadata.GetStringFromMetadata(CrunchyPluginInfo.Language)), ws.Cookies); if (!VerifyLogin(ws.Cookies)) { session.Status = ResponseStatus.InvalidLogin; session.ErrorMessage = "Invalid Account Information"; session.cookies = new Dictionary <string, string>(); } else { session.cookies = ws.Cookies.ToDictionary(); session.Status = ResponseStatus.Ok; } } else { SetWebError(session); } ws?.Dispose(); } catch (Exception e) { session.Status = ResponseStatus.SystemError; session.ErrorMessage = e.ToString(); } return(session); }
public async Task<ISession> Authenticate(Dictionary<string,object> authenticationmetadata) { CrunchySession session = new CrunchySession(); try { Response r = await _info.VerifyBaseAuthentication(authenticationmetadata); if (r.Status != ResponseStatus.Ok) { r.PropagateError(session); return session; } Dictionary<string, string> form = new Dictionary<string, string>(); form.Add("formname", "RpcApiUser_Login"); form.Add("fail_url", "http://www.crunchyroll.com/login"); form.Add("name", authenticationmetadata.GetStringFromMetadata(DownloadPluginInfo.Username)); form.Add("password", authenticationmetadata.GetStringFromMetadata(DownloadPluginInfo.Password)); string postdata = form.PostFromDictionary(); WebStream ws = await WebStream.Post("https://www.crunchyroll.com/?a=formhandler",form,null,LibSet[UserAgentS],null,null,SocketTimeout,false,null, _info.ProxyFromGlobalRequirements(_global)); if (ws != null && ws.StatusCode == HttpStatusCode.Found) { ws.Cookies = await SetLocale(LocaleFromString(authenticationmetadata.GetStringFromMetadata(CrunchyPluginInfo.Language)), ws.Cookies); if (!VerifyLogin(ws.Cookies)) { session.Status = ResponseStatus.InvalidLogin; session.ErrorMessage = "Invalid Account Information"; session.cookies = new Dictionary<string, string>(); } else { session.cookies = ws.Cookies.ToDictionary(); session.Status = ResponseStatus.Ok; } } else { SetWebError(session); } ws?.Dispose(); } catch (Exception e) { session.Status=ResponseStatus.SystemError; session.ErrorMessage = e.ToString(); } return session; }
private async Task <FileSystemResult> GetToken(string code) { Dictionary <string, string> postdata = new Dictionary <string, string>(); postdata.Add("grant_type", "authorization_code"); postdata.Add("code", code); postdata.Add("client_id", ClientId); postdata.Add("client_secret", ClientSecret); postdata.Add("redirect_uri", RedirectUri); FileSystemResult <Token> fs = await CreateMetadataStream <Token>(OAuthUrl, Encoding.UTF8.GetBytes(postdata.PostFromDictionary())); if (!fs.IsOk) { return(new FileSystemResult(fs.Error)); } Token = fs.Result; return(new FileSystemResult()); }
internal async Task <FileSystemResult> MayRefreshToken(bool force = false) { if (Token == null) { return(new FileSystemResult("Authorization Token not found")); } if (Token.ExpirationDate.AddMinutes(3) < DateTime.Now || force) { string refreshToken = Token.RefreshToken; Dictionary <string, string> postdata = new Dictionary <string, string>(); postdata.Add("grant_type", "refresh_token"); postdata.Add("refresh_token", Token.RefreshToken); postdata.Add("client_id", ClientId); postdata.Add("client_secret", ClientSecret); Token = null; FileSystemResult <Token> fs = await CreateMetadataStream <Token>(OAuthUrl, Encoding.UTF8.GetBytes(postdata.PostFromDictionary())); if (!fs.IsOk) { return(new FileSystemResult(fs.Error)); } Token = fs.Result; if (string.IsNullOrEmpty(Token.RefreshToken)) { Token.RefreshToken = refreshToken; } } return(new FileSystemResult()); }
public async Task <Response> Download(ISession session, Episode episode, string template, string downloadpath, Quality quality, Format formats, CancellationToken token, IProgress <DownloadInfo> progress) { try { string deflangcode = "jpn"; string deflang = "日本語"; Response ret = new Response(); DaiSukiSession s = session as DaiSukiSession; if (s == null) { return new Response { ErrorMessage = "Invalid Session", Status = ResponseStatus.InvalidArgument } } ; if (!episode.PluginMetadata.ContainsKey("Url")) { return new Response { ErrorMessage = "Invalid Episode", Status = ResponseStatus.InvalidArgument } } ; DownloadInfo dp = new DownloadInfo { FileName = TemplateParser.FilenameFromEpisode(episode, quality, template), Format = formats, Percent = 0, Quality = quality }; token.ThrowIfCancellationRequested(); dp.Languages = new List <string>(); dp.Percent = 1; dp.Status = "Getting Metadata"; progress.Report(dp); List <string> todeleteFiles = new List <string>(); WebStream ws = await WebStream.Get(episode.PluginMetadata["Url"], null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, null, _info.ProxyFromGlobalRequirements(_global)); if (ws != null && ws.StatusCode == HttpStatusCode.OK) { if (!VerifyLogin(ws.Cookies)) { SetLoginError(ret); } else { StreamReader rd = new StreamReader(ws); string dta = rd.ReadToEnd(); rd.Dispose(); ws.Dispose(); Match bgn = bgnWrapper.Match(dta); if (!bgn.Success) { ret.ErrorMessage = "Unable to find Daisuki public key"; ret.Status = ResponseStatus.WebError; return(ret); } Match flash = flashVars.Match(dta); if (!flash.Success) { ret.ErrorMessage = "Seems this Episode is a YouTube video, unable to download"; ret.Status = ResponseStatus.WebError; return(ret); } MatchCollection col = flash2Vars.Matches(flash.Groups["vars"].Value); Dictionary <string, string> vars = new Dictionary <string, string>(); foreach (Match m in col) { if (m.Success) { vars.Add(m.Groups["name"].Value, m.Groups["value"].Value); } } if (!vars.ContainsKey("s") || !vars.ContainsKey("country") || !vars.ContainsKey("init")) { ret.ErrorMessage = "Some of Daisuki startup variables are missing"; ret.Status = ResponseStatus.WebError; return(ret); } token.ThrowIfCancellationRequested(); ws = await WebStream.Get(LibSet[BaseHostS] + bgn.Groups["wrapper"].Value, null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, null, _info.ProxyFromGlobalRequirements(_global)); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to find Daisuki public key"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return(ret); } rd = new StreamReader(ws); dta = rd.ReadToEnd(); rd.Dispose(); ws.Dispose(); Match mm = publicKey.Match(dta); if (!mm.Success) { ret.ErrorMessage = "Unable to find Daisuki public key"; ret.Status = ResponseStatus.WebError; return(ret); } string bld = mm.Groups["key"].Value.Replace("\\n", ""); token.ThrowIfCancellationRequested(); dp.Percent = 2; progress.Report(dp); ws = await WebStream.Get(LibSet[BaseHostS] + vars["country"] + "?cashPath=" + (long)((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds), null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, episode.PluginMetadata["Url"], _info.ProxyFromGlobalRequirements(_global)); Country c; if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to find Daisuki Country Code"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return(ret); } try { XmlSerializer ser = new XmlSerializer(typeof(Country)); c = (Country)ser.Deserialize(ws); ws.Dispose(); } catch (Exception) { ret.ErrorMessage = "Unable to find Daisuki Country Code"; ret.Status = ResponseStatus.WebError; ws.Dispose(); return(ret); } Dictionary <string, string> form = new Dictionary <string, string>(); Api api = new Api(); if (vars.ContainsKey("ss_id")) { api.SS_Id = vars["ss_id"]; } if (vars.ContainsKey("mv_id")) { api.MV_Id = vars["mv_id"]; } if (vars.ContainsKey("device_cd")) { api.Device_CD = vars["device_cd"]; } if (vars.ContainsKey("ss1_prm")) { api.SS1_PRM = vars["ss1_prm"]; } if (vars.ContainsKey("ss2_prm")) { api.SS2_PRM = vars["ss2_prm"]; } if (vars.ContainsKey("ss3_prm")) { api.SS3_PRM = vars["ss3_prm"]; } RSACryptoServiceProvider prov = ProviderFromPEM(bld); AesManaged aes = new AesManaged(); aes.GenerateKey(); aes.Mode = CipherMode.CBC; int blocksize = aes.BlockSize / 8; aes.IV = new byte[blocksize]; aes.KeySize = 256; aes.Padding = PaddingMode.Zeros; aes.GenerateKey(); byte[] apidata = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(api)); int nsize = ((apidata.Length + (blocksize - 1)) / blocksize) * blocksize; if (nsize != apidata.Length) { Array.Resize(ref apidata, nsize); } ICryptoTransform t = aes.CreateEncryptor(); byte[] enc = t.TransformFinalBlock(apidata, 0, nsize); byte[] key = prov.Encrypt(aes.Key, false); form.Add("s", vars["s"]); form.Add("c", c.CountryCode); form.Add("e", episode.PluginMetadata["Url"]); form.Add("d", Convert.ToBase64String(enc)); form.Add("a", Convert.ToBase64String(key)); token.ThrowIfCancellationRequested(); string n = form.PostFromDictionary(); ws = await WebStream.Get(LibSet[BaseHostS] + vars["init"] + "?" + n, null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, episode.PluginMetadata["Url"], _info.ProxyFromGlobalRequirements(_global)); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to retrieve metadata"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return(ret); } rd = new StreamReader(ws); dta = rd.ReadToEnd(); rd.Dispose(); ws.Dispose(); MetaEncrypt menc = JsonConvert.DeserializeObject <MetaEncrypt>(dta); if (menc == null || menc.Status != "00") { ret.ErrorMessage = "Unable to retrieve metadata"; ret.Status = ResponseStatus.WebError; return(ret); } t = aes.CreateDecryptor(); byte[] indata = Convert.FromBase64String(menc.EncryptedData); nsize = ((indata.Length + (blocksize - 1)) / blocksize) * blocksize; if (nsize != indata.Length) { Array.Resize(ref indata, nsize); } byte[] outdata = t.TransformFinalBlock(indata, 0, indata.Length); int start = outdata.Length; while (outdata[start - 1] == 0) { start--; } if (start != outdata.Length) { Array.Resize(ref outdata, start); } string final = Encoding.UTF8.GetString(outdata); Data ldta = JsonConvert.DeserializeObject <Data>(final); NameValueCollection headers = new NameValueCollection(); headers.Add("Accept", "*/*"); headers.Add("Accept-Language", "en-US"); headers.Add("x-flash-version", "18,0,0,232"); string guid = GenGUID(12); string playurl = ldta.play_url + "&g=" + guid + "&hdcore=3.2.0"; token.ThrowIfCancellationRequested(); dp.Percent = 3; dp.Status = "Gettings subtitles"; progress.Report(dp); dp.Languages = new List <string>(); Dictionary <string, string> subtitles = new Dictionary <string, string>(); if (string.IsNullOrEmpty(ldta.caption_url)) { dp.Languages.Add("Hardcoded"); } else { ws = await WebStream.Get(ldta.caption_url + "?cashPath=" + (long)((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds), null, LibSet[UserAgentS], headers, null, SocketTimeout, true, "http://img.daisuki.net/common2/pages/anime/swf/bngn_player_001.swf", _info.ProxyFromGlobalRequirements(_global)); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to retrieve subtitles"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return(ret); } TTML subs = new TTML(ws); subtitles = subs.ToAss(); ws.Dispose(); } dp.Percent = 4; dp.Status = "Downloading video"; progress.Report(dp); token.ThrowIfCancellationRequested(); ws = await WebStream.Get(playurl, null, LibSet[UserAgentS], headers, null, SocketTimeout, true, "http://img.daisuki.net/common2/pages/anime/swf/bngn_player_001.swf", _info.ProxyFromGlobalRequirements(_global)); int idx = playurl.LastIndexOf(".smil/", StringComparison.InvariantCulture); string baseurl = string.Empty; if (idx > 0) { baseurl = playurl.Substring(0, idx + 6); } if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to retrieve metadata"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return(ret); } XmlSerializer serm = new XmlSerializer(typeof(Manifest)); //Stream ms = File.OpenRead(@"C:\users\mpiva\Downloads\s.manifest"); //Manifest manifest = (Manifest)serm.Deserialize(ms); Manifest manifest = (Manifest)serm.Deserialize(ws); rd.Dispose(); ws.Dispose(); manifest.Init(); KeyValuePair <Media, Quality>?kv = BestMediaFromManifest(manifest, quality); if (kv == null) { ret.ErrorMessage = "Unable to find the best media"; ret.Status = ResponseStatus.WebError; return(ret); } dp.Quality = kv.Value.Value; Media media = kv.Value.Key; string inputs = string.Empty; string maps = String.Empty; int pp = 0; foreach (string k in subtitles.Keys) { string pth = Path.GetTempFileName() + ".ass"; todeleteFiles.Add(pth); File.WriteAllText(pth, subtitles[k]); inputs += "-i \"" + pth + "\" "; dp.Languages.Add(Languages.TranslateToOriginalLanguage(k)); maps += GetFFMPEGSubtitleArguments(pp + 1, pp, Languages.CodeFromLanguage(k), Languages.TranslateToOriginalLanguage(k)); pp++; } dp.Percent = 4; dp.FileName = TemplateParser.FilenameFromEpisode(episode, dp.Quality, template); dp.FullPath = Path.Combine(downloadpath, dp.FileName); token.ThrowIfCancellationRequested(); progress.Report(dp); string intermediatefile = dp.FullPath + ".tm1"; /* http://www.daisuki.net/etc/designs/daisuki/swf/bngn_player_002.swf*/ headers["X-Requested-With"] = "ShockwaveFlash/20.0.0.267"; FragmentProcessor frag = new FragmentProcessor(ws.Cookies, headers, LibSet[UserAgentS], SocketTimeout, episode.PluginMetadata["Url"], _info.ProxyFromGlobalRequirements(_global), 2, 5, intermediatefile); double dbl = 91; IProgress <double> d = new Progress <double>((val) => { dp.Percent = (val * dbl / 100) + 4; progress.Report(dp); }); todeleteFiles.Add(intermediatefile); await frag.Start(baseurl, guid, manifest, media, token, d); dp.Size = await ReMux(intermediatefile, inputs, maps, formats, deflangcode, deflang, 96, 4, dp, progress, token); dp.Percent = 100; dp.Status = "Finished"; progress.Report(dp); foreach (string del in todeleteFiles) { try { File.Delete(del); } catch (Exception) { } } ret.Status = ResponseStatus.Ok; } } else { SetWebError(ret); } ws?.Dispose(); return(ret); } catch (Exception e) { if (e is OperationCanceledException) { return new Response { ErrorMessage = "Canceled", Status = ResponseStatus.Canceled } } ; return(new Shows { ErrorMessage = e.ToString(), Status = ResponseStatus.SystemError }); } }
public async Task<Response> Download(ISession session, Episode episode, string template, string downloadpath, Quality quality, Format formats, CancellationToken token, IProgress<DownloadInfo> progress) { try { string deflangcode = "jpn"; string deflang = "日本語"; Response ret = new Response(); DaiSukiSession s = session as DaiSukiSession; if (s == null) return new Response { ErrorMessage = "Invalid Session", Status = ResponseStatus.InvalidArgument }; if (!episode.PluginMetadata.ContainsKey("Url")) return new Response { ErrorMessage = "Invalid Episode", Status = ResponseStatus.InvalidArgument }; DownloadInfo dp = new DownloadInfo { FileName = TemplateParser.FilenameFromEpisode(episode, quality, template), Format = formats, Percent = 0, Quality = quality }; token.ThrowIfCancellationRequested(); dp.Languages = new List<string>(); dp.Percent = 1; dp.Status = "Getting Metadata"; progress.Report(dp); List<string> todeleteFiles = new List<string>(); WebStream ws = await WebStream.Get(episode.PluginMetadata["Url"], null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, null, _info.ProxyFromGlobalRequirements(_global)); if (ws != null && ws.StatusCode == HttpStatusCode.OK) { if (!VerifyLogin(ws.Cookies)) SetLoginError(ret); else { StreamReader rd = new StreamReader(ws); string dta = rd.ReadToEnd(); rd.Dispose(); ws.Dispose(); Match bgn = bgnWrapper.Match(dta); if (!bgn.Success) { ret.ErrorMessage = "Unable to find Daisuki public key"; ret.Status=ResponseStatus.WebError; return ret; } Match flash = flashVars.Match(dta); if (!flash.Success) { ret.ErrorMessage = "Seems this Episode is a YouTube video, unable to download"; ret.Status = ResponseStatus.WebError; return ret; } MatchCollection col = flash2Vars.Matches(flash.Groups["vars"].Value); Dictionary<string,string> vars=new Dictionary<string, string>(); foreach (Match m in col) { if (m.Success) { vars.Add(m.Groups["name"].Value, m.Groups["value"].Value); } } if (!vars.ContainsKey("s") || !vars.ContainsKey("country") || !vars.ContainsKey("init")) { ret.ErrorMessage = "Some of Daisuki startup variables are missing"; ret.Status = ResponseStatus.WebError; return ret; } token.ThrowIfCancellationRequested(); ws = await WebStream.Get(LibSet[BaseHostS]+bgn.Groups["wrapper"].Value, null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true,null, _info.ProxyFromGlobalRequirements(_global)); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to find Daisuki public key"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return ret; } rd = new StreamReader(ws); dta = rd.ReadToEnd(); rd.Dispose(); ws.Dispose(); Match mm = publicKey.Match(dta); if (!mm.Success) { ret.ErrorMessage = "Unable to find Daisuki public key"; ret.Status = ResponseStatus.WebError; return ret; } string bld = mm.Groups["key"].Value.Replace("\\n", ""); token.ThrowIfCancellationRequested(); dp.Percent = 2; progress.Report(dp); ws = await WebStream.Get(LibSet[BaseHostS] + vars["country"]+"?cashPath="+ (long)((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds), null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, episode.PluginMetadata["Url"], _info.ProxyFromGlobalRequirements(_global)); Country c; if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to find Daisuki Country Code"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return ret; } try { XmlSerializer ser = new XmlSerializer(typeof(Country)); c = (Country)ser.Deserialize(ws); ws.Dispose(); } catch (Exception) { ret.ErrorMessage = "Unable to find Daisuki Country Code"; ret.Status = ResponseStatus.WebError; ws.Dispose(); return ret; } Dictionary<string, string> form = new Dictionary<string, string>(); Api api=new Api(); if (vars.ContainsKey("ss_id")) api.SS_Id = vars["ss_id"]; if (vars.ContainsKey("mv_id")) api.MV_Id = vars["mv_id"]; if (vars.ContainsKey("device_cd")) api.Device_CD = vars["device_cd"]; if (vars.ContainsKey("ss1_prm")) api.SS1_PRM = vars["ss1_prm"]; if (vars.ContainsKey("ss2_prm")) api.SS2_PRM = vars["ss2_prm"]; if (vars.ContainsKey("ss3_prm")) api.SS3_PRM = vars["ss3_prm"]; RSACryptoServiceProvider prov = ProviderFromPEM(bld); AesManaged aes = new AesManaged(); aes.GenerateKey(); aes.Mode=CipherMode.CBC; int blocksize = aes.BlockSize/8; aes.IV=new byte[blocksize]; aes.KeySize=256; aes.Padding=PaddingMode.Zeros; aes.GenerateKey(); byte[] apidata = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(api)); int nsize = ((apidata.Length + (blocksize - 1))/blocksize)*blocksize; if (nsize!=apidata.Length) Array.Resize(ref apidata,nsize); ICryptoTransform t=aes.CreateEncryptor(); byte[] enc=t.TransformFinalBlock(apidata, 0, nsize); byte[] key = prov.Encrypt(aes.Key,false); form.Add("s", vars["s"]); form.Add("c", c.CountryCode); form.Add("e", episode.PluginMetadata["Url"]); form.Add("d", Convert.ToBase64String(enc)); form.Add("a", Convert.ToBase64String(key)); token.ThrowIfCancellationRequested(); string n = form.PostFromDictionary(); ws = await WebStream.Get(LibSet[BaseHostS]+vars["init"]+"?"+n, null, LibSet[UserAgentS], null, s.cookies.ToCookieCollection(), SocketTimeout, true, episode.PluginMetadata["Url"], _info.ProxyFromGlobalRequirements(_global)); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to retrieve metadata"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return ret; } rd = new StreamReader(ws); dta = rd.ReadToEnd(); rd.Dispose(); ws.Dispose(); MetaEncrypt menc = JsonConvert.DeserializeObject<MetaEncrypt>(dta); if (menc == null || menc.Status != "00") { ret.ErrorMessage = "Unable to retrieve metadata"; ret.Status = ResponseStatus.WebError; return ret; } t = aes.CreateDecryptor(); byte[] indata = Convert.FromBase64String(menc.EncryptedData); nsize = ((indata.Length + (blocksize - 1)) / blocksize) * blocksize; if (nsize != indata.Length) Array.Resize(ref indata, nsize); byte[] outdata=t.TransformFinalBlock(indata, 0, indata.Length); int start = outdata.Length; while (outdata[start - 1] == 0) start--; if (start!=outdata.Length) Array.Resize(ref outdata,start); string final = Encoding.UTF8.GetString(outdata); Data ldta = JsonConvert.DeserializeObject<Data>(final); NameValueCollection headers = new NameValueCollection(); headers.Add("Accept", "*/*"); headers.Add("Accept-Language", "en-US"); headers.Add("x-flash-version", "18,0,0,232"); string guid = GenGUID(12); string playurl = ldta.play_url + "&g=" + guid + "&hdcore=3.2.0"; token.ThrowIfCancellationRequested(); dp.Percent = 3; dp.Status = "Gettings subtitles"; progress.Report(dp); dp.Languages = new List<string>(); Dictionary<string, string> subtitles = new Dictionary<string, string>(); if (string.IsNullOrEmpty(ldta.caption_url)) dp.Languages.Add("Hardcoded"); else { ws = await WebStream.Get(ldta.caption_url + "?cashPath=" + (long)((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds), null, LibSet[UserAgentS], headers, null, SocketTimeout, true, "http://img.daisuki.net/common2/pages/anime/swf/bngn_player_001.swf", _info.ProxyFromGlobalRequirements(_global)); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to retrieve subtitles"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return ret; } TTML subs = new TTML(ws); subtitles = subs.ToAss(); ws.Dispose(); } dp.Percent = 4; dp.Status = "Downloading video"; progress.Report(dp); token.ThrowIfCancellationRequested(); ws = await WebStream.Get(playurl, null, LibSet[UserAgentS], headers, null, SocketTimeout, true, "http://img.daisuki.net/common2/pages/anime/swf/bngn_player_001.swf", _info.ProxyFromGlobalRequirements(_global)); int idx = playurl.LastIndexOf(".smil/", StringComparison.InvariantCulture); string baseurl = string.Empty; if (idx > 0) baseurl = playurl.Substring(0, idx + 6); if (ws == null || ws.StatusCode != HttpStatusCode.OK) { ret.ErrorMessage = "Unable to retrieve metadata"; ret.Status = ResponseStatus.WebError; ws?.Dispose(); return ret; } XmlSerializer serm = new XmlSerializer(typeof(Manifest)); //Stream ms = File.OpenRead(@"C:\users\mpiva\Downloads\s.manifest"); //Manifest manifest = (Manifest)serm.Deserialize(ms); Manifest manifest = (Manifest)serm.Deserialize(ws); rd.Dispose(); ws.Dispose(); manifest.Init(); KeyValuePair<Media, Quality>? kv = BestMediaFromManifest(manifest, quality); if (kv == null) { ret.ErrorMessage = "Unable to find the best media"; ret.Status = ResponseStatus.WebError; return ret; } dp.Quality = kv.Value.Value; Media media = kv.Value.Key; string inputs = string.Empty; string maps = String.Empty; int pp = 0; foreach (string k in subtitles.Keys) { string pth = Path.GetTempFileName() + ".ass"; todeleteFiles.Add(pth); File.WriteAllText(pth, subtitles[k]); inputs += "-i \"" + pth + "\" "; dp.Languages.Add(Languages.TranslateToOriginalLanguage(k)); maps += GetFFMPEGSubtitleArguments(pp + 1, pp, Languages.CodeFromLanguage(k), Languages.TranslateToOriginalLanguage(k)); pp++; } dp.Percent = 4; dp.FileName = TemplateParser.FilenameFromEpisode(episode, dp.Quality, template); dp.FullPath = Path.Combine(downloadpath, dp.FileName); token.ThrowIfCancellationRequested(); progress.Report(dp); string intermediatefile = dp.FullPath + ".tm1"; /* http://www.daisuki.net/etc/designs/daisuki/swf/bngn_player_002.swf*/ headers["X-Requested-With"] = "ShockwaveFlash/20.0.0.267"; FragmentProcessor frag =new FragmentProcessor(ws.Cookies,headers, LibSet[UserAgentS], SocketTimeout, episode.PluginMetadata["Url"], _info.ProxyFromGlobalRequirements(_global), 2,5,intermediatefile); double dbl = 91; IProgress<double> d = new Progress<double>((val) => { dp.Percent = (val * dbl / 100) + 4; progress.Report(dp); }); todeleteFiles.Add(intermediatefile); await frag.Start(baseurl, guid, manifest, media, token, d); dp.Size = await ReMux(intermediatefile, inputs, maps, formats, deflangcode, deflang, 96, 4, dp, progress, token); dp.Percent = 100; dp.Status = "Finished"; progress.Report(dp); foreach (string del in todeleteFiles) { try { File.Delete(del); } catch (Exception) { } } ret.Status = ResponseStatus.Ok; } } else { SetWebError(ret); } ws?.Dispose(); return ret; } catch (Exception e) { if (e is OperationCanceledException) return new Response { ErrorMessage = "Canceled", Status = ResponseStatus.Canceled }; return new Shows { ErrorMessage = e.ToString(), Status = ResponseStatus.SystemError }; } }