/// <summary> /// 下载视频 /// </summary> /// <returns></returns> public override bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); //修正井号 Info.Url = Info.Url.TrimEnd('#'); //修正简写URL if (Regex.Match(Info.Url, @"^ac\d+$").Success) { Info.Url = "http://www.acfun.tv/v/" + Info.Url; } //修正index.html if (!Info.Url.EndsWith(".html")) { if (Info.Url.EndsWith("/")) { Info.Url += "index.html"; } else { Info.Url += "/index.html"; } } string url = Info.Url; //取得子页面文件名(例如"index_123.html") string suburl = Regex.Match(Info.Url, @"ac\d+/(?<part>index\.html|index_\d+\.html)").Groups["part"].Value; //取得AC号和子编号 Match mACNumber = Regex.Match(Info.Url, @"(?<ac>ac\d+)/index(_(?<sub>\d+)|)\.html"); Settings["ACNumber"] = mACNumber.Groups["ac"].Value; Settings["ACSubNumber"] = mACNumber.Groups["sub"].Success ? mACNumber.Groups["sub"].Value : "1"; //设置自定义文件名 Settings["CustomFileName"] = AcFunPlugin.DefaultFileNameFormat; if (Info.BasePlugin.Configuration.ContainsKey("CustomFileName")) { Settings["CustomFileName"] = Info.BasePlugin.Configuration["CustomFileName"]; } //是否通过【自动应答】禁用对话框 bool disableDialog = false; if (Info.AutoAnswer != null) { foreach (var item in Info.AutoAnswer) { if (item.Prefix == "acfun") { if (item.Identify == "auto") { disableDialog = true; } break; } } } try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); //分析id和视频存放站点(type) string type; string id = ""; //视频id //string ot = ""; //视频子id //取得embed块的源代码 Regex rEmbed = new Regex(@"\<div id=""area-player""\>.+?\</div\>", RegexOptions.Singleline); Match mEmbed = rEmbed.Match(src); string embedSrc = mEmbed.ToString().Replace("type=\"application/x-shockwave-flash\"", ""); //检查是否为Flash游戏 Regex rFlash = new Regex(@"src=""(?<player>.+?)\.swf"""); Match mFlash = rFlash.Match(embedSrc); #region 取得当前Flash播放器地址 //脚本地址 string playerScriptUrl = "http:" + Regex.Match(src, @"(?<=<script src="")//static\.acfun\.tv/dotnet/\d+/script/article\.js(?="">)").Value + @"?_version=12289360"; //脚本源代码 string playerScriptSrc = Network.GetHtmlSource(playerScriptUrl, Encoding.UTF8, Info.Proxy); //swf文件地址 string playerUrl = Regex.Match(playerScriptSrc, @"http://.+?swf").Value; //添加到插件设置中 if (Info.Settings.ContainsKey("PlayerUrl")) { Info.Settings["PlayerUrl"] = playerUrl; } else { Info.Settings.Add("PlayerUrl", playerUrl); } #endregion //如果是Flash游戏 if (mFlash.Success && !mFlash.Value.Contains("newflvplayer")) { type = "game"; } else { if (!embedSrc.Contains(@"text/javascript")) //旧版本 { //获取ID Regex rId = new Regex(@"(\?|amp;|"")id=(?<id>\w+)(?<ot>(-\w*|))"); Match mId = rId.Match(embedSrc); id = mId.Groups["id"].Value; if (Info.Settings.ContainsKey("cid")) { Info.Settings["cid"] = id; } else { Info.Settings.Add("cid", id); } //取得type值 Regex rType = new Regex(@"type(|\w)=(?<type>\w*)"); Match mType = rType.Match(embedSrc); type = mType.Groups["type"].Value; if (type.Equals("video", StringComparison.CurrentCultureIgnoreCase)) { type = "sina"; } } else { //取得acfun id值 Regex rAcfunId = new Regex(@"'id':'(?<id>\d+)"); Match mAcfunId = rAcfunId.Match(embedSrc); string acfunid = mAcfunId.Groups["id"].Value; //获取跳转 string getvideobyid = Network.GetHtmlSource("http://www.acfun.tv/api/getVideoByID.aspx?vid=" + acfunid, Encoding.UTF8); //将信息添加到Setting中 Regex rVideoInfo = new Regex(@"""(?<key>.+?)"":(""|)(?<value>.+?)(""|)[,|}]"); MatchCollection mcVideoInfo = rVideoInfo.Matches(getvideobyid); foreach (Match mVideoInfo in mcVideoInfo) { string key = mVideoInfo.Groups["key"].Value; string value = mVideoInfo.Groups["value"].Value; if (Info.Settings.ContainsKey(key)) { Info.Settings[key] = value; } else { Info.Settings.Add(key, value); } } id = Info.Settings["vid"]; type = Info.Settings["vtype"]; } } //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value.Replace(" - Acfun", "").Replace(" - 天下漫友是一家", ""); //取得所有子标题 Regex rSubTitle = new Regex(@"<a class=""pager pager-article"" href=""(?<part>.+?)"">(?<content>.+?)</a>"); MatchCollection mSubTitles = rSubTitle.Matches(src); //如果存在下拉列表框 if (mSubTitles.Count > 0) { //解析关联项需要同时满足的条件: //1.这个任务不是被其他任务所添加的 //2.用户设置了“解析关联项” if (!Info.IsBeAdded) { if (Info.ParseRelated) { //准备(地址-标题)字典 var dict = new Dictionary <string, string>(); foreach (Match item in mSubTitles) { dict.Add(url.Replace(suburl, item.Groups["part"].Value), item.Groups["content"].Value); } //用户选择任务 var ba = new Collection <string>(); if (!disableDialog) { ba = ToolForm.CreateMultiSelectForm(dict, Info.AutoAnswer, "acfun"); } //根据用户选择新建任务 foreach (string u in ba) { //新建任务 delegates.NewTask(new ParaNewTask(Info.BasePlugin, u, this.Info)); } } } } Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); Info.SubFilePath.Clear(); //下载弹幕 bool comment = DownloadSubtitle(title); if (!comment) { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } //解析器的解析结果 ParseResult pr = null; //如果允许下载视频 if ((Info.DownloadTypes & DownloadType.Video) != 0) { //检查type值 switch (type) { case "sina": //新浪视频 //解析视频 SinaVideoParser parserSina = new SinaVideoParser(); pr = parserSina.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "qq": //QQ视频 //解析视频 QQVideoParser parserQQ = new QQVideoParser(); pr = parserQQ.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "youku": //优酷视频 //解析视频 YoukuParser parserYouKu = new YoukuParser(); pr = parserYouKu.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "tudou": //土豆视频 TudouParser parserTudou = new TudouParser(); pr = parserTudou.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "game": //flash游戏 videos = new string[] { mFlash.Groups["player"].Value }; break; } Info.videos = videos; return(true); //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(videos[i]))) { ext = ".flv"; } else { ext = Path.GetExtension(videos[i]); } } if (ext == ".hlv") { ext = ".flv"; } //设置文件名 var renamehelper = new CustomFileNameHelper(); string filename = renamehelper.CombineFileName(Settings["CustomFileName"], title, "", Info.PartCount == 1 ? "" : Info.CurrentPart.ToString(), ext.Replace(".", ""), Info.Settings["ACNumber"], Info.Settings["ACSubNumber"]); filename = Path.Combine(Info.SaveDirectory.ToString(), filename); //生成父文件夹 if (!Directory.Exists(Path.GetDirectoryName(filename))) { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } //设置当前DownloadParameter currentParameter = new DownloadParameter() { //文件名 FilePath = filename, //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; //设置代理服务器 currentParameter.Proxy = Info.Proxy; //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success = false; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return(false); } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for } //end 判断是否下载视频 //如果插件设置中没有GenerateAcPlay项,或此项设置为true则生成.acplay快捷方式 if (!Info.BasePlugin.Configuration.ContainsKey("GenerateAcPlay") || Info.BasePlugin.Configuration["GenerateAcPlay"] == "true") { //生成AcPlay文件 string acplay = GenerateAcplayConfig(pr, title); //支持AcPlay直接播放 Info.Settings["AcPlay"] = acplay; } //支持导出列表 if (videos != null) { StringBuilder sb = new StringBuilder(videos.Length * 2); foreach (string item in videos) { sb.Append(item); sb.Append("|"); } if (Info.Settings.ContainsKey("ExportUrl")) { Info.Settings["ExportUrl"] = sb.ToString(); } else { Info.Settings.Add("ExportUrl", sb.ToString()); } } } catch (Exception ex) { throw ex; } //下载成功完成 return(true); }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); //修正井号 Info.Url = Info.Url.TrimEnd('#'); //修正旧版URL Info.Url = Info.Url.Replace("bilibili.us", "bilibili.tv"); //修正简写URL if (Regex.Match(Info.Url, @"^av\d{2,6}$").Success) { Info.Url = "http://www.bilibili.tv/video/" + Info.Url + "/"; } //修正index_1.html if (!Info.Url.EndsWith(".html")) { if (Info.Url.EndsWith("/")) { Info.Url += "index_1.html"; } else { Info.Url += "/index_1.html"; } } string url = Info.Url; //取得子页面文件名(例如"/video/av12345/index_123.html") string suburl = Regex.Match(Info.Url, @"bilibili\.tv(?<part>/video/av\d+/index_\d+\.html)").Groups["part"].Value; //是否通过【自动应答】禁用对话框 bool disableDialog = false; if (Info.AutoAnswer != null) { foreach (var item in Info.AutoAnswer) { if (item.Prefix == "bilibili") { if (item.Identify == "auto") { disableDialog = true; } break; } } } //视频地址数组 string[] videos = null; try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); //type值 string type = ""; #region 登录并重新获取网页源文件 //检查是否需要登录 if (src.Contains("您无权访问本页面")) //需要登录 { CookieContainer cookies = new CookieContainer(); //登录Bilibili UserLoginInfo user; //检查插件配置 try { user = new UserLoginInfo(); user.Username = Encoding.UTF8.GetString(Convert.FromBase64String(Info.Settings["user"])); user.Password = Encoding.UTF8.GetString(Convert.FromBase64String(Info.Settings["password"])); if (string.IsNullOrEmpty(user.Username) || string.IsNullOrEmpty(user.Password)) { throw new Exception(); } } catch { user = ToolForm.CreateLoginForm("https://secure.bilibili.tv/member/index_do.php?fmdo=user&dopost=regnew"); Info.Settings["user"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(user.Username)); Info.Settings["password"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(user.Password)); } //Post的数据 string postdata = "fmdo=login&dopost=login&refurl=http%%3A%%2F%%2Fbilibili.tv%%2F&keeptime=604800&userid=" + user.Username + "&pwd=" + user.Password + "&keeptime=604800"; byte[] data = Encoding.UTF8.GetBytes(postdata); //生成请求 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://secure.bilibili.tv/member/index_do.php"); req.Method = "POST"; req.Referer = "https://secure.bilibili.tv/login.php"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"; req.CookieContainer = new CookieContainer(); //发送POST数据 using (var outstream = req.GetRequestStream()) { outstream.Write(data, 0, data.Length); outstream.Flush(); } //关闭请求 req.GetResponse().Close(); cookies = req.CookieContainer; //保存cookies string cookiesstr = req.CookieContainer.GetCookieHeader(req.RequestUri); //字符串形式的cookies //重新请求网页 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); if (Info.Proxy != null) { request.Proxy = Info.Proxy; } //设置cookies request.CookieContainer = cookies; //获取网页源代码 src = Network.GetHtmlSource(request, Encoding.UTF8); } #endregion //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); //文件名称 string title = mTitle.Groups["title"].Value.Replace("- 嗶哩嗶哩", "").Replace("- ( ゜- ゜)つロ", "").Replace("乾杯~", "").Replace("- bilibili.tv", "").Trim(); //取得子标题 Regex rSubTitle = new Regex(@"<option value='(?<part>.+?\.html)'(| selected)>(?<content>.+?)</option>"); MatchCollection mSubTitles = rSubTitle.Matches(src); //如果存在下拉列表框 if (mSubTitles.Count > 0) { //确定当前视频的子标题 foreach (Match item in mSubTitles) { if (suburl == item.Groups["part"].Value) { title = title + " - " + item.Groups["content"].Value; break; } } //如果需要解析关联下载项 //解析关联项需要同时满足的条件: //1.这个任务不是被其他任务所添加的 //2.用户设置了“解析关联项” if (!Info.IsBeAdded) { if (Info.ParseRelated) { //准备(地址-标题)字典 var dict = new Dictionary <string, string>(); foreach (Match item in mSubTitles) { if (suburl != item.Groups["part"].Value) { dict.Add(url.Replace(suburl, item.Groups["part"].Value), item.Groups["content"].Value); } } //用户选择任务 var ba = new Collection <string>(); if (!disableDialog) { ba = ToolForm.CreateMultiSelectForm(dict, Info.AutoAnswer, "bilibili"); } //根据用户选择新建任务 foreach (string u in ba) { //新建任务 delegates.NewTask(new ParaNewTask(Info.BasePlugin, u, this.Info)); } } } } Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //重新设置保存目录(生成子文件夹) if (!Info.SaveDirectory.ToString().EndsWith(title)) { string newdir = Path.Combine(Info.SaveDirectory.ToString(), title); if (!Directory.Exists(newdir)) { Directory.CreateDirectory(newdir); } Info.SaveDirectory = new DirectoryInfo(newdir); } //清空地址 Info.FilePath.Clear(); Info.SubFilePath.Clear(); //视频id string id = ""; //分析id和视频存放站点(type) //取得"bofqi块的源代码 Regex rEmbed = new Regex("<div class=\"scontent\" id=\"bofqi\">(?<content>.*?)</div>", RegexOptions.Singleline); Match mEmbed = rEmbed.Match(src); string embedSrc = mEmbed.Groups["content"].Value.Replace("type=\"application/x-shockwave-flash\"", ""); //检查"file"参数 Regex rFile = new Regex("file=(\"|)(?<file>.+?)(\"|&)"); Match mFile = rFile.Match(embedSrc); //取得Flash地址 Regex rFlash = new Regex("src=\"(?<flash>.*?\\.swf)\""); Match mFlash = rFlash.Match(embedSrc); //取得id值 Regex rId = new Regex(@"(?<idname>(\w{0,2}id|data))=(?<id>([\w\-]+|$http://.+?$))".Replace("$", "\"")); Match mId = rId.Match(embedSrc); //取得ID id = mId.Groups["id"].Value; //取得type值 type = mId.Groups["idname"].Value; //解析器的解析结果 ParseResult pr = null; //如果不是“仅下载字幕” if (Info.DownSub != DownloadSubtitleType.DownloadSubtitleOnly) { if (mFile.Success) //如果有file参数 { string fileurl = mFile.Groups["file"].Value; videos = new string[] { fileurl }; } else if (mId.Success) //如果是普通的外链 { //检查外链 switch (type) { case "qid": //QQ视频 //解析视频 QQVideoParser parserQQ = new QQVideoParser(); pr = parserQQ.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "ykid": //优酷视频 //解析视频 YoukuParser parserYouKu = new YoukuParser(); pr = parserYouKu.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "uid": //土豆视频 //解析视频 TudouParser parserTudou = new TudouParser(); pr = parserTudou.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "data": //Flash游戏 id = id.Replace("\"", ""); videos = new string[] { id }; break; default: //新浪视频 SinaVideoParser parserSina = new SinaVideoParser(); pr = parserSina.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; } } else //如果是游戏 { string flashurl = mFlash.Groups["flash"].Value; videos = new string[] { flashurl }; } Info.videos = videos; return(true); //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(videos[i]))) { ext = ".flv"; } else { ext = Path.GetExtension(videos[i]); } } if (ext == ".hlv") { ext = ".flv"; } //设置当前DownloadParameter if (Info.PartCount == 1) { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; } else { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + "(" + (i + 1).ToString() + ")" + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; } //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return(false); } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for } //end 判断是否下载视频 //下载弹幕 bool comment = DownloadComment(title, id); //生成AcPlay文件 string acplay = GenerateAcplayConfig(pr, title); if (!comment) { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } //支持导出列表 StringBuilder sb = new StringBuilder(videos.Length * 2); foreach (string item in videos) { sb.Append(item); sb.Append("|"); } if (Info.Settings.ContainsKey("ExportUrl")) { Info.Settings["ExportUrl"] = sb.ToString(); } else { Info.Settings.Add("ExportUrl", sb.ToString()); } //支持AcPlay if (Info.Settings.ContainsKey("AcPlay")) { Info.Settings["AcPlay"] = acplay; } else { Info.Settings.Add("AcPlay", acplay); } } catch (Exception ex) { Info.Settings["user"] = ""; Info.Settings["password"] = ""; throw ex; } return(true); }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); string url = Info.Url; //视频地址数组 string[] videos = null; try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); //视频id string id = ""; //type值 string type = ""; //player id string playerId = ""; //选择的视频(下拉列表) int selectedvideo = 0; //清空地址 Info.FilePath.Clear(); //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); //分析id和视频存放站点(type) //取得"mplayer块的源代码 Regex rEmbed = new Regex(@"<div id=""mplayer"">.+?</embed>", RegexOptions.Singleline); Match mEmbed = rEmbed.Match(src); string embedSrc = mEmbed.Value; //取得id值 Regex rId = new Regex(@"\w+id=(?<id>\w+)"); MatchCollection mIds = rId.Matches(embedSrc); //取得type值 Regex rType = new Regex(@"type=(?<type>\w+)"); MatchCollection mTypes = rType.Matches(embedSrc); //取得PlayerID值 Regex rPlayerid = new Regex(@"<li>(?<playerid>content.+?)</li>"); Match mPlayerid = rPlayerid.Match(embedSrc); playerId = mPlayerid.Groups["playerid"].Value; //取得所有子标题 Regex rSubTitle = new Regex(@"\|(?<subtitle>.*?)(\*\*|</li>)"); MatchCollection mSubTitles = rSubTitle.Matches(embedSrc); Match mId = null; Match mType = null; Match mSubTitle = null; if (mIds.Count > 1) //如果数量大于一个 { //定义字典 var dict = new Dictionary<string, string>(); for (int i = 0; i < mIds.Count; i++) { dict.Add(i.ToString(), (i + 1).ToString() + "、" + mSubTitles[i].Groups["subtitle"].Value); } //用户选择下载哪一个视频 selectedvideo = int.Parse(ToolForm.CreateSingleSelectForm("请选择视频:", dict, "", Info.AutoAnswer, "tucao")); mId = mIds[selectedvideo]; mType = mTypes[selectedvideo]; mSubTitle = mSubTitles[selectedvideo]; } else { mId = mIds[0]; mType = mTypes[0]; mSubTitle = mSubTitles[0]; } //设置标题 string title = mTitle.Groups["title"].Value.Replace("- 吐槽 - tucao.cc", ""); string subTitle = mSubTitle.Groups["subtitle"].Value; if (!string.IsNullOrEmpty(subTitle)) //如果存在子标题(视频为合集) { //更改标题 title = title + " - " + subTitle; //更改URL防止hash时出错 Info.Url = Info.Url + "#" + subTitle; } //过滤非法字符 Info.Title = title; title = Tools.InvalidCharacterFilter(title, ""); //取得ID id = mId.Groups["id"].Value; //取得type值 type = mType.Groups["type"].Value; DownloadSubtitleType downsub = Info.DownSub; //如果不是“仅下载字幕” if (downsub != DownloadSubtitleType.DownloadSubtitleOnly) { //检查外链 switch (type) { case "qq": //QQ视频 //解析视频 QQVideoParser parserQQ = new QQVideoParser(); videos = parserQQ.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; case "youku": //优酷视频 //解析视频 YoukuParser parserYouKu = new YoukuParser(); videos = parserYouKu.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; case "tudou": //土豆视频 //解析视频 TudouParser parserTudou = new TudouParser(); videos = parserTudou.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; case "sina": //新浪视频 SinaVideoParser parserSina = new SinaVideoParser(); videos = parserSina.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; } Info.videos = videos; return true; //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(videos[i]))) ext = ".flv"; else ext = Path.GetExtension(videos[i]); } if (ext == ".hlv") ext = ".flv"; //设置当前DownloadParameter if (Info.PartCount == 1) { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } else { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + "(" + (i + 1).ToString() + ")" + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success; //添加断点续传段 //if (File.Exists(currentParameter.FilePath)) //{ // //取得文件长度 // int len = int.Parse(new FileInfo(currentParameter.FilePath).Length.ToString()); // //设置RangeStart属性 // currentParameter.RangeStart = len; // Info.Title = "[续传]" + Info.Title; //} //else //{ // Info.Title = Info.Title.Replace("[续传]", ""); //} //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return false; } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for } //下载弹幕 if ((downsub != DownloadSubtitleType.DontDownloadSubtitle) && !string.IsNullOrEmpty(playerId)) { //----------下载字幕----------- delegates.TipText(new ParaTipText(this.Info, "正在下载字幕文件")); //字幕文件(on)地址 string subfile = Path.Combine(Info.SaveDirectory.ToString(), title + ".xml"); Info.SubFilePath.Add(subfile); //取得字幕文件(on)地址 string subUrl = "http://www.tucao.cc/index.php?m=comment&c=mukio&a=init&type=" + type + "&playerID=" + playerId + "~" + selectedvideo.ToString() + "&r=0.09502756828442216"; //下载字幕文件 try { Network.DownloadFile(new DownloadParameter() { Url = subUrl, FilePath = subfile, Proxy = Info.Proxy }); } catch { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } }// end 下载弹幕xml } catch (Exception ex) { throw ex; }//end try //下载成功完成 return true; }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); //修正井号 Info.Url = Info.Url.TrimEnd('#'); //修正简写URL if (Regex.Match(Info.Url, @"^ac\d+$").Success) Info.Url = "http://www.acfun.tv/v/" + Info.Url; //修正index.html if (!Info.Url.EndsWith(".html")) { if (Info.Url.EndsWith("/")) Info.Url += "index.html"; else Info.Url += "/index.html"; } string url = Info.Url; //取得子页面文件名(例如"index_123.html") string suburl = Regex.Match(Info.Url, @"ac\d+/(?<part>index\.html|index_\d+\.html)").Groups["part"].Value; //是否通过【自动应答】禁用对话框 bool disableDialog = false; if (Info.AutoAnswer != null) { foreach (var item in Info.AutoAnswer) { if (item.Prefix == "acfun") { if (item.Identify == "auto") disableDialog = true; break; } } } try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); //分析id和视频存放站点(type) string type; string id = ""; //视频id //string ot = ""; //视频子id //取得embed块的源代码 Regex rEmbed = new Regex(@"\<div id=""area-player""\>.+?\</div\>", RegexOptions.Singleline); Match mEmbed = rEmbed.Match(src); string embedSrc = mEmbed.ToString().Replace("type=\"application/x-shockwave-flash\"", ""); //检查是否为Flash游戏 Regex rFlash = new Regex(@"src=""(?<player>.+?)\.swf"""); Match mFlash = rFlash.Match(embedSrc); #region 取得当前Flash播放器地址 //脚本地址 string playerScriptUrl = "http:" + Regex.Match(src, @"(?<=<script src="")//static\.acfun\.tv/dotnet/\d+/script/article\.js(?="">)").Value + @"?_version=12289360"; //脚本源代码 string playerScriptSrc = Network.GetHtmlSource(playerScriptUrl, Encoding.UTF8, Info.Proxy); //swf文件地址 string playerUrl = Regex.Match(playerScriptSrc, @"http://.+?swf").Value; //添加到插件设置中 if (Info.Settings.ContainsKey("PlayerUrl")) Info.Settings["PlayerUrl"] = playerUrl; else Info.Settings.Add("PlayerUrl", playerUrl); #endregion //如果是Flash游戏 if (mFlash.Success && !mFlash.Value.Contains("newflvplayer")) { type = "game"; } else { if (!embedSrc.Contains(@"text/javascript")) //旧版本 { //获取ID Regex rId = new Regex(@"(\?|amp;|"")id=(?<id>\w+)(?<ot>(-\w*|))"); Match mId = rId.Match(embedSrc); id = mId.Groups["id"].Value; if (Info.Settings.ContainsKey("cid")) Info.Settings["cid"] = id; else Info.Settings.Add("cid", id); //取得type值 Regex rType = new Regex(@"type(|\w)=(?<type>\w*)"); Match mType = rType.Match(embedSrc); type = mType.Groups["type"].Value; if (type.Equals("video", StringComparison.CurrentCultureIgnoreCase)) type = "sina"; } else { //取得acfun id值 Regex rAcfunId = new Regex(@"'id':'(?<id>\d+)"); Match mAcfunId = rAcfunId.Match(embedSrc); string acfunid = mAcfunId.Groups["id"].Value; //获取跳转 string getvideobyid = Network.GetHtmlSource("http://www.acfun.tv/api/getVideoByID.aspx?vid=" + acfunid, Encoding.UTF8); //将信息添加到Setting中 Regex rVideoInfo = new Regex(@"""(?<key>.+?)"":(""|)(?<value>.+?)(""|)[,|}]"); MatchCollection mcVideoInfo = rVideoInfo.Matches(getvideobyid); foreach (Match mVideoInfo in mcVideoInfo) { string key = mVideoInfo.Groups["key"].Value; string value = mVideoInfo.Groups["value"].Value; if (Info.Settings.ContainsKey(key)) Info.Settings[key] = value; else Info.Settings.Add(key, value); } id = Info.Settings["vid"]; type = Info.Settings["vtype"]; } } //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value.Replace(" - Acfun", "").Replace(" - 天下漫友是一家", ""); //取得所有子标题 Regex rSubTitle = new Regex(@"<a class=""pager pager-article"" href=""(?<part>.+?)"">(?<content>.+?)</a>"); MatchCollection mSubTitles = rSubTitle.Matches(src); //如果存在下拉列表框 if (mSubTitles.Count > 0) { //解析关联项需要同时满足的条件: //1.这个任务不是被其他任务所添加的 //2.用户设置了“解析关联项” if (!Info.IsBeAdded) { if (Info.ParseRelated) { //准备(地址-标题)字典 var dict = new Dictionary<string, string>(); foreach (Match item in mSubTitles) { dict.Add(url.Replace(suburl, item.Groups["part"].Value), item.Groups["content"].Value); } //用户选择任务 var ba = new Collection<string>(); if (!disableDialog) ba = ToolForm.CreateMultiSelectForm(dict, Info.AutoAnswer, "acfun"); //根据用户选择新建任务 foreach (string u in ba) { //新建任务 delegates.NewTask(new ParaNewTask(Info.BasePlugin, u, this.Info)); } } } } Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //重新设置保存目录(生成子文件夹) if (!Info.SaveDirectory.ToString().EndsWith(title)) { string newdir = Path.Combine(Info.SaveDirectory.ToString(), title); if (!Directory.Exists(newdir)) Directory.CreateDirectory(newdir); Info.SaveDirectory = new DirectoryInfo(newdir); } //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); Info.SubFilePath.Clear(); //解析器的解析结果 ParseResult pr = null; //如果不是“仅下载字幕” if (Info.DownSub != DownloadSubtitleType.DownloadSubtitleOnly) { //检查type值 switch (type) { case "sina": //新浪视频 //解析视频 SinaVideoParser parserSina = new SinaVideoParser(); pr = parserSina.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "qq": //QQ视频 //解析视频 QQVideoParser parserQQ = new QQVideoParser(); pr = parserQQ.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "youku": //优酷视频 //解析视频 YoukuParser parserYouKu = new YoukuParser(); pr = parserYouKu.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "tudou": //土豆视频 TudouParser parserTudou = new TudouParser(); pr = parserTudou.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "game": //flash游戏 videos = new string[] { mFlash.Groups["player"].Value }; break; } Info.videos = videos; return true; //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(videos[i]))) ext = ".flv"; else ext = Path.GetExtension(videos[i]); } if (ext == ".hlv") ext = ".flv"; //设置当前DownloadParameter if (Info.PartCount == 1) { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; } else { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + "(" + (i + 1).ToString() + ")" + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; } //设置代理服务器 currentParameter.Proxy = Info.Proxy; //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success = false; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return false; } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for }//end 判断是否下载视频 //下载弹幕 bool comment = DownloadComment(title); //生成AcPlay文件 string acplay = GenerateAcplayConfig(pr, title); if (!comment) { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } //支持导出列表 StringBuilder sb = new StringBuilder(videos.Length * 2); foreach (string item in videos) { sb.Append(item); sb.Append("|"); } if (Info.Settings.ContainsKey("ExportUrl")) Info.Settings["ExportUrl"] = sb.ToString(); else Info.Settings.Add("ExportUrl", sb.ToString()); //支持AcPlay if (Info.Settings.ContainsKey("AcPlay")) Info.Settings["AcPlay"] = acplay; else Info.Settings.Add("AcPlay", acplay); } catch (Exception ex) { throw ex; } //下载成功完成 return true; }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); string url = Info.Url; //视频地址数组 string[] videos = null; try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); //视频id string id = ""; //type值 string type = ""; //player id string playerId = ""; //选择的视频(下拉列表) int selectedvideo = 0; //清空地址 Info.FilePath.Clear(); //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); //分析id和视频存放站点(type) //取得"mplayer块的源代码 Regex rEmbed = new Regex(@"<div id=""mplayer"">.+?</embed>", RegexOptions.Singleline); Match mEmbed = rEmbed.Match(src); string embedSrc = mEmbed.Value; //取得id值 Regex rId = new Regex(@"\w+id=(?<id>\w+)"); MatchCollection mIds = rId.Matches(embedSrc); //取得type值 Regex rType = new Regex(@"type=(?<type>\w+)"); MatchCollection mTypes = rType.Matches(embedSrc); //取得PlayerID值 Regex rPlayerid = new Regex(@"<li>(?<playerid>content.+?)</li>"); Match mPlayerid = rPlayerid.Match(embedSrc); playerId = mPlayerid.Groups["playerid"].Value; //取得所有子标题 Regex rSubTitle = new Regex(@"\|(?<subtitle>.*?)(\*\*|</li>)"); MatchCollection mSubTitles = rSubTitle.Matches(embedSrc); Match mId = null; Match mType = null; Match mSubTitle = null; if (mIds.Count > 1) //如果数量大于一个 { //定义字典 var dict = new Dictionary <string, string>(); for (int i = 0; i < mIds.Count; i++) { dict.Add(i.ToString(), (i + 1).ToString() + "、" + mSubTitles[i].Groups["subtitle"].Value); } //用户选择下载哪一个视频 selectedvideo = int.Parse(ToolForm.CreateSingleSelectForm("请选择视频:", dict, "", Info.AutoAnswer, "tucao")); mId = mIds[selectedvideo]; mType = mTypes[selectedvideo]; mSubTitle = mSubTitles[selectedvideo]; } else { mId = mIds[0]; mType = mTypes[0]; mSubTitle = mSubTitles[0]; } //设置标题 string title = mTitle.Groups["title"].Value.Replace("- 吐槽 - tucao.cc", ""); string subTitle = mSubTitle.Groups["subtitle"].Value; if (!string.IsNullOrEmpty(subTitle)) //如果存在子标题(视频为合集) { //更改标题 title = title + " - " + subTitle; //更改URL防止hash时出错 Info.Url = Info.Url + "#" + subTitle; } //过滤非法字符 Info.Title = title; title = Tools.InvalidCharacterFilter(title, ""); //取得ID id = mId.Groups["id"].Value; //取得type值 type = mType.Groups["type"].Value; DownloadSubtitleType downsub = Info.DownSub; //如果不是“仅下载字幕” if (downsub != DownloadSubtitleType.DownloadSubtitleOnly) { //检查外链 switch (type) { case "qq": //QQ视频 //解析视频 QQVideoParser parserQQ = new QQVideoParser(); videos = parserQQ.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; case "youku": //优酷视频 //解析视频 YoukuParser parserYouKu = new YoukuParser(); videos = parserYouKu.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; case "tudou": //土豆视频 //解析视频 TudouParser parserTudou = new TudouParser(); videos = parserTudou.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; case "sina": //新浪视频 SinaVideoParser parserSina = new SinaVideoParser(); videos = parserSina.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); break; } Info.videos = videos; return(true); //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(videos[i]))) { ext = ".flv"; } else { ext = Path.GetExtension(videos[i]); } } if (ext == ".hlv") { ext = ".flv"; } //设置当前DownloadParameter if (Info.PartCount == 1) { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } else { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + "(" + (i + 1).ToString() + ")" + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success; //添加断点续传段 //if (File.Exists(currentParameter.FilePath)) //{ // //取得文件长度 // int len = int.Parse(new FileInfo(currentParameter.FilePath).Length.ToString()); // //设置RangeStart属性 // currentParameter.RangeStart = len; // Info.Title = "[续传]" + Info.Title; //} //else //{ // Info.Title = Info.Title.Replace("[续传]", ""); //} //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return(false); } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for } //下载弹幕 if ((downsub != DownloadSubtitleType.DontDownloadSubtitle) && !string.IsNullOrEmpty(playerId)) { //----------下载字幕----------- delegates.TipText(new ParaTipText(this.Info, "正在下载字幕文件")); //字幕文件(on)地址 string subfile = Path.Combine(Info.SaveDirectory.ToString(), title + ".xml"); Info.SubFilePath.Add(subfile); //取得字幕文件(on)地址 string subUrl = "http://www.tucao.cc/index.php?m=comment&c=mukio&a=init&type=" + type + "&playerID=" + playerId + "~" + selectedvideo.ToString() + "&r=0.09502756828442216"; //下载字幕文件 try { Network.DownloadFile(new DownloadParameter() { Url = subUrl, FilePath = subfile, Proxy = Info.Proxy }); } catch { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } } // end 下载弹幕xml } catch (Exception ex) { throw ex; } //end try //下载成功完成 return(true); }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); //修正井号 Info.Url = Info.Url.TrimEnd('#'); //修正旧版URL Info.Url = Info.Url.Replace("bilibili.us", "bilibili.tv"); //修正简写URL if (Regex.Match(Info.Url, @"^av\d{2,6}$").Success) Info.Url = "http://www.bilibili.tv/video/" + Info.Url + "/"; //修正index_1.html if (!Info.Url.EndsWith(".html")) { if (Info.Url.EndsWith("/")) Info.Url += "index_1.html"; else Info.Url += "/index_1.html"; } string url = Info.Url; //取得子页面文件名(例如"/video/av12345/index_123.html") string suburl = Regex.Match(Info.Url, @"bilibili\.tv(?<part>/video/av\d+/index_\d+\.html)").Groups["part"].Value; //是否通过【自动应答】禁用对话框 bool disableDialog = false; if (Info.AutoAnswer != null) { foreach (var item in Info.AutoAnswer) { if (item.Prefix == "bilibili") { if (item.Identify == "auto") disableDialog = true; break; } } } //视频地址数组 string[] videos = null; try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); //type值 string type = ""; #region 登录并重新获取网页源文件 //检查是否需要登录 if (src.Contains("您无权访问本页面")) //需要登录 { CookieContainer cookies = new CookieContainer(); //登录Bilibili UserLoginInfo user; //检查插件配置 try { user = new UserLoginInfo(); user.Username = Encoding.UTF8.GetString(Convert.FromBase64String(Info.Settings["user"])); user.Password = Encoding.UTF8.GetString(Convert.FromBase64String(Info.Settings["password"])); if (string.IsNullOrEmpty(user.Username) || string.IsNullOrEmpty(user.Password)) throw new Exception(); } catch { user = ToolForm.CreateLoginForm("https://secure.bilibili.tv/member/index_do.php?fmdo=user&dopost=regnew"); Info.Settings["user"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(user.Username)); Info.Settings["password"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(user.Password)); } //Post的数据 string postdata = "fmdo=login&dopost=login&refurl=http%%3A%%2F%%2Fbilibili.tv%%2F&keeptime=604800&userid=" + user.Username + "&pwd=" + user.Password + "&keeptime=604800"; byte[] data = Encoding.UTF8.GetBytes(postdata); //生成请求 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://secure.bilibili.tv/member/index_do.php"); req.Method = "POST"; req.Referer = "https://secure.bilibili.tv/login.php"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"; req.CookieContainer = new CookieContainer(); //发送POST数据 using (var outstream = req.GetRequestStream()) { outstream.Write(data, 0, data.Length); outstream.Flush(); } //关闭请求 req.GetResponse().Close(); cookies = req.CookieContainer; //保存cookies string cookiesstr = req.CookieContainer.GetCookieHeader(req.RequestUri); //字符串形式的cookies //重新请求网页 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); if (Info.Proxy != null) request.Proxy = Info.Proxy; //设置cookies request.CookieContainer = cookies; //获取网页源代码 src = Network.GetHtmlSource(request, Encoding.UTF8); } #endregion //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); //文件名称 string title = mTitle.Groups["title"].Value.Replace("- 嗶哩嗶哩", "").Replace("- ( ゜- ゜)つロ", "").Replace("乾杯~", "").Replace("- bilibili.tv", "").Trim(); //取得子标题 Regex rSubTitle = new Regex(@"<option value='(?<part>.+?\.html)'(| selected)>(?<content>.+?)</option>"); MatchCollection mSubTitles = rSubTitle.Matches(src); //如果存在下拉列表框 if (mSubTitles.Count > 0) { //确定当前视频的子标题 foreach (Match item in mSubTitles) { if (suburl == item.Groups["part"].Value) { title = title + " - " + item.Groups["content"].Value; break; } } //如果需要解析关联下载项 //解析关联项需要同时满足的条件: //1.这个任务不是被其他任务所添加的 //2.用户设置了“解析关联项” if (!Info.IsBeAdded) { if (Info.ParseRelated) { //准备(地址-标题)字典 var dict = new Dictionary<string, string>(); foreach (Match item in mSubTitles) { if (suburl != item.Groups["part"].Value) { dict.Add(url.Replace(suburl, item.Groups["part"].Value), item.Groups["content"].Value); } } //用户选择任务 var ba = new Collection<string>(); if (!disableDialog) ba = ToolForm.CreateMultiSelectForm(dict, Info.AutoAnswer, "bilibili"); //根据用户选择新建任务 foreach (string u in ba) { //新建任务 delegates.NewTask(new ParaNewTask(Info.BasePlugin, u, this.Info)); } } } } Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //重新设置保存目录(生成子文件夹) if (!Info.SaveDirectory.ToString().EndsWith(title)) { string newdir = Path.Combine(Info.SaveDirectory.ToString(), title); if (!Directory.Exists(newdir)) Directory.CreateDirectory(newdir); Info.SaveDirectory = new DirectoryInfo(newdir); } //清空地址 Info.FilePath.Clear(); Info.SubFilePath.Clear(); //视频id string id = ""; //分析id和视频存放站点(type) //取得"bofqi块的源代码 Regex rEmbed = new Regex("<div class=\"scontent\" id=\"bofqi\">(?<content>.*?)</div>", RegexOptions.Singleline); Match mEmbed = rEmbed.Match(src); string embedSrc = mEmbed.Groups["content"].Value.Replace("type=\"application/x-shockwave-flash\"", ""); //检查"file"参数 Regex rFile = new Regex("file=(\"|)(?<file>.+?)(\"|&)"); Match mFile = rFile.Match(embedSrc); //取得Flash地址 Regex rFlash = new Regex("src=\"(?<flash>.*?\\.swf)\""); Match mFlash = rFlash.Match(embedSrc); //取得id值 Regex rId = new Regex(@"(?<idname>(\w{0,2}id|data))=(?<id>([\w\-]+|$http://.+?$))".Replace("$", "\"")); Match mId = rId.Match(embedSrc); //取得ID id = mId.Groups["id"].Value; //取得type值 type = mId.Groups["idname"].Value; //解析器的解析结果 ParseResult pr = null; //如果不是“仅下载字幕” if (Info.DownSub != DownloadSubtitleType.DownloadSubtitleOnly) { if (mFile.Success) //如果有file参数 { string fileurl = mFile.Groups["file"].Value; videos = new string[] { fileurl }; } else if (mId.Success)//如果是普通的外链 { //检查外链 switch (type) { case "qid": //QQ视频 //解析视频 QQVideoParser parserQQ = new QQVideoParser(); pr = parserQQ.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "ykid": //优酷视频 //解析视频 YoukuParser parserYouKu = new YoukuParser(); pr = parserYouKu.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "uid": //土豆视频 //解析视频 TudouParser parserTudou = new TudouParser(); pr = parserTudou.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; case "data": //Flash游戏 id = id.Replace("\"", ""); videos = new string[] { id }; break; default: //新浪视频 SinaVideoParser parserSina = new SinaVideoParser(); pr = parserSina.Parse(new ParseRequest() { Id = id, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); break; } } else //如果是游戏 { string flashurl = mFlash.Groups["flash"].Value; videos = new string[] { flashurl }; } Info.videos = videos; return true; //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(videos[i]))) ext = ".flv"; else ext = Path.GetExtension(videos[i]); } if (ext == ".hlv") ext = ".flv"; //设置当前DownloadParameter if (Info.PartCount == 1) { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; } else { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + "(" + (i + 1).ToString() + ")" + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; } //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return false; } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for }//end 判断是否下载视频 //下载弹幕 bool comment = DownloadComment(title, id); //生成AcPlay文件 string acplay = GenerateAcplayConfig(pr, title); if (!comment) { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } //支持导出列表 StringBuilder sb = new StringBuilder(videos.Length * 2); foreach (string item in videos) { sb.Append(item); sb.Append("|"); } if (Info.Settings.ContainsKey("ExportUrl")) Info.Settings["ExportUrl"] = sb.ToString(); else Info.Settings.Add("ExportUrl", sb.ToString()); //支持AcPlay if (Info.Settings.ContainsKey("AcPlay")) Info.Settings["AcPlay"] = acplay; else Info.Settings.Add("AcPlay", acplay); } catch (Exception ex) { Info.Settings["user"] = ""; Info.Settings["password"] = ""; throw ex; } return true; }