public ParseResult Parse(ParseRequest request) { var httpRequest = (HttpWebRequest)WebRequest.Create(@"http://jiexi.acfun.info/index.php?type=mobileclient&vid=" + request.Id); httpRequest.Proxy = request.Proxy; httpRequest.UserAgent = "Dalvik/1.6.0 (Linux; U; Android 4.2.2; H30-U10 Build/HuaweiH30-U10)"; httpRequest.Accept = "application/json"; httpRequest.Headers.Add("Accept-Encoding", "gzip"); var json = Network.GetHtmlSource(httpRequest, Encoding.UTF8); var acInfo = JsonConvert.DeserializeObject <AcInfo>(json); if (acInfo.code != 200) { throw new Exception("AcfunInterfaceParser: " + acInfo.message); } var pr = new ParseResult(); var qualityDict = new Dictionary <string, string>(); AddQualityDict(qualityDict, acInfo.result); string chosenQuality = ToolForm.CreateSingleSelectForm("请选择视频清晰度:", qualityDict, "", request.AutoAnswers, "acfun"); var videoInfo = GetVideoInfoFromQuality(acInfo, chosenQuality); //视频总长度 pr.SpecificResult.Add("totallength", videoInfo.totalseconds.ToString()); //Framecount pr.SpecificResult.Add("framecount", "0"); //src pr.SpecificResult.Add("src", "200"); //vstr pr.SpecificResult.Add("vstr", ""); videoInfo.files.ForEach(file => { pr.Items.Add(new ParseResultItem { RealAddress = file.url, Information = new SerializableDictionary <string, string>() { { "length", (file.seconds * 1000).ToString() }, { "order", file.no.ToString() } } }); }); return(pr); }
/// <summary> /// 解析优酷视频源文件地址 /// </summary> ///<remarks>自动应答会检查前缀为<i>youku</i>的所有设置</remarks> public ParseResult Parse(ParseRequest request) { ParseResult pr = new ParseResult(); string urlpre = @"http://v.youku.com/player/getPlayList/VideoIDS/%ID%/timezone/+08/version/5/source/video?n=3&ran=4656&password=%PW%"; string url = urlpre.Replace(@"%ID%", request.Id).Replace(@"%PW%", request.Password); string xmldoc = Network.GetHtmlSource(url, Encoding.UTF8, request.Proxy); //选择语言 Regex rLang = new Regex(@"(?<=""audiolang"":\[).+?(?=\])"); Match mLang = rLang.Match(xmldoc); if (mLang.Success) //如果存在多种语言 { string langs = mLang.Value; Regex rLanguage = new Regex(@"""lang"":""(?<lang>.+?)"",""vid"":""(?<vid>.+?)"""); MatchCollection mcLanguages = rLanguage.Matches(langs); Dictionary <string, string> langDict = new Dictionary <string, string>(); foreach (Match mLanguage in mcLanguages) { langDict.Add(mLanguage.Groups["vid"].Value, Tools.ReplaceUnicode2Str(mLanguage.Groups["lang"].Value)); } string chosenId = ToolForm.CreateSingleSelectForm("您正在下载的视频有多种语言版本,请选择语言:", langDict, "", request.AutoAnswers, "youku"); request.Id = chosenId; url = urlpre.Replace(@"%ID%", request.Id).Replace(@"%PW%", request.Password); xmldoc = Network.GetHtmlSource(url, Encoding.UTF8, request.Proxy); } //正则表达式提取各个参数 string regexstring = "\"seed\":(?<seed>\\w+),.+\"key1\":\"(?<key1>\\w+)\",\"key2\":\"(?<key2>\\w+)\".+\"streamfileids\":{\"(?<fileposfix>\\w+)\":\"(?<fileID>[0-9\\*]+)"; Regex r = new Regex(regexstring); Match m = r.Match(xmldoc); //提取参数 double seed = Double.Parse(m.Groups["seed"].Value); string key1 = m.Groups["key1"].Value; string key2 = m.Groups["key2"].Value; //提取各视频参数 Regex rStreamFileIds = new Regex(@"""streamfileids"":{(?<fileids>.+?)}"); Match mStreamFileIds = rStreamFileIds.Match(xmldoc); string fileIds = mStreamFileIds.Groups["fileids"].Value; var dict = new Dictionary <string, string>(); string defaultres = ""; //是否有超清模式 if (fileIds.Contains("hd2")) { dict.Add("hd2", "超清(hd2)"); defaultres = "hd2"; } //是否有高清模式 if (fileIds.Contains("mp4")) { dict.Add("mp4", "高清(mp4)"); defaultres = "mp4"; } //是否有普通清晰度 if (fileIds.Contains("flv")) { dict.Add("flv", "标清(flv)"); defaultres = "flv"; } string fileposfix = null; string strSelect = null; //自动应答 if (request.AutoAnswers != null && request.AutoAnswers.Count > 0) { foreach (var item in request.AutoAnswers) { if (item.Prefix == "youku") { if (fileIds.Contains(item.Identify)) { strSelect = item.Identify; fileposfix = item.Identify; break; } } } } if (string.IsNullOrEmpty(fileposfix)) { //如果多余一种清晰度 if (dict.Count > 1) { fileposfix = ToolForm.CreateSingleSelectForm("您正在下载优酷视频,请选择视频清晰度:", dict, defaultres, request.AutoAnswers, "youku"); } else { fileposfix = defaultres; } strSelect = fileposfix; } //修正高清 if (fileposfix == "hd2") { fileposfix = "flv"; } //取得FileID Regex rFileID = new Regex(@"""" + strSelect + @""":""(?<fileid>.+?)"""); Match mFileID = rFileID.Match(fileIds); string fileID = mFileID.Groups["fileid"].Value; //提取视频个数 int flv_no = 0; string regexFlvNo = @"""segs"":{""\w+"":\[(?<content>.+?)\]"; Regex rn = new Regex(regexFlvNo); Match mn = rn.Match(xmldoc); char[] tmp_content = mn.Groups["content"].Value.ToCharArray(); foreach (char item in tmp_content) { if (item == '{') { flv_no++; } } //提取key Regex rSegs = new Regex(@"segs"":{(?<segs>.+?)},""streamsizes"); Match mSegs = rSegs.Match(xmldoc); string segs = mSegs.Groups["segs"].Value; Regex rSegsSub = new Regex(@"""" + strSelect + @""":\[(?<segssub>.+?)\]"); Match mSegsSub = rSegsSub.Match(segs); string segssub = mSegsSub.Groups["segssub"].Value; string regexKey = @"""k"":""(?<k>\w+)"",""k2"":""(?<k2>\w+)"""; MatchCollection mcKey = Regex.Matches(segssub, regexKey); List <string> keys = new List <string>(); foreach (Match mKey in mcKey) { keys.Add("?K=" + mKey.Groups["k"].Value + ",k2:" + mKey.Groups["k2"].Value); } //生成sid string sid = genSid(); //生成fileid string fileid = getFileID(fileID, seed); //生成key //string key = genKey(key1, key2); //添加各个地址 List <string> lst = new List <string>(); for (int i = 0; i < keys.Count; i++) { //得到地址 string u = "http://f.youku.com/player/getFlvPath/sid/" + sid + "_" + string.Format("{0:D2}", i) + //"/st/" + fileposfix + "/fileid/" + fileid.Substring(0, 8) + string.Format("{0:D2}", i) "/st/" + fileposfix + "/fileid/" + fileid.Substring(0, 8) + string.Format("{0:X2}", i) + fileid.Substring(10) + keys[i]; //添加地址 pr.Items.Add(new ParseResultItem(u)); } //提取各项详细信息 MatchCollection mcSegs = Regex.Matches(segssub, @"{.+?}"); for (int i = 0; i < mcSegs.Count; i++) { MatchCollection mcKeys = Regex.Matches(mcSegs[i].Value, @"""(?<key>\w+)"":""(?<value>\w+)"""); foreach (Match mkey in mcKeys) { string k = mkey.Groups["key"].Value; string v = mkey.Groups["value"].Value; //修正length和order if (k.Equals("seconds")) { k = "length"; v = (Int32.Parse(v) * 1000).ToString(); } if (k.Equals("no")) { k = "order"; } pr.Items[i].Information.Add(k, v); } } return(pr); }
/// <summary> /// 解析土豆视频 /// </summary> /// <remarks>接受的AutoAnswer对象需要以<i>tudou</i>作为前缀</remarks> public ParseResult Parse(ParseRequest request) { ParseResult pr = new ParseResult(); int t; if (!int.TryParse(request.Id, out t)) //测试iid是否是真实的(应该为数字) { //取得土豆网页面源代码 string tudousource = Network.GetHtmlSource("http://www.tudou.com/programs/view/" + request.Id + "/", Encoding.GetEncoding("GB2312"), request.Proxy); //取得iid Regex r1 = new Regex(@"(I|i)id = (?<iid>\d.*)"); Match m1 = r1.Match(tudousource); request.Id = m1.Groups["iid"].ToString(); } string xmlurl = @"http://v2.tudou.com/v?st=1%2C2%2C3%2C4%2C99&it=" + request.Id + "&pw=" + request.Password; string xmldoc = Network.GetHtmlSource(xmlurl, Encoding.UTF8, request.Proxy); Regex rVideo = new Regex("<f [^>]+brt=\"(?<brt>\\d+)\">(?<url>[^<]+)</f>"); MatchCollection mcVideo = rVideo.Matches(xmldoc); //默认url string defaultUrl = ""; //将 数字-清晰度 存入到字典中 var resolutiondict = new Dictionary <string, string>(); resolutiondict.Add("1", "流畅 256P"); resolutiondict.Add("2", "清晰 360P"); resolutiondict.Add("3", "高清 720P"); //resolutiondict.Add("4", "高清 1080P"); resolutiondict.Add("99", "原画"); //将 清晰度-地址 存入到字典中 var videodict = new Dictionary <string, string>(); foreach (Match item in mcVideo) { string brt = item.Groups["brt"].Value; string url = item.Groups["url"].Value; if (string.IsNullOrEmpty(defaultUrl)) { defaultUrl = url; } if (resolutiondict.ContainsKey(brt)) { brt = resolutiondict[brt]; } if (!videodict.ContainsValue(brt)) //不覆盖已有的 清晰度-地址 对 { videodict.Add(url, brt); } } //自动应答 if (request.AutoAnswers.Count > 0) { string answer; foreach (var item in request.AutoAnswers) { if (item.Prefix == "tudou") { if (resolutiondict.ContainsKey(item.Identify)) //如果自动应答设置中有"1"/"2"/"3"/"99" { answer = resolutiondict[item.Identify]; //取得描述(如"流畅 256P") foreach (var u in videodict.Keys) //从字典中查找描述信息所属的URL { if (videodict[u].Equals(answer)) { pr.Items.Add(new ParseResultItem(new Uri(u))); return(pr); } } } } } } string urladdress; //只在视频清晰度数量多余1个时进行选择 if (videodict.Count > 1) { urladdress = ToolForm.CreateSingleSelectForm("请选择视频清晰度:", videodict, defaultUrl, request.AutoAnswers, "tudou"); //DEBUG //全都加到结果集里 /*foreach (var item in videodict) * { * pr.Items.Add(new ParseResultItem(new Uri(item.Key))); * }*/ } else //如果只有一个清晰度,不进行选择 { urladdress = defaultUrl; //DEBUG //pr.Items.Add(new ParseResultItem(new Uri(urladdress))); } pr.Items.Add(new ParseResultItem(new Uri(urladdress))); return(pr); }
/// <summary> /// 解析土豆视频 /// </summary> /// <remarks>接受的AutoAnswer对象需要以<i>tudou</i>作为前缀</remarks> public ParseResult Parse(ParseRequest request) { ParseResult pr = new ParseResult(); int t; if (!int.TryParse(request.Id, out t)) //测试iid是否是真实的(应该为数字) { //取得土豆网页面源代码 string tudousource = Network.GetHtmlSource("http://www.tudou.com/programs/view/" + request.Id + "/", Encoding.GetEncoding("GB2312"), request.Proxy); //取得iid列表 Regex rIid = new Regex(@"(?<=iid(:| = ))\d+", RegexOptions.Singleline); MatchCollection mIids = rIid.Matches(tudousource); List <string> iids = new List <string>(); foreach (Match mIid in mIids) { iids.Add(mIid.Value); } //取得icode列表 Regex rIcode = new Regex(@"(?<=icode(:| = )(""|'))[\w\-]+", RegexOptions.Singleline); MatchCollection mIcodes = rIcode.Matches(tudousource); List <string> icodes = new List <string>(); foreach (Match mIcode in mIcodes) { icodes.Add(mIcode.Value); } //取得标题列表 Regex rKw = new Regex(@"(?<=kw(:| = )(""|')).+?(?=(""|'))", RegexOptions.Singleline); MatchCollection mKws = rKw.Matches(tudousource); List <string> kws = new List <string>(); foreach (Match mKw in mKws) { kws.Add(mKw.Value); } //检查需要的iid for (int i = 0; i < icodes.Count; i++) { if (request.Id.Equals(icodes[i])) { request.Id = iids[i]; pr.SpecificResult["icode"] = icodes[i]; pr.SpecificResult["title"] = kws[i]; break; } } } pr.SpecificResult["iid"] = request.Id; string xmlurl = @"http://v2.tudou.com/v?st=1%2C2%2C3%2C4%2C99&it=" + request.Id + "&pw=" + request.Password; string xmldoc = Network.GetHtmlSource(xmlurl, Encoding.UTF8, request.Proxy); Regex rVideo = new Regex("<f [^>]+brt=\"(?<brt>\\d+)\">(?<url>[^<]+)</f>"); MatchCollection mcVideo = rVideo.Matches(xmldoc); //默认url string defaultUrl = ""; //将 数字-清晰度 存入到字典中 var resolutiondict = new Dictionary <string, string>(); resolutiondict.Add("1", "流畅 256P"); resolutiondict.Add("2", "清晰 360P"); resolutiondict.Add("3", "高清 720P"); resolutiondict.Add("99", "原画"); //将 清晰度-地址 存入到字典中 var videodict = new Dictionary <string, string>(); foreach (Match item in mcVideo) { string brt = item.Groups["brt"].Value; string url = item.Groups["url"].Value; if (string.IsNullOrEmpty(defaultUrl)) { defaultUrl = url; } if (resolutiondict.ContainsKey(brt)) { brt = resolutiondict[brt]; } if (!videodict.ContainsValue(brt)) //不覆盖已有的 清晰度-地址 对 { videodict.Add(url, brt); } } //自动应答 if (request.AutoAnswers.Count > 0) { string answer; foreach (var item in request.AutoAnswers) { if (item.Prefix == "tudou") { if (resolutiondict.ContainsKey(item.Identify)) //如果自动应答设置中有"1"/"2"/"3"/"99" { answer = resolutiondict[item.Identify]; //取得描述(如"流畅 256P") foreach (var u in videodict.Keys) //从字典中查找描述信息所属的URL { if (videodict[u].Equals(answer)) { pr.Items.Add(new ParseResultItem(u)); return(pr); } } } } } } string urladdress; //只在视频清晰度数量多余1个时进行选择 if (videodict.Count > 1) { urladdress = ToolForm.CreateSingleSelectForm("请选择视频清晰度:", videodict, defaultUrl, request.AutoAnswers, "tudou"); } else //如果只有一个清晰度,不进行选择 { urladdress = defaultUrl; } pr.Items.Add(new ParseResultItem(urladdress)); return(pr); }
//下载视频 public override bool Download() { //开始下载 TipText("正在分析视频地址"); //原始Url Info.Url = Info.Url.TrimStart('+'); //修正url string url = "http://www.flvcd.com/parse.php?kw=" + Tools.UrlEncode(Info.Url); try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.GetEncoding("GB2312"), Info.Proxy); //检查是否需要密码 if (src.Contains("请输入密码")) { TipText("等待输入密码"); string pw = ToolForm.CreatePasswordForm(true, "", ""); url = url + "&passwd=" + pw; src = Network.GetHtmlSource(url, Encoding.GetEncoding("GB2312"), Info.Proxy); } //获得所有清晰度 //获取需要的源代码部分 TipText("解析所有清晰度"); Regex rMulti = new Regex(@"用硕鼠下载.*?赞助商链接", RegexOptions.Singleline); Match mMulti = rMulti.Match(src); string allResSrc = mMulti.Value; //获取url和名称 Regex rGetAllRes = new Regex(@"<a href=""(?<url>.+?)"".+?<B>(?<mode>.+?)</B>"); MatchCollection mGetAllRes = rGetAllRes.Matches(allResSrc); if (mGetAllRes.Count >= 1) { //将url和名称填入字典中 var dict = new Dictionary <string, string>(); dict.Add(url, "默认清晰度"); foreach (Match item in mGetAllRes) { dict.Add("http://www.flvcd.com/" + item.Groups["url"].Value, item.Groups["mode"].Value); } //用户选择清晰度 url = ToolForm.CreateSingleSelectForm("在线解析引擎可以解析此视频的多种清晰度模式,\n请选择您需要的视频清晰度:", dict, url, Info.AutoAnswer, "flvcd"); //重新获取网页源文件 src = Network.GetHtmlSource(url, Encoding.GetEncoding("GB2312"), Info.Proxy); } //取得视频标题 TipText("正在解析视频"); Regex rTitle = new Regex(@"<input type=$hidden$ name=$name$ value=$(?<title>.+?)$>".Replace("$", "\"")); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value; Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //取得内容 var urlMatch = Regex.Match(src, @"<input type=#hidden# name=#inf# value=#(?<urls>.+?)#".Replace('#', '"')); if (!urlMatch.Success) { throw new Exception("FLVCD插件暂时不支持此URL的解析" + Environment.NewLine + Info.Url); } string content = urlMatch.Groups["urls"].Value; List <string> partUrls = new List <string>(content.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)); //重新设置保存目录(生成子文件夹) 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.PartCount = partUrls.Count; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(partUrls[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(partUrls[i]))) { ext = ".flv"; } else { ext = Path.GetExtension(partUrls[i]); } } //设置当前DownloadParameter currentParameter = new DownloadParameter() { //文件名 FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + "-" + string.Format("{0:00}", i) + ext), //文件URL Url = partUrls[i], //代理服务器 Proxy = Info.Proxy }; //添加文件路径到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; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } } //end for } catch (Exception ex) { throw; } // end try //下载成功完成 return(true); }
/// <summary> /// 下载并更换当前壁纸 /// </summary> public override bool Download() { TipText("正在选择区域"); var now = DateTime.Now; //修正URL if (Info.Url.Equals("bing", StringComparison.CurrentCultureIgnoreCase)) { Info.Url = "bing" + now.Year.ToString() + now.Month.ToString("D2") + now.Day.ToString("D2"); } else { var m = Regex.Match(Info.Url, @"(?<y>\d{4})(?<m>\d{2})(?<d>\d{2})"); now = new DateTime(int.Parse(m.Groups["y"].Value), int.Parse(m.Groups["m"].Value), int.Parse(m.Groups["d"].Value)); } //mkt代码-国家 字典 var dictMarketRegion = new SerializableDictionary <string, string>(); //mkt代码-图片URL 字典 var dictMarketPic = new SerializableDictionary <string, string>(); //mkt代码-图片本地位置 字典 var dictMarketFile = new Dictionary <string, string>(); //获取所有区域的背景图片地址 //如果之前没有缓存 if (!Settings.ContainsKey("dictMarketRegion") || !Settings.ContainsKey("dictMarketPic")) { var worldwidesrc = Network.GetHtmlSource("http://www.bing.com/account/worldwide", Encoding.UTF8, Info.Proxy); var mcMarkets = Regex.Matches(worldwidesrc, @"scope=web&setmkt=(?<mkt>.+?)&.+?>(?<region>.+?)</a>"); foreach (Match mMarket in mcMarkets) { dictMarketRegion.Add(mMarket.Groups["mkt"].Value, mMarket.Groups["region"].Value); } //获取每个区域的背景图 foreach (string key in dictMarketRegion.Keys) { TipText("正在获取图片地址: " + dictMarketRegion[key]); var marketsrc = Network.GetHtmlSource("http://www.bing.com/?scope=web&setmkt=" + key, Encoding.UTF8); //获取背景图真实地址 var image = "http://www.bing.com" + Regex.Match(marketsrc, @"(?<=g_img={url:').+?(?=')").Value; //添加到字典 dictMarketPic.Add(key, image); } //序列化 Settings["dictMarketRegion"] = SerializableDictionary <string, string> .WriteToString(dictMarketRegion); Settings["dictMarketPic"] = SerializableDictionary <string, string> .WriteToString(dictMarketPic); } else { //反序列化 dictMarketRegion = SerializableDictionary <string, string> .LoadFromString(Settings["dictMarketRegion"]); dictMarketPic = SerializableDictionary <string, string> .LoadFromString(Settings["dictMarketPic"]); } //设置任务标题 Info.Title = string.Format("Bing每日壁纸: {0}年{1}月{2}日", now.Year, now.Month.ToString("D2"), now.Day.ToString("D2")); //下载所有图片 int i = 1; Info.FilePath.Clear(); foreach (string key in dictMarketPic.Keys) { //新分段 NewPart(i++, dictMarketPic.Count); //设置文件名 如 C:\Bing-20120123\china.jpg var ext = Path.GetExtension(dictMarketPic[key]); if (ext != ".png" || ext != ".jpg") { ext = ".jpg"; } var filename = "Bing" + "-" + now.Year.ToString() + now.Month.ToString("D2") + now.Day.ToString("D2") + @"\" + dictMarketRegion[key] + ext; filename = Path.Combine(Info.SaveDirectory.ToString(), filename); Info.FilePath.Add(filename); dictMarketFile.Add(key, filename); //设置下载参数 p.FilePath = filename; p.Url = dictMarketPic[key]; p.Proxy = Info.Proxy; //下载图片 DownloadFile(); } //设置壁纸 if (!Tools.IsRunningOnMono) { //选择地区 var regionMkt = ToolForm.CreateSingleSelectForm("请选择需要设为壁纸的图片:", dictMarketRegion, "zh-CN", null, "bing"); var file = dictMarketFile[regionMkt]; SystemParametersInfo(20, 0, file, 0x01 | 0x02); } return(true); }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析漫画地址")); if (currentParameter != null) { //将停止flag设置为true currentParameter.IsStop = false; } try { //取得Url源文件 string src = Network.GetHtmlSource(Info.Url, Encoding.GetEncoding("GB2312"), Info.Proxy); //要下载的Url列表 var subUrls = new Collection <string>(); //分析漫画id和lid Regex r = new Regex(@"http://(www\.|)imanhua\.com/comic/(?<id>\d+)(/list_(?<lid>\d+)\.html|)"); Match m = r.Match(Info.Url); string id = m.Groups["id"].Value; string lid = m.Groups["lid"].Value; #region 确定是整部漫画还是单独一话 //lid为空 则为整部漫画 if (string.IsNullOrEmpty(lid)) { //取得所有漫画的列表 Regex rAllComics = new Regex(@"<a href=$(?<suburl>/comic/\d+/list_\d+.html)$ title=$(?<title>.*?)$".Replace("$", "\"")); MatchCollection mcAllComics = rAllComics.Matches(src); //填充字典 var dict = new Dictionary <string, string>(); foreach (Match item in mcAllComics) { dict.Add("http://www.imanhua.com" + item.Groups["suburl"].Value, item.Groups["title"].Value); } //选择下载哪部漫画 //提取用户上次选择的章节 如果配置中有Chosen项 if (Info.Settings.ContainsKey("Chosen") && !string.IsNullOrEmpty(Info.Settings["Chosen"])) { foreach (var u in Info.Settings["Chosen"].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)) { subUrls.Add(u); } } else { subUrls = ToolForm.CreateMultiSelectForm(dict, Info.AutoAnswer, "imanhua"); } //如果用户没有选择任何章节 if (subUrls.Count == 0) { return(false); } //取得漫画标题 Regex rTitle = new Regex(@"\<h1\>(?<title>.*)\<\/h1\>"); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value; //过滤标题中的非法字符 title = Tools.InvalidCharacterFilter(title, ""); Info.Title = title; } else //如果不是整部漫画则添加此单话url { subUrls.Add(Info.Url); //取得漫画标题 //取得上级页面的url Regex rGetParent = new Regex(@"http://www\.imanhua\.com/comic/\d+/"); Match mGetParent = rGetParent.Match(Info.Url); string parentUrl = mGetParent.ToString(); //取得源代码并分析 string pSrc = Network.GetHtmlSource(parentUrl, Encoding.GetEncoding("GB2312"), Info.Proxy); //取得漫画标题 Regex rTitle = new Regex(@"\<h1\>(?<title>.*)\<\/h1\>"); Match mTitle = rTitle.Match(pSrc); string title = mTitle.Groups["title"].Value; //过滤标题中的非法字符 title = Tools.InvalidCharacterFilter(title, ""); Info.Title = title; } //end if #endregion //将用户选择的漫画章节存入配置 var sbChosen = new StringBuilder(); foreach (var suburl in subUrls) { sbChosen.Append(suburl + "|"); } Info.Settings["Chosen"] = sbChosen.ToString(); #region 择服务器 //取得服务器配置文件 string serverjs = Network.GetHtmlSource(@"http://www.imanhua.com/v2/config/config.js", Encoding.GetEncoding("GB2312"), Info.Proxy); Regex rServer = new Regex(@"arrHost\[\d+\][ =""'\[]+(?<server>.+?)[""', ]+(?<ip>.+?)[""']\]"); MatchCollection mServers = rServer.Matches(serverjs); //添加到数组中 Dictionary <string, string> servers = new Dictionary <string, string>(); foreach (Match item in mServers) { if (!servers.ContainsKey(item.Groups["ip"].Value)) { servers.Add(item.Groups["ip"].Value, item.Groups["server"].Value); } } //选择服务器 string serverName = ToolForm.CreateSingleSelectForm("", servers, "", Info.AutoAnswer, "imanhua"); #endregion #region 载漫画 //建立文件夹 string mainDir = Info.SaveDirectory + (Info.SaveDirectory.ToString().EndsWith(@"\") ? "" : @"\") + Info.Title; //确定漫画共有几个段落 Info.PartCount = subUrls.Count; int i = 0; //分段落下载 foreach (string surl in subUrls) { Info.CurrentPart = i + 1; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //分析漫画id和lid Regex rSubUrl = new Regex(@"http://(www\.|)imanhua\.com/comic/(?<bid>\d+)(/list_(?<cid>\d+)\.html|)"); Match mSubUrl = rSubUrl.Match(surl); string bookId = mSubUrl.Groups["bid"].Value; string chapterId = mSubUrl.Groups["cid"].Value; //地址数组 List <string> fileUrls = new List <string>(); //分析源代码,取得下载地址 WebClient wc = new WebClient(); //if (Info.Proxy != null) wc.Proxy = Info.Proxy; //取得源代码 byte[] buff = wc.DownloadData(surl); string cookie = wc.ResponseHeaders.Get("Set-Cookie"); string source = Encoding.GetEncoding("GB2312").GetString(buff); //取得标题 //Regex rTitle = new Regex(@"<span id=""position"">.+?>> <a href="".+?"">(?<title>.+?)</a> >> <a href="".+?"">(?<subtitle>.+?)</a></span>"); //Match mTitle = rTitle.Match(source); //string subTitle = mTitle.Groups["subtitle"].Value; string subTitle = Regex.Match(source, @"(?<=<h2>).+?(?=</h2>)").Value; //过滤子标题中的非法字符 subTitle = Tools.InvalidCharacterFilter(subTitle, ""); //合并本地路径(文件夹) string subDir = mainDir + @"\" + subTitle; //创建文件夹 Directory.CreateDirectory(subDir); ////检查是否是老版本 //if (int.Parse(chapterId) > 7910) //7910之后为新版本 //{ //如果使用动态生成 if (source.Contains(@"var cInfo={")) { //获取所有文件名 Regex rFileName = new Regex(@"(?<="")[^,]+(?="")"); MatchCollection mcFileNames = rFileName.Matches(Regex.Match(source, @"(?<=""files"":\[).+?(?=\])").Value); foreach (Match file in mcFileNames) { if (file.Value.StartsWith("/")) { fileUrls.Add(serverName + file.Value); } else { fileUrls.Add(serverName + "/Files/Images/" + bookId + "/" + chapterId + "/" + file.Value); } } } else { //获取所有文件名 //获取页面HTML中的js段 Regex rJsFiles = new Regex(@"(?<=var pic=\[).+?(?=\])"); string jsFiles = rJsFiles.Match(source).Value; //获取所有图片文件 Regex rFileName = new Regex(@"(?<="")[^,]+(?="")"); MatchCollection mcFileNames = rFileName.Matches(jsFiles); foreach (Match file in mcFileNames) { fileUrls.Add(serverName + (file.Value.StartsWith("/") ? file.Value : "/" + file.Value)); } } //输出真实地址 StringBuilder sb = new StringBuilder(fileUrls.Count); foreach (var file in fileUrls) { sb.Append(file + "|"); } Info.Settings["ExportUrl"] = sb.ToString(); sb = null; //设置下载长度 currentParameter.TotalLength = fileUrls.Count; //下载文件! for (int j = 0; j < fileUrls.Count; j++) { if (currentParameter.IsStop) { return(false); } try { wc.Headers.Add("Referer", subUrls[i]); wc.Headers.Add("Cookie", cookie); byte[] content = wc.DownloadData(fileUrls[j]); string fn = Path.GetFileName(fileUrls[j]); File.WriteAllBytes(Path.Combine(subDir, fn), content); } catch { } //end try currentParameter.DoneBytes = j; } // end for i++; } //end foreach } //end try catch (Exception ex) //出现错误即下载失败 { throw ex; } //end try #endregion //下载成功完成 currentParameter.DoneBytes = currentParameter.TotalLength; return(true); } //end DownloadVideo
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); //原始Url Info.Url = Info.Url.TrimStart('+'); //修正url string url = "http://www.flvcd.com/parse.php?kw=" + Tools.UrlEncode(Info.Url); try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.GetEncoding("GB2312"), Info.Proxy); //检查是否需要密码 if (src.Contains("请输入密码")) { string pw = ToolForm.CreatePasswordForm(true, "", ""); url = url + "&passwd=" + pw; src = Network.GetHtmlSource(url, Encoding.GetEncoding("GB2312"), Info.Proxy); } //获得所有清晰度 //获取需要的源代码部分 Regex rMulti = new Regex(@"用硕鼠下载.*?赞助商链接", RegexOptions.Singleline); Match mMulti = rMulti.Match(src); string allResSrc = mMulti.Value; //获取url和名称 Regex rGetAllRes = new Regex(@"<a href=""(?<url>.+?)"".+?<B>(?<mode>.+?)</B>"); MatchCollection mGetAllRes = rGetAllRes.Matches(allResSrc); if (mGetAllRes.Count > 1) { //将url和名称填入字典中 var dict = new Dictionary <string, string>(); dict.Add(url, "默认清晰度"); foreach (Match item in mGetAllRes) { dict.Add("http://www.flvcd.com/" + item.Groups["url"].Value, item.Groups["mode"].Value); } //用户选择清晰度 url = ToolForm.CreateSingleSelectForm("在线解析引擎可以解析此视频的多种清晰度模式,\n请选择您需要的视频清晰度:", dict, url, Info.AutoAnswer, "flvcd"); //重新获取网页源文件 src = Network.GetHtmlSource(url, Encoding.GetEncoding("GB2312"), Info.Proxy); } //取得视频标题 Regex rTitle = new Regex(@"<input type=$hidden$ name=$name$ value=$(?<title>.+?)$>".Replace("$", "\"")); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value; Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //取得内容 Regex rContent = new Regex("<input type=\"hidden\" name=\"inf\".+\">", RegexOptions.Singleline); Match mContent = rContent.Match(src); string content = mContent.Value; if (string.IsNullOrEmpty(content)) { throw new Exception("FLVCD插件暂时不支持此URL的解析\n" + Info.Url); } //重新设置保存目录(生成子文件夹) 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(); //取得各个Part名称 List <string> partNames = new List <string>(); Regex rPartNames = new Regex(@"<N>(?<name>.+)"); MatchCollection mcPartNames = rPartNames.Matches(content); foreach (Match item in mcPartNames) { string pn = Tools.InvalidCharacterFilter(item.Groups["name"].Value, ""); partNames.Add(pn); } //取得各Part下载地址 List <string> partUrls = new List <string>(); Regex rPartUrls = new Regex(@"<U>(?<url>.+)"); MatchCollection mcPartUrls = rPartUrls.Matches(content); foreach (Match item in mcPartUrls) { partUrls.Add(item.Groups["url"].Value.Replace("&", "&")); } Info.videos = partUrls.ToArray(); return(true); //下载视频 //确定视频共有几个段落 Info.PartCount = partUrls.Count; //------------分段落下载------------ for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 string ext = Tools.GetExtension(partUrls[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(partUrls[i]))) { ext = ".flv"; } else { ext = Path.GetExtension(partUrls[i]); } } //设置当前DownloadParameter currentParameter = new DownloadParameter() { //文件名 FilePath = Path.Combine(Info.SaveDirectory.ToString(), partNames[i] + ext), //文件URL Url = partUrls[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 } catch (Exception ex) { throw ex; } // end try //下载成功完成 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); }
/// <summary> /// 解析土豆视频 /// </summary> /// <remarks>接受的AutoAnswer对象需要以<i>tudou</i>作为前缀</remarks> public ParseResult Parse(ParseRequest request) { ParseResult pr = new ParseResult(); int t; if (!int.TryParse(request.Id, out t)) //测试iid是否是真实的(应该为数字) { //取得土豆网页面源代码 string tudousource = Network.GetHtmlSource("http://www.tudou.com/programs/view/" + request.Id + "/", Encoding.GetEncoding("GB2312"), request.Proxy); //取得iid列表 Regex rIid = new Regex(@"(?<=iid(:| = ))\d+", RegexOptions.Singleline); MatchCollection mIids = rIid.Matches(tudousource); List <string> iids = new List <string>(); foreach (Match mIid in mIids) { iids.Add(mIid.Value); } //取得icode列表 Regex rIcode = new Regex(@"(?<=icode(:| = )(""|'))[\w\-]+", RegexOptions.Singleline); MatchCollection mIcodes = rIcode.Matches(tudousource); List <string> icodes = new List <string>(); foreach (Match mIcode in mIcodes) { icodes.Add(mIcode.Value); } //取得标题列表 Regex rKw = new Regex(@"(?<=kw(:| = )(""|')).+?(?=(""|'))", RegexOptions.Singleline); MatchCollection mKws = rKw.Matches(tudousource); List <string> kws = new List <string>(); foreach (Match mKw in mKws) { kws.Add(mKw.Value); } //检查需要的iid for (int i = 0; i < icodes.Count; i++) { if (request.Id.Equals(icodes[i])) { request.Id = iids[i]; pr.SpecificResult["icode"] = icodes[i]; pr.SpecificResult["title"] = kws[i]; break; } } } pr.SpecificResult["iid"] = request.Id; //string xmlurl = @"http://v2.tudou.com/v?st=1%2C2%2C3%2C4%2C99&it=" + request.Id + "&pw=" + request.Password; string xmlurl = @"http://v2.tudou.com/f?sender=pepper&v=4.2.2&sj=1&id=" + request.Id + "&sid=10000&r=6226"; string xmldoc = Network.GetHtmlSource(xmlurl, Encoding.UTF8, request.Proxy); xmldoc = xmldoc.Replace("<a>", "").Replace("</a>", "").Replace("<b>", "").Replace("</b>", ""); if (xmldoc.StartsWith("<f")) { xmldoc = "<v>" + xmldoc + "</v>"; } //反序列化XML文档 TudouVideo tudou; var serializer = new XmlSerializer(typeof(TudouVideo)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xmldoc))) { tudou = (TudouVideo)serializer.Deserialize(ms); } //Regex rVideo = new Regex("<f [^>]+brt=\"(?<brt>\\d+)\">(?<url>[^<]+)</f>"); //MatchCollection mcVideo = rVideo.Matches(xmldoc); //默认url string defaultUrl = ""; //将 数字-清晰度 存入到字典中 var resolutiondict = new Dictionary <string, string>(); resolutiondict.Add("1", "流畅"); resolutiondict.Add("2", "清晰"); resolutiondict.Add("3", "高清"); resolutiondict.Add("4", "超清"); resolutiondict.Add("99", "原画"); //将 清晰度-地址 存入到字典中 var videodict = new Dictionary <string, string>(); //foreach (Match item in mcVideo) foreach (var info in tudou.videos) { string brt = info.brt ?? "1"; // item.Groups["brt"].Value; string url = info.address; // item.Groups["url"].Value; if (string.IsNullOrEmpty(defaultUrl)) { defaultUrl = url; } brt = resolutiondict[brt]; if (!videodict.ContainsValue(brt)) //不覆盖已有的 清晰度-地址 对 { videodict.Add(url, brt); } } //自动应答 if (request.AutoAnswers != null && request.AutoAnswers.Count > 0) { string answer; foreach (var item in request.AutoAnswers) { if (item.Prefix == "tudou") { if (resolutiondict.ContainsKey(item.Identify)) //如果自动应答设置中有"1"/"2"/"3"/"99" { answer = resolutiondict[item.Identify]; //取得描述(如"流畅 256P") foreach (var u in videodict.Keys) //从字典中查找描述信息所属的URL { if (videodict[u].Equals(answer)) { pr.Items.Add(new ParseResultItem(u)); return(pr); } } } } } } string urladdress; //只在视频清晰度数量多余1个时进行选择 if (videodict.Count > 1) { urladdress = ToolForm.CreateSingleSelectForm("请选择视频清晰度:", videodict, defaultUrl, request.AutoAnswers, "tudou"); } else //如果只有一个清晰度,不进行选择 { urladdress = defaultUrl; } pr.Items.Add(new ParseResultItem(urladdress)); pr.Items[0].Information.Add("order", "1"); //写入视频时长 pr.Items[0].Information.Add("length", tudou.time); pr.SpecificResult.Add("totallength", tudou.time); return(pr); }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); try { //取得网页源文件 string src = Network.GetHtmlSource(Info.Url, Encoding.UTF8, Info.Proxy); //去除乱码 src = src.Replace(@"\u0026", "&"); src = src.Replace("\\\"", "\""); for (int i = 0; i < 10; i++) { src = src.Replace("%25", "%"); } src = src.Replace("%3A", ":").Replace("%2F", "/") .Replace("%3F", "?").Replace("%2C", ",").Replace("%3D", "=") .Replace("%26", "&"); //取得视频标题 Regex rTitle = new Regex(@"<meta name=""title"" content=""(?<title>.+?)"">"); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value; Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); //取得Flash参数 Regex rFlashVars = new Regex(@"flashvars=""(?<content>.+?)"""); Match mFlashVars = rFlashVars.Match(src); string flashvars = mFlashVars.Groups["content"].Value; //取得清晰度列表 Regex rFmtList = new Regex(@"fmt_list=(?<fmt>.+?)&"); Match mFmtList = rFmtList.Match(flashvars); string fmtlist = mFmtList.Groups["fmt"].Value; Regex rFmts = new Regex(@"(?<fmtid>\d+)/(?<fmtres>\d+x\d+)/\d+/\d+/\d+"); MatchCollection mcFmts = rFmts.Matches(fmtlist); //分辨率列表 var resolutions = new List <string>(); //FMT列表 var fmtids = new List <string>(); //视频地址列表 var videoUrls = new List <string>(); foreach (Match mFmt in mcFmts) { string describe = ""; //添加到FMT列表 fmtids.Add(mFmt.Groups["fmtid"].Value); switch (mFmt.Groups["fmtid"].Value) { #region "FMT列表" case "0": case "5": case "6": describe = "FLV(H.263) MP3(64kbps)"; break; case "34": case "35": describe = "FLV(H.263) AAC(128kbps)"; break; case "13": case "17": describe = "3GP(mpeg4) AAC"; break; case "18": describe = "MPEG-4-AAC(H.264) AAC(128kbps)"; break; case "22": case "37": case "38": describe = "MPEG-4-AAC(H.264) AAC(152kbps)"; break; case "82": case "85": describe = "3D MPEG-4-AAC(H.264) AAC(152kbps)"; break; case "83": describe = "3D MPEG-4-AAC(H.264) AAC(96kbps)"; break; case "84": describe = "3D MPEG-4-AAC(H.264) AAC(128kbps)"; break; case "43": case "46": describe = "WebM(VP8) OGG(128kbps)"; break; case "44": case "45": describe = "WebM(VP8) OGG(192kbps)"; break; case "100": case "101": case "102": describe = "3D WebM(VP8) OGG(192kbps)"; break; default: describe = "未知格式"; break; #endregion } //添加到分辨率列表 resolutions.Add(mFmt.Groups["fmtres"].Value + " " + describe /*+ " [fmt=" + fmt.Groups["fmtid"].Value + "]" */); } //获取下载地址 int index1 = src.IndexOf("url_encoded_fmt_stream_map"); int index2 = src.IndexOf("<!-- begin watch-video-extra -->"); string urls = src.Substring(index1, index2 - index1); Regex rUrls = new Regex(@"url=(?<url>http://.+?)&quality="); MatchCollection mUrls = rUrls.Matches(urls); //添加到视频地址列表 foreach (Match item in mUrls) { videoUrls.Add(item.Groups["url"].Value); } //添加(FMT-清晰度)字典 var dict = new Dictionary <string, string>(); for (int i = 0; i < videoUrls.Count; i++) { dict.Add(fmtids[i], resolutions[i]); } //用户选择清晰度(获取一个FMT值) string chosenFmt; if (Info.Settings.ContainsKey("FMT")) { chosenFmt = Info.Settings["FMT"]; } else { chosenFmt = ToolForm.CreateSingleSelectForm("您正在下载YouTube视频,请选择视频清晰度:", dict, "", Info.AutoAnswer, "youtube"); Info.Settings["FMT"] = chosenFmt; } //设置真实地址 videos = new string[1]; videos[0] = videoUrls[fmtids.FindIndex(new Predicate <string>((s) => { if (chosenFmt.Equals(s)) { return(true); } else { return(false); } }))]; //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; //分段落下载 for (int i = 0; i < Info.PartCount; i++) { Info.CurrentPart = i + 1; //取得文件后缀名 //string ext = Tools.GetExtension(videos[i]); //设置当前DownloadParameter if (Info.PartCount == 1) //如果只有一段 { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ".flv"), //文件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() + ")" + ".flv"), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } //添加文件路径到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 + " 下载失败"; } } } } catch (Exception ex) //出现错误即下载失败 { throw ex; } //下载成功完成 return(true); }