public override bool Download() { string FlvBind_exe = "http://storage.live.com/items/4C4A61560B6A6DB5!6016"; string FlvLib_dll = "http://storage.live.com/items/4C4A61560B6A6DB5!6017"; string FFMpeg_exe = "http://storage.live.com/items/4C4A61560B6A6DB5!5795"; string FFMpeg_exe_1 = "http://download-codeplex.sec.s-msft.com/Download?ProjectName=acdown&DownloadId=579838"; string FFMpeg_exe_2 = "http://download-codeplex.sec.s-msft.com/Download?ProjectName=acdown&DownloadId=579839"; string Libfaac_dll = "http://storage.live.com/items/4C4A61560B6A6DB5!5794"; string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string folder = Path.Combine(appdata, "Kaedei" + Path.DirectorySeparatorChar + "FlvCombine" + Path.DirectorySeparatorChar); Info.Title = "AcDown视频合并插件"; NewPart(1, 4); TipText("正在下载Flv合并组件(1/2)"); p = new DownloadParameter() { Url = FlvBind_exe, FilePath = Path.Combine(folder, "FlvBind.exe"), Proxy = Info.Proxy }; if (!DownloadFile()) return false; NewPart(2, 4); TipText("正在下载Flv合并组件(2/2)"); p = new DownloadParameter() { Url = FlvLib_dll, FilePath = Path.Combine(folder, "FlvLib.dll"), Proxy = Info.Proxy }; if (!DownloadFile()) return false; NewPart(3, 4); TipText("正在下载高级视频合并组件(1/2)"); p = new DownloadParameter() { Url = FFMpeg_exe, FilePath = Path.Combine(folder, "ffmpeg.exe"), Proxy = Info.Proxy }; if (!DownloadFile()) return false; NewPart(4, 4); TipText("正在下载高级视频合并组件(2/2)"); p = new DownloadParameter() { Url = Libfaac_dll, FilePath = Path.Combine(folder, "libfaac.dll"), Proxy = Info.Proxy }; if (!DownloadFile()) return false; return true; }
public override bool Download() { TipText("开始分析"); Track[] tracks; string folder = ""; Match match; Dictionary<string, string> additionalFiles = new Dictionary<string, string>(); match = Regex.Match(Info.Url, XiamiPlugin.RegexPatternSong); if (match.Groups["var"].Success) { tracks = GetPlaylist(match.Groups["var"].Value, PlaylistType.Song); if (tracks.Length > 0) { Info.Title = tracks[0].Filename; } else return true; } else { match = Regex.Match(Info.Url, XiamiPlugin.RegexPatternArtist); if (match.Groups["var"].Success) { tracks = GetPlaylist(match.Groups["var"].Value, PlaylistType.Artist); if (tracks.Length > 0) { Info.Title = tracks[0].Artist; folder = Info.Title; } else return true; } else { match = Regex.Match(Info.Url, XiamiPlugin.RegexPatternAlbum); if (match.Groups["var"].Success) { tracks = GetPlaylist(match.Groups["var"].Value, PlaylistType.Album); if (tracks.Length > 0) { for (int i = 0; i < tracks.Length; i++) { tracks[i].Filename = String.Format("{0:D2} {1} - {2}", i + 1, tracks[i].Title, tracks[i].Artist); } Info.Title = tracks[0].Artist + " - " + tracks[0].Album; folder = Info.Title; } else return true; } else { match = Regex.Match(Info.Url, XiamiPlugin.RegexPatternCollect); if (match.Groups["var"].Success) { tracks = GetPlaylist(match.Groups["var"].Value, PlaylistType.Collect); if (tracks.Length == 0) return true; for (int i = 0; i < tracks.Length; i++) { tracks[i].Filename = String.Format("{0:D2} {1}", i + 1, tracks[i].Filename); } string source = Network.GetHtmlSource(@"http://www.xiami.com/song/showcollect/id/" + match.Groups["var"].Value, Encoding.UTF8, Info.Proxy); var title = Regex.Match(source, @"<title>(?<var>.*)</title>").Groups["var"]; Info.Title = (title != null && !String.IsNullOrEmpty(title.Value) ? title.Value : "未知精选集 (" + match.Groups["var"].Value + ")"); folder = Info.Title; var cover = Regex.Match(source, "<a class=\"bigImgCover\" rel=\"nofollow\" target=\"_blank\" href=\"(?<var>.*)\">").Groups["var"]; if (cover != null && !String.IsNullOrEmpty(cover.Value)) additionalFiles.Add ("精选集封面.jpg", cover.Value); var pics = Regex.Matches(source, "<a href=\"(?<var>.*)\" target=\"_blank\" rel=\"nofollow\" class=\"bigImg\">"); int count = 1; foreach (Match item in pics) { additionalFiles.Add (String.Format("精选集图片 ({0:D2}).jpg", count++), item.Groups["var"].Value); } } else { return false; } } } } if (tracks.Length > 1 && String.IsNullOrEmpty (folder)) folder = Info.Title; string localFolder = Info.SaveDirectory.FullName; if (!String.IsNullOrEmpty (folder)) { string newdir = Path.Combine(Info.SaveDirectory.ToString(), folder); if (!Directory.Exists(newdir)) Directory.CreateDirectory(newdir); localFolder = newdir; } if (additionalFiles.Count > 0) { foreach (KeyValuePair<string, string> item in additionalFiles) { p = new DownloadParameter(); p.Url = item.Value; p.FilePath = System.IO.Path.Combine(localFolder, Tools.InvalidCharacterFilter (item.Key, "_")); p.Proxy = Info.Proxy; try{ DownloadWithRescue(p); }catch{} } } int part = 1; foreach (Track track in tracks) { string filePath = System.IO.Path.Combine(localFolder, Tools.InvalidCharacterFilter (track.Filename, "_")); NewPart(part++, tracks.Length); if (!String.IsNullOrEmpty(track.LyricURL)) { p = new DownloadParameter(); p.Url = track.LyricURL; p.FilePath = filePath + ".lrc"; p.Proxy = Info.Proxy; if (!DownloadWithRescue(p)) return false; } if (!String.IsNullOrEmpty(track.PictureURL)) { p = new DownloadParameter(); p.Url = track.PictureURL; p.FilePath = filePath + ".jpg"; p.Proxy = Info.Proxy; if (!DownloadWithRescue(p)) return false; } if (!String.IsNullOrEmpty(track.SongURL)) { p = new DownloadParameter(); p.Url = track.SongURL; p.FilePath = filePath + ".mp3"; p.Proxy = Info.Proxy; if (!DownloadWithRescue(p)) return false; } } return true; }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); try { //获取密码 string password = ""; if (Info.Url.EndsWith("密码")) { password = ToolForm.CreatePasswordForm(true, "", ""); Info.Url.Replace("密码", ""); } //取得网页源文件 string src = Network.GetHtmlSource(Info.Url, Encoding.GetEncoding("GBK"), Info.Proxy); //分析视频iid string iid = ""; //取得iid Regex rlist = new Regex(@"(a|l)(?<aid>\d+)(i(?<iid>\d+)|)(?=\.html)"); Match mlist = rlist.Match(Info.Url); if (mlist.Success) //如果是列表中的视频 { //尝试取得url中的iid if (!string.IsNullOrEmpty(mlist.Groups["iid"].Value)) { iid = mlist.Groups["iid"].Value; } else //否则取得源文件中的iid { Regex r1 = new Regex(@"defaultIid = (?<iid>\d+)"); Match m1 = r1.Match(src); iid = m1.Groups["iid"].ToString(); } } else //如果是普通视频(或新列表视频) { //URL中获取id var mIdInUrl = Regex.Match(Info.Url, @"(listplay|albumplay)/(?<l>.+?)/(?<i>.+?)(?=\.html)"); if (mIdInUrl.Success) { iid = mIdInUrl.Groups["i"].Value; } else { //2012.08.26 - 08.27修改 albumplay进到这儿的等号两边是没空格的。。 var mIdInSrc = Regex.Match(src, @"(listData = |listData=)\[{\niid.+?icode:""(?<icode>[\w\-]+)""", RegexOptions.Singleline); if (mIdInSrc.Success) { iid = mIdInSrc.Groups["icode"].Value; } else { Regex r1 = new Regex(@"(I|i)id = (?<iid>\d+)"); Match m1 = r1.Match(src); iid = m1.Groups["iid"].ToString(); } } } //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); //调用内建的土豆视频解析器 TudouParser parserTudou = new TudouParser(); var pr = parserTudou.Parse(new ParseRequest() { Id = iid, Password = password, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); //取得视频标题 string title = ""; if (pr.SpecificResult.ContainsKey("title")) { title = pr.SpecificResult["title"]; } else { //if (mlist.Success) //{ // //取得aid/lid标题 // string aid = mlist.Groups["aid"].Value; // Regex rlisttitle = null; // Match mlisttitle = null; // if (mlist.ToString().StartsWith("a")) //如果是a开头的列表 // { // rlisttitle = new Regex(@"aid:" + aid + @"\n,name:""(?<title>.+?)""", RegexOptions.Singleline); // mlisttitle = rlisttitle.Match(src); // } // else if (mlist.ToString().StartsWith("l")) //如果是l开头的列表 // { // rlisttitle = new Regex(@"ltitle = ""(?<title>.+?)""", RegexOptions.Singleline); // mlisttitle = rlisttitle.Match(src); // } // //取得iid标题 // Regex rsubtitle = new Regex(@"iid:" + iid + @"\n(,cartoonType:\d+\n|),title:""(?<subtitle>.+?)""", RegexOptions.Singleline); // Match msubtitle = rsubtitle.Match(src); // title = mlisttitle.Groups["title"].Value + "-" + msubtitle.Groups["subtitle"].Value; //} //else //{ Regex rTitle = new Regex(@"\<h1\>(?<title>.*)\<\/h1\>"); Match mTitle = rTitle.Match(src); title = mTitle.Groups["title"].Value; //} } Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); 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 (ext == ".f4v") 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; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频文件 success = Network.DownloadFile(currentParameter, this.Info); //下载视频 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 + " 下载失败"; } } } //下载弹幕(dp) if ((Info.DownloadTypes & DownloadType.Subtitle) != 0) { try { Network.DownloadFile(new DownloadParameter() { FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ".json"), Url = "http://comment.dp.tudou.com/comment/get/" + pr.SpecificResult["iid"] + "/vdn12d/", Proxy = Info.Proxy }); } catch { } } } catch (Exception ex) //出现错误即下载失败 { throw ex; } //下载成功完成 return true; }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); try { //获取密码 string password = ""; if (Info.Url.EndsWith("密码")) password = ToolForm.CreatePasswordForm(true, "", ""); //取得网页源文件 string src = Network.GetHtmlSource(Info.Url.Replace("密码", ""), Encoding.UTF8, Info.Proxy); //分析视频id Regex r1 = new Regex(@"videoId = '(?<vid>\w+)'"); Match m1 = r1.Match(src); string vid = m1.Groups["vid"].ToString(); //取得视频标题 Regex rTitle = new Regex(@"<title>(?<title>.*)</title>"); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value.Replace(" - 在线观看", "").Replace(" - 视频", "").Replace(" - 优酷视频", ""); Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); //调用内建的优酷视频解析器 YoukuParser parserYouku = new YoukuParser(); videos = parserYouku.Parse(new ParseRequest() { Id = vid, Password = password, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); 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]); //设置当前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; }
//下载视频 public void Download() { //开始下载 delegates.Start(new ParaStart(this.TaskId)); delegates.TipText(new ParaTipText(this.TaskId, "正在分析视频地址")); _status = DownloadStatus.正在下载; try { //获取密码 string password = ""; if (Url.EndsWith("密码")) password = ToolForm.CreatePasswordForm(true, "", ""); //取得网页源文件 string src = Network.GetHtmlSource(Url.Replace("密码", ""), Encoding.UTF8, delegates.Proxy); //分析视频evid string evid = ""; //取得evid Regex r1 = new Regex(@"evid = '(?<evid>.+)'"); Match m1 = r1.Match(src); evid = m1.Groups["evid"].ToString(); //取得视频标题 Regex rTitle = new Regex(@"<h(1|2) class=$(vt|pvt)$>(?<title>.+?)<".Replace("$","\"")); Match mTitle = rTitle.Match(src); string title = mTitle.Groups["title"].Value; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); _title = title; //视频地址数组 string[] videos = null; //清空地址 _filePath.Clear(); //调用内建的土豆视频解析器 SixcnParser parserSixcn = new SixcnParser(); videos = parserSixcn.Parse(new string[] { evid, password }, delegates.Proxy); //下载视频 //确定视频共有几个段落 _partCount = videos.Length; //分段落下载 for (int i = 0; i < _partCount; i++) { _currentPart = i + 1; //提示更换新Part delegates.NewPart(new ParaNewPart(this.TaskId, i + 1)); //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); //设置当前DownloadParameter if (_partCount == 1) //如果只有一段 { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(SaveDirectory.ToString(), _title + "." + ext), //文件URL Url = videos[i] }; } else //如果分段有多段 { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(SaveDirectory.ToString(), _title + "(" + (i + 1).ToString() + ")" + "." + ext), //文件URL Url = videos[i] }; } //添加文件路径到List<>中 _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; } //下载视频文件 success = Network.DownloadFile(currentParameter); //未出现错误即用户手动停止 if (!success) { _status = DownloadStatus.已经停止; delegates.Finish(new ParaFinish(this.TaskId, false)); return; } } } catch (Exception ex) //出现错误即下载失败 { _status = DownloadStatus.出现错误; delegates.Error(new ParaError(this.TaskId, ex)); return; } //下载成功完成 _status = DownloadStatus.下载完成; delegates.Finish(new ParaFinish(this.TaskId, true)); }
/// <summary> /// 下载文件 /// </summary> /// <param name="para">传递的下载参数</param> /// <returns>一个布尔值,指示指定的下载是否已成功完成</returns> public static bool DownloadFile(DownloadParameter para) { return(DownloadFile(para, null)); }
/// <summary> /// 下载文件 /// </summary> /// <param name="para">传递的下载参数</param> /// <param name="task">当前下载的任务信息</param> /// <returns>一个布尔值,指示指定的下载是否已成功完成</returns> public static bool DownloadFile(DownloadParameter para, TaskInfo task) { //用于限速的Tick Int32 privateTick = 0; //网络数据包大小 = 1KB byte[] buffer = new byte[1024]; //网络流 Stream st; //文件流 Stream fs; //Deflate/gzip 解压流 Stream decompressStream = null; //缓冲流 BufferedStream bs; //服务器是否支持range bool supportrange = false; //是否启用断点续传 bool enableResume = false; //提取缓存 bool extractcache = false; if (task != null) extractcache = para.ExtractCache; //修正代理服务器 //if (para.Proxy == null) // para.Proxy = new WebProxy(); //初始化重试管理器 bool needRedownload = false; //需要重试下载 int remainRetryTime = GlobalSettings.GetSettings().RetryTimes; //剩余的重试次数 //允许重试时才进行循环 do { //Http请求 HttpWebRequest request; //服务器回应 HttpWebResponse response; #region 获取多次跳转后的真实地址 bool needRedirect = false; //是否需要继续获取Location值(重定向) do { //创建http请求 request = (HttpWebRequest)HttpWebRequest.Create(para.Url); //设置超时 request.Timeout = GlobalSettings.GetSettings().NetworkTimeout; //设置代理服务器 if (para.Proxy != null) request.Proxy = para.Proxy; //设置Cookie if (para.Cookies != null) request.CookieContainer = para.Cookies; request.AllowAutoRedirect = false; //获取服务器回应 response = (HttpWebResponse)request.GetResponse(); if (!string.IsNullOrEmpty(response.Headers["Location"])) { para.Url = response.Headers["Location"]; needRedirect = true; } else { needRedirect = false; } } while (needRedirect); //重新获取服务器回应 #endregion #region 检查文件是否被下载过&是否支持断点续传 //检查服务器是否支持断点续传 if (response != null) supportrange = (response.Headers[HttpResponseHeader.AcceptRanges] == "bytes"); //设置文件长度和已下载的长度 //文件长度 para.TotalLength = response.ContentLength; #region 检查系统缓存 try { if (extractcache && para.TotalLength > 0) //如果允许提取缓存且文件长度大于0时 { //获取temp文件夹 string tempfolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Temp\"); //获取internet cache文件夹 string internettemp = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); //查找到的文件名称 string filename = null; //查找文件 //internet cache文件夹 string[] files = Directory.GetFiles(internettemp, para.ExtractCachePattern, SearchOption.AllDirectories); foreach (var file in files) { FileInfo fi = new FileInfo(file); if (fi.Length == para.TotalLength) { filename = file; break; } } if (String.IsNullOrEmpty(filename)) //系统temp文件夹 { files = Directory.GetFiles(tempfolder, para.ExtractCachePattern, SearchOption.AllDirectories); foreach (var file in files) { FileInfo fi = new FileInfo(file); if (fi.Length == para.TotalLength) { filename = file; break; } } } //释放空间 files = null; //如果找到文件则直接复制 if (!String.IsNullOrEmpty(filename)) { para.DoneBytes = para.TotalLength; File.Copy(filename, para.FilePath); //不需要继续下载 needRedownload = false; //返回下载成功 return true; } } } catch { //如果复制过程中出错则继续下载 para.DoneBytes = 0; needRedownload = true; } #endregion //建立文件夹 string dir = Directory.GetParent(para.FilePath).ToString(); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); //如果要下载的文件存在 long filelength = 0; if (File.Exists(para.FilePath)) { filelength = new FileInfo(para.FilePath).Length; if (filelength > 0) { //如果文件长度相同 if (filelength == para.TotalLength) { //返回下载成功 return true; } //如果【已有文件长度小于网络文件总长度】且【服务器支持断点续传】才启用断点续传功能 enableResume = (filelength < para.TotalLength) && supportrange; //如果服务器支持断点续传 if (enableResume) { //重新获取服务器回应 if (response != null) response.Close(); //创建http请求 var newrequest = (HttpWebRequest)HttpWebRequest.Create(para.Url); //设置超时 newrequest.Timeout = GlobalSettings.GetSettings().NetworkTimeout; //设置代理服务器 if (para.Proxy != null) newrequest.Proxy = para.Proxy; //设置Cookie if (para.Cookies != null) request.CookieContainer = para.Cookies; //设置Range newrequest.AddRange(int.Parse(filelength.ToString())); var newresponse = (HttpWebResponse)newrequest.GetResponse(); //检测服务器是否存在欺诈(宣称支持断点续传且返回200 OK,但是内容为报错信息。经常出现在新浪视频服务器的返回信息中) //判定为欺诈的条件为:返回的长度小于剩余(未下载的)文件长度的90% if (newresponse.ContentLength < (para.TotalLength - filelength) * 9 / 10) { //重新获取文件 response = (HttpWebResponse)request.GetResponse(); //服务器不支持断点续传 enableResume = false; //设置"已完成字节数" para.DoneBytes = 0; } else { //服务器支持断点续传 para.DoneBytes = filelength; //设置新连接 response = newresponse; } } } } #endregion int t, limitcount = 0; //系统计数 para.LastTick = System.Environment.TickCount; //获取下载流 using (st = response.GetResponseStream()) { //设置gzip/deflate解压缩 if (response.ContentEncoding == "gzip") { decompressStream = new GZipStream(st, CompressionMode.Decompress); } else if (response.ContentEncoding == "deflate") { decompressStream = new DeflateStream(st, CompressionMode.Decompress); } else { decompressStream = st; } //设置FileStream if (enableResume)//若允许断点续传 { fs = new FileStream(para.FilePath, FileMode.Open, FileAccess.Write, FileShare.Read, 8); fs.Seek(filelength, SeekOrigin.Begin); } else //不允许断点续传 { fs = new FileStream(para.FilePath, FileMode.Create, FileAccess.Write, FileShare.Read, 8); } //打开文件流 using (fs) { //使用缓冲流 bs = new BufferedStream(fs, GlobalSettings.GetSettings().CacheSize * 1024 * 1024); try { //读取第一块数据 Int32 osize = decompressStream.Read(buffer, 0, buffer.Length); //开始循环 while (osize > 0) { #region 判断是否取消下载 //如果用户终止则返回false if (para.IsStop) { //关闭流 bs.Close(); st.Close(); fs.Close(); return false; } #endregion //增加已完成字节数 para.DoneBytes += osize; //写文件(缓存) bs.Write(buffer, 0, osize); //设置限速 int limit = 0; if (task != null) if (task.SpeedLimit >= 0) limit = task.SpeedLimit; if (limit > 0) { //下载计数加一count++ limitcount++; //下载1KB osize = decompressStream.Read(buffer, 0, buffer.Length); //累积到limit KB后 if (limitcount >= limit) { t = System.Environment.TickCount - privateTick; //检查是否大于一秒 if (t < 1000) //如果小于一秒则等待至一秒 Thread.Sleep(1000 - t); //重置count和计时器,继续下载 limitcount = 0; privateTick = System.Environment.TickCount; } } else //如果不限速 { osize = decompressStream.Read(buffer, 0, buffer.Length); } } //end while //如果下载完成的数据没有到达服务器宣称的长度的90%就报告错误 if (para.TotalLength > 0) if (para.DoneBytes < (para.TotalLength * 9 / 10)) throw new Exception("Data downloaded is less than the server announced."); //下载成功完成,不需要重新下载 needRedownload = false; } //end bufferedstream catch (Exception ex) { //可重试次数减1 remainRetryTime--; //不再重试直接抛出异常的规则: //1.没有可重试次数 //2.服务器不支持断点续传 if (remainRetryTime < 0 || (!enableResume)) { needRedownload = false; throw ex; } else //否则继续重试 { needRedownload = true; //重试前等待的时间 Thread.Sleep(GlobalSettings.GetSettings().RetryWaitingTime); } } finally { bs.Close(); } }// end filestream } //end netstream } while (needRedownload); //end while(needReDownload) //一切顺利返回true 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 override bool Download() { //开始下载 TipText("正在分析视频地址"); //原始Url Info.Url = Info.Url.TrimStart('+'); //修正url string url = "http://www.flvcd.com/parse.php?format=&kw=" + Tools.UrlEncode(Info.Url); try { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.GetEncoding("UTF-8"), 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; }
//下载视频 public override bool Download() { //开始下载 TipText("正在解析视频地址"); //解析专辑 if (Regex.IsMatch(Info.Url, TudouPlugin.regAlbumcover, RegexOptions.IgnoreCase)) { string source = Network.GetHtmlSource(Info.Url, Encoding.GetEncoding("GBK"), Info.Proxy); MatchCollection mcAlbumPlays = Regex.Matches(source.Replace(" ", "").Replace("\t", "").Replace("\r\n", ""), @"<h6class=""caption.+?(?<url>http://www\.tudou\.com/albumplay/[\w\-]+(/[\w\-]+|)\.html)"">(?<title>.+?)</a></h6>"); var plays = new Dictionary<string, string>(); foreach (Match mAlbumPlays in mcAlbumPlays) { string aUrl = mAlbumPlays.Groups["url"].Value; string aTitle = mAlbumPlays.Groups["title"].Value; plays.Add(aUrl, aTitle); } var chosen = ToolForm.CreateMultiSelectForm(plays, null, "tudou"); if (chosen.Count == 0) throw new Exception("未从列表中选择任何视频"); //修正当前url为用户选中的第一个url Info.Url = chosen[0]; //添加其他任务 for (int i = 1; i < chosen.Count; i++) { NewTask(chosen[i]); } } string url = Info.Url; //修正豆泡网址 if (Regex.Match(Info.Url, TudouPlugin.regDpProgramview).Success) { url = @"http://www.tudou.com/programs/view/" + Regex.Match(Info.Url, TudouPlugin.regDpProgramview).Groups["icode"].Value; } else if (Regex.IsMatch(Info.Url, TudouPlugin.regDpAlbumList)) { url = Info.Url.Replace("dp.tudou.com", "www.tudou.com"); url = url.Replace("/l/", "/listplay/"); url = url.Replace("/a/", "/albumplay/"); } //Settings["icode"] = Regex.Match(Info.Url, TudouPlugin.regProgramView).Groups["icode"].Value; string src = Network.GetHtmlSource(url, Encoding.GetEncoding("GBK"), Info.Proxy); //取得iid Settings["iid"] = Regex.Match(src.Replace(" ", ""), @"(?<=iid:)\d+").Value; //取得专辑标题 Settings["AlbumTitle"] = Regex.Match(src, @"(?<=atitle="").+?(?="")").Value ?? ""; //视频标题 Info.Title = Regex.Match(src, @"(?<=kw:( |)(""|')).+?(?=(""|'))").Value; Settings["title"] = Tools.InvalidCharacterFilter(Info.Title, ""); if (!string.IsNullOrEmpty(Settings["AlbumTitle"])) { Settings["title"] = Tools.InvalidCharacterFilter(Settings["AlbumTitle"], "") + Path.DirectorySeparatorChar + Settings["title"]; } //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); //调用土豆视频解析器 TudouParser parserTudou = new TudouParser(); var pr = parserTudou.Parse(new ParseRequest() { Id = Settings["iid"], Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); videos = pr.ToArray(); //下载弹幕 if ((Info.DownloadTypes & DownloadType.Subtitle) != 0) { //如果视频地址属于豆泡 if (Regex.IsMatch(Info.Url, TudouPlugin.regDpProgramview) || Regex.IsMatch(Info.Url, TudouPlugin.regDpAlbumList)) { TipText("正在下载弹幕文件"); try { var subfile = Path.Combine(Info.SaveDirectory.ToString(), Settings["title"] + ".json"); Info.SubFilePath.Clear(); Info.SubFilePath.Add(subfile); Network.DownloadFile(new DownloadParameter() { FilePath = subfile, Url = "http://comment.dp.tudou.com/comment/get/" + Settings["iid"] + "/vdn12d/", Proxy = Info.Proxy }); } catch { } } } //下载视频 //确定视频共有几个段落 Info.PartCount = videos.Length; TipText("正在开始下载视频文件"); //分段落下载 for (int i = 0; i < videos.Length; i++) { //取得文件后缀名 string ext = Tools.GetExtension(videos[i]); if (ext == ".f4v") ext = ".flv"; //设置当前DownloadParameter if (Info.PartCount == 1) //如果只有一段 { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), Settings["title"] + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } else //如果分段有多段 { currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), Settings["title"] + "(" + (i + 1).ToString() + ")" + ext), //文件URL Url = videos[i], //代理服务器 Proxy = Info.Proxy }; } //添加文件路径到List<>中 Info.FilePath.Add(currentParameter.FilePath); //下载文件 bool success; //提示更换新Part NewPart(i + 1, videos.Length); //下载视频文件 success = Network.DownloadFile(currentParameter, this.Info); //下载视频 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 + " 下载失败"; } } } //生成.acplay文件 if (File.Exists(Path.Combine(Info.SaveDirectory.ToString(), Settings["title"] + ".json"))) { var acplay = GenerateAcplayConfig(pr, Settings["title"]); if (!string.IsNullOrEmpty(acplay)) Settings["AcPlay"] = acplay; } //下载成功完成 return true; }
//下载视频 public bool Download() { //开始下载 delegates.TipText(new ParaTipText(this.Info, "正在分析视频地址")); try { //获取密码 string password = ""; if (Info.Url.EndsWith("密码")) { password = ToolForm.CreatePasswordForm(true, "", ""); Info.Url.Replace("密码", ""); } //取得网页源文件 string src = Network.GetHtmlSource(Info.Url, Encoding.GetEncoding("GBK"), Info.Proxy); //分析视频iid string iid = ""; //取得iid Regex rlist = new Regex(@"(a|l)(?<aid>\d+)(i(?<iid>\d+)|)(?=\.html)"); Match mlist = rlist.Match(Info.Url); if (mlist.Success) //如果是列表中的视频 { //尝试取得url中的iid if (!string.IsNullOrEmpty(mlist.Groups["iid"].Value)) { iid = mlist.Groups["iid"].Value; } else //否则取得源文件中的iid { Regex r1 = new Regex(@"defaultIid = (?<iid>\d.*)"); Match m1 = r1.Match(src); iid = m1.Groups["iid"].ToString(); } } else //如果是普通视频(或新列表视频) { //2012.08.26修改: // http://www.tudou.com/listplay/69gOmmDlugI/JJKorVrTgPk.html 走这个if后面会有问题,但用listData的话是好的,就注释掉了 //URL中获取id /*var mIdInUrl = Regex.Match(Info.Url, @"listplay/(?<l>.+?)/(?<i>.+?)(?=\.html)"); if (mIdInUrl.Success) { iid = mIdInUrl.Groups["i"].Value; } else*/ { //2012.08.26修改 albumplay进到这儿的等号两边是没空格的。。 var mIdInSrc = Regex.Match(src, @"((?<=listData = \[{\niid:)|(?<=listData=\[{\niid:))\w+"); if (mIdInSrc.Success) { iid = mIdInSrc.Value; } else { Regex r1 = new Regex(@"(I|i)id = (?<iid>\d.*)"); Match m1 = r1.Match(src); iid = m1.Groups["iid"].ToString(); //2012.08.26修改: 针对 http://www.tudou.com/programs/view/ShtKrHZ5O_8/?fr=rec2 的情况,这时候iid=88582122 ,icode = 'ShtKrHZ5O_8' ,oid = 91827385 (后面大量) int space_pos = iid.IndexOf(' '); if (space_pos >= 0) { iid = iid.Substring(0, space_pos); } } } } //取得视频标题 string title = ""; if (mlist.Success) { //取得aid/lid标题 string aid = mlist.Groups["aid"].Value; Regex rlisttitle = null; Match mlisttitle = null; if (mlist.ToString().StartsWith("a")) //如果是a开头的列表 { rlisttitle = new Regex(@"aid:" + aid + @"\n,name:""(?<title>.+?)""", RegexOptions.Singleline); mlisttitle = rlisttitle.Match(src); } else if (mlist.ToString().StartsWith("l")) //如果是l开头的列表 { rlisttitle = new Regex(@"ltitle = ""(?<title>.+?)""", RegexOptions.Singleline); mlisttitle = rlisttitle.Match(src); } //取得iid标题 Regex rsubtitle = new Regex(@"iid:" + iid + @"\n(,cartoonType:\d+\n|),title:""(?<subtitle>.+?)""", RegexOptions.Singleline); Match msubtitle = rsubtitle.Match(src); title = mlisttitle.Groups["title"].Value + "-" + msubtitle.Groups["subtitle"].Value; } else { Regex rTitle = new Regex(@"\<h1\>(?<title>.*)\<\/h1\>"); Match mTitle = rTitle.Match(src); title = mTitle.Groups["title"].Value; } Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); //视频地址数组 string[] videos = null; //清空地址 Info.FilePath.Clear(); //调用内建的土豆视频解析器 TudouParser parserTudou = new TudouParser(); videos = parserTudou.Parse(new ParseRequest() { Id = iid, Password = password, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }).ToArray(); 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 (ext == ".f4v") 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; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频文件 success = Network.DownloadFile(currentParameter, this.Info); //下载视频 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; }
public bool DownLoadCNTV(string url) { string chaper_src = Network.GetHtmlSource(url, Encoding.GetEncoding("GBK"), Info.Proxy); Regex regChapter = new Regex("title\":\"(?<title>[^\"]+)"); Match item = regChapter.Match (chaper_src); if (item.Success == false) return false; string title = item.Groups["title"].Value; Info.Title = title; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); regChapter = new Regex("url\":\"(?<vido_url>[^\"]+)"); List<string> partUrls = new List<string>(); foreach (Match match in regChapter.Matches(chaper_src)) { partUrls.Add(match.Groups["vido_url"].Value); } //重新设置保存目录(生成子文件夹) 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 + " 下载失败"; } } } return true; }
/// <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; else if (!Info.Url.StartsWith("http://", StringComparison.CurrentCultureIgnoreCase)) Info.Url = "http://" + Info.Url; //修正URL为 http://www.acfun.tv/v/ac12345_67 形式 Info.Url = Info.Url.Replace(".html", "").Replace("/index", ""); if (!Info.Url.Contains("_")) { Info.Url += "_1"; } //取得AC号和子编号 Match mAcNumber = Regex.Match(Info.Url, @"(?<ac>ac\d+)_(?<sub>\d+)"); m_acNumber = mAcNumber.Groups["ac"].Value; m_acSubNumber = mAcNumber.Groups["sub"].Value; //设置自定义文件名 m_customFileName = AcFunPlugin.DefaultFileNameFormat; if (Info.BasePlugin.Configuration.ContainsKey("CustomFileName")) { m_customFileName = Info.BasePlugin.Configuration["CustomFileName"]; } //是否通过【自动应答】禁用对话框 bool disableDialog = false; disableDialog = AutoAnswer.IsInAutoAnswers(Info.AutoAnswer, "acfun", "auto"); //当前播放器地址 Settings["PlayerUrl"] = @"http://static.acfun.tv/player/ssl/ACFlashPlayerN0102.swf"; //取得网页源文件 string src = Network.GetHtmlSource(Info.Url, Encoding.UTF8, Info.Proxy); var relatedVideoList = new Dictionary<string, string>(); TipText("正在获取视频详细信息"); var videoIdCollection = Regex.Matches(src, @"<a data-vid=""(?<vid>\d+)"" data-from=""(?<from>\w+)""(?: data-did=""(?<did>\w*?)"")? data-sid=""(?<sid>\w+)"" href=""(?<href>.+?)"" title=""(?<title>.+?)"".+?>(?<content>.+?)</a>", RegexOptions.IgnoreCase); foreach (Match mVideoId in videoIdCollection) { //所有子标题 if (mVideoId.Groups["content"].Value.Contains("<i")) //当前标题 { m_currentPartTitle = Regex.Replace(mVideoId.Groups["content"].Value, @"<i.+?i>", "", RegexOptions.IgnoreCase); m_currentPartVideoId = mVideoId.Groups["vid"].Value; } else //其他标题 { relatedVideoList.Add("http://www.acfun.tv" + mVideoId.Groups["href"].Value, mVideoId.Groups["content"].Value); } } //取得视频标题 var videoTitleMatchResult = Regex.Match(src, @"(?<=system\.title = \$\.parseSafe\(')(.+?)(?='\))", RegexOptions.IgnoreCase); if (!videoTitleMatchResult.Success) { videoTitleMatchResult = Regex.Match(src, @"(?<=<title>).+?(?=</title>)", RegexOptions.IgnoreCase); } m_videoTitle = videoTitleMatchResult.Value; m_currentPartTitle = string.IsNullOrEmpty(m_currentPartTitle) ? m_videoTitle : m_currentPartTitle; m_currentPartTitle = m_currentPartTitle.Replace(" - AcFun弹幕视频网 - 中国宅文化基地", ""); //取得当前视频完整标题 Info.Title = m_videoTitle + " - " + m_currentPartTitle; m_videoTitle = Tools.InvalidCharacterFilter(m_videoTitle, ""); m_currentPartTitle = Tools.InvalidCharacterFilter(m_currentPartTitle, ""); //解析关联项需要同时满足的条件: //1.这个任务不是被其他任务所添加的 //2.用户设置了“解析关联项” TipText("正在选择关联视频"); if (!Info.IsBeAdded && Info.ParseRelated && relatedVideoList.Count > 0) { //用户选择任务 var ba = new Collection<string>(); if (!disableDialog) ba = ToolForm.CreateMultiSelectForm(relatedVideoList, Info.AutoAnswer, "acfun"); //根据用户选择新建任务 foreach (string u in ba) { //新建任务 delegates.NewTask(new ParaNewTask(Info.BasePlugin, u, this.Info)); } } //视频地址数组 //清空地址 Info.FilePath.Clear(); Info.SubFilePath.Clear(); //下载弹幕 DownloadSubtitle(m_currentPartVideoId); TipText("正在解析视频源地址"); //解析器的解析结果 ParseResult pr = null; //如果允许下载视频 if ((Info.DownloadTypes & DownloadType.Video) != 0) { var parser = new AcfunInterfaceParser(); pr = parser.Parse(new ParseRequest { Id = m_currentPartVideoId, Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer }); //视频地址列表 var videos = pr.ToArray(); //支持导出列表 if (videos != null) { var sb = new StringBuilder(); foreach (string item in videos) { sb.Append(item); sb.Append("|"); } Settings["ExportUrl"] = sb.ToString(); } //下载视频 TipText("正在开始下载视频文件"); //确定视频共有几个段落 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(m_customFileName, m_videoTitle, m_currentPartTitle, Info.PartCount == 1 ? "" : Info.CurrentPart.ToString(), ext.Replace(".", ""), m_acNumber, m_acSubNumber); filename = Path.Combine(Info.SaveDirectory.ToString(), filename); //添加文件名到文件列表中 Info.FilePath.Add(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" }; //下载文件 bool success = false; //提示更换新Part delegates.NewPart(new ParaNewPart(this.Info, i + 1)); //下载视频 try { success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return false; } } catch //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw; } 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); //支持AcPlay直接播放 Settings["AcPlay"] = acplay; } //生成视频自动合并参数 if (Info.FilePath.Count > 1 && !Info.PartialFinished) { Info.Settings.Remove("VideoCombine"); var arg = new StringBuilder(); foreach (var item in Info.FilePath) { arg.Append(item); arg.Append("|"); } var renamehelper = new CustomFileNameHelper(); string filename = renamehelper.CombineFileName(m_customFileName, m_videoTitle, m_currentPartTitle, "", "mp4", m_acNumber, m_acSubNumber); filename = Path.Combine(Info.SaveDirectory.ToString(), filename); arg.Append(filename); Info.Settings["VideoCombine"] = arg.ToString(); } //下载成功完成 return true; }
//下载视频 public override bool Download() { //开始下载 TipText("正在分析视频地址"); //修正井号 Info.Url = Info.Url.TrimEnd('#'); //修正旧版URL Info.Url = Info.Url.Replace("bilibili.us", "bilibili.tv"); Info.Url = Info.Url.Replace("www.bilibili.tv", "bilibili.kankanews.com"); Info.Url = Info.Url.Replace("bilibili.tv", "bilibili.kankanews.com"); //修正简写URL if (Regex.Match(Info.Url, @"^av\d{2,6}$").Success) Info.Url = "http://bilibili.kankanews.com/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\.kankanews\.com(?<part>/video/av\d+/index_\d+\.html)").Groups["part"].Value; //取得AV号和子编号 Match mAVNumber = Regex.Match(Info.Url, @"(?<av>av\d+)/index_(?<sub>\d+)\.html"); Settings["AVNumber"] = mAVNumber.Groups["ac"].Value; Settings["AVSubNumber"] = mAVNumber.Groups["sub"].Value; //设置自定义文件名 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 == "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(); string subtitle = title; //取得子标题 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) { subtitle = 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 + " - " + subtitle; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); subtitle = Tools.InvalidCharacterFilter(subtitle, ""); //清空地址 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; //下载弹幕 bool comment = DownloadComment(title, subtitle, id); if (!comment) { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } //解析器的解析结果 ParseResult pr = null; //如果允许下载视频 if ((Info.DownloadTypes & DownloadType.Video) != 0) { 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"; //设置文件名 var renamehelper = new CustomFileNameHelper(); string filename = renamehelper.CombineFileName(Settings["CustomFileName"], title, subtitle, Info.PartCount == 1 ? "" : Info.CurrentPart.ToString(), ext.Replace(".", ""), Info.Settings["AVNumber"], Info.Settings["AVSubNumber"]); filename = Path.Combine(Info.SaveDirectory.ToString(), filename); //生成父文件夹 if (!Directory.Exists(Path.GetDirectoryName(filename))) Directory.CreateDirectory(Path.GetDirectoryName(filename)); //设置当前DownloadParameter currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = filename, //文件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 判断是否下载视频 //如果插件设置中没有GenerateAcPlay项,或此项设置为true则生成.acplay快捷方式 if (!Info.BasePlugin.Configuration.ContainsKey("GenerateAcPlay") || Info.BasePlugin.Configuration["GenerateAcPlay"] == "true") { //生成AcPlay文件 string acplay = GenerateAcplayConfig(pr, title, subtitle); //支持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) { Info.Settings["user"] = ""; Info.Settings["password"] = ""; throw ex; } return true; }
protected bool DownloadWithRescue(DownloadParameter p) { //下载视频 try { this.currentParameter = p; if (!Network.DownloadFile(currentParameter, this.Info)) //未出现错误即用户手动停止 { return false; } } catch (Exception ex) //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw ex; } else //否则继续下载,设置“部分失败”状态 { Info.PartialFinished = true; Info.PartialFinishedDetail += "\r\n文件: " + currentParameter.Url + " 下载失败"; } } return true; }
//下载视频 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 override bool Download() { //开始下载 TipText("正在开始任务"); //获取视频编号 string sm = Regex.Match(Info.Url, @"(?<=(http://www\.nicovideo\.jp/watch/|))sm\d+").Value; //修正简写URL if (Info.Url.StartsWith("sm", StringComparison.CurrentCultureIgnoreCase)) Info.Url = "http://www.nicovideo.jp/watch/" + Info.Url; //获取网页源代码 string src = Network.GetHtmlSource(Info.Url, Encoding.UTF8, Info.Proxy); //匹配登录按钮 Match mLoginButton = Regex.Match(src, "(?<=アカウント新規登録へ.+?<a href=\").+?(?=\">.+?ログイン画面へ)"); //获取登录地址 string loginUrl = mLoginButton.Value; TipText("正在登录Nico"); //向网页Post数据 CookieContainer cookies = new CookieContainer(); //登录NicoNico 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(null,"https://secure.nicovideo.jp/secure/register"); Info.Settings["user"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(user.Username)); Info.Settings["password"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(user.Password)); } //Post的数据 string postdata = string.Format("next_url={0}&mail={1}&password={2}", sm, Tools.UrlEncode(user.Username), Tools.UrlEncode(user.Password)); byte[] data = Encoding.UTF8.GetBytes(postdata); //生成请求 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://secure.nicovideo.jp/secure/login?site=niconico"); req.Proxy = Info.Proxy; req.AllowAutoRedirect = false; req.Method = "POST"; req.Referer = loginUrl; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20100101 Firefox/16.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 TipText("正在解析视频标题"); //解析视频标题 HttpWebRequest reqTitle = (HttpWebRequest)HttpWebRequest.Create(Info.Url); reqTitle.Proxy = Info.Proxy; //设置cookies reqTitle.CookieContainer = cookies; //获取视频信息 string srcTitle = Network.GetHtmlSource(reqTitle, Encoding.UTF8); //视频标题 Info.Title = Regex.Match(srcTitle, @"(?<=<title>).+?(?=</title>)").Value.Replace("‐ ニコニコ動画(原宿)", "").Trim(); //Info.Title = Regex.Match(srcTitle, @"(?<=<span class=""videoHeaderTitle"">).+?(?=</span>)").Value; string title = Tools.InvalidCharacterFilter(Info.Title, ""); TipText("正在分析视频地址"); //通过API获取视频信息 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(@"http://flapi.nicovideo.jp/api/getflv/" + sm); request.Method = "POST"; request.Proxy = Info.Proxy; //设置cookies request.CookieContainer = cookies; //获取视频信息 string videoinfo = Network.GetHtmlSource(request, Encoding.ASCII); //视频真实地址 string video = Regex.Match(videoinfo, @"(?<=url=).+?(?=&)").Value; video = video.Replace("%3A", ":").Replace("%2F", "/").Replace("%3F", "?").Replace("%3D", "="); //下载视频 NewPart(1, 1); //设置下载参数 currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = Path.Combine(Info.SaveDirectory.ToString(), title + ".mp4"), //文件URL Url = video, //代理服务器 Proxy = Info.Proxy, //Cookie Cookies = cookies, //提取缓存 ExtractCache = Info.ExtractCache, ExtractCachePattern = "fla*.tmp" }; //下载视频 bool success = Network.DownloadFile(currentParameter, this.Info); if (!success) //未出现错误即用户手动停止 { return false; } return true; }
public bool DownLoadFile (List<string> partUrls, string folder, string chapter, string ext) { Info.Title = chapter; //过滤非法字符 folder = Tools.InvalidCharacterFilter(folder, ""); //重新设置保存目录(生成子文件夹) if (!Info.SaveDirectory.ToString().EndsWith(folder)) { string newdir = Path.Combine(Info.SaveDirectory.ToString(), folder); 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; //取得文件后缀名 if (ext.Length <= 0) { ext = Tools.GetExtension(partUrls[i]); if (string.IsNullOrEmpty(ext)) { if (string.IsNullOrEmpty(Path.GetExtension(partUrls[i]))) ext = ".flv"; else ext = Path.GetExtension(partUrls[i]); } } string div = ""; if (Info.PartCount > 1) { div = "-" + string.Format("{0:00}", i); } string file_path = Path.Combine(Info.SaveDirectory.ToString(), chapter + ext); //设置当前DownloadParameter currentParameter = new DownloadParameter() { //文件名 FilePath = file_path, //文件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 + " 下载失败"; } } } return true; }
/// <summary> /// 下载文件 /// </summary> /// <param name="para">传递的下载参数</param> /// <returns>一个布尔值,指示指定的下载是否已成功完成</returns> public static bool DownloadFile(DownloadParameter para) { return DownloadFile(para, null); }
//下载视频 public override bool Download() { //开始下载 TipText("正在分析视频地址"); //清空地址 Info.FilePath.Clear(); //从url中获得hid和partId var urlMatch = Regex.Match(Info.Url, @"tucao\.cc/play/h(?<hid>\d+)(?:/#(?<partId>\d+))?", RegexOptions.IgnoreCase); int hid = int.Parse(urlMatch.Groups["hid"].Value); int partId = int.Parse(urlMatch.Groups["partId"].Success ? urlMatch.Groups["partId"].Value : "1"); //取得视频信息 var videoInfo = JsonConvert.DeserializeObject<TucaoVideoInfo>( Network.GetHtmlSource(string.Format(@"http://www.tucao.cc/api_v2/view.php?hid={0}&apikey={1}", hid, API_KEY), Encoding.UTF8)); var currentPart = videoInfo.result.video[partId - 1]; string title = videoInfo.result.title; string subtitle = currentPart.title; if (title.Equals(subtitle)) subtitle = ""; if (!string.IsNullOrEmpty(subtitle)) //如果存在子标题(视频为合集) { //更改标题 title = title + " - " + subtitle; //更改URL防止hash时出错 Info.Url = Info.Url + "#" + partId; } //过滤非法字符 Info.Title = title; title = Tools.InvalidCharacterFilter(title, ""); //视频地址数组 string[] videos = null; //如果允许下载视频 if ((Info.DownloadTypes & DownloadType.Video) != 0) { //获取视频地址 var video = new TucaoInterfaceParser().Parse(currentPart.type, currentPart.vid, Info.Proxy); videos = video.ToArray(); //下载视频 //确定视频共有几个段落 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; //提示更换新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 (((Info.DownloadTypes & DownloadType.Subtitle) != 0)) { //----------下载字幕----------- delegates.TipText(new ParaTipText(this.Info, "正在下载字幕文件")); //字幕文件(on)地址 string subfile = Path.Combine(Info.SaveDirectory.ToString(), title + ".xml"); Info.SubFilePath.Add(subfile); //取得字幕文件(on)地址 string subUrl = string.Format("http://www.tucao.cc/index.php?m=mukio&c=index&a=init&playerID=11-{0}-1-{1}&r=0.5134681154294", hid, partId); //下载字幕文件 try { Network.DownloadFile(new DownloadParameter() { Url = subUrl, FilePath = subfile, Proxy = Info.Proxy }); } catch { //Info.PartialFinished = true; //Info.PartialFinishedDetail += "\r\n弹幕文件文件下载失败"; } }// end 下载弹幕xml //视频合并 if (Info.FilePath.Count > 1 && !Info.PartialFinished) { Info.Settings.Remove("VideoCombine"); var arg = new StringBuilder(); foreach (var item in Info.FilePath) { arg.Append(item); arg.Append("|"); } arg.Append(Path.Combine(Info.SaveDirectory.ToString(), title + ".mp4")); Info.Settings["VideoCombine"] = arg.ToString(); } //下载成功完成 return true; }
//下载视频 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.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]); //设置当前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; }
//下载视频 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; }
/// <summary> /// 下载文件 /// </summary> /// <param name="para">传递的下载参数</param> /// <param name="task">当前下载的任务信息</param> /// <returns>一个布尔值,指示指定的下载是否已成功完成</returns> public static bool DownloadFile(DownloadParameter para, TaskInfo task) { //用于限速的Tick Int32 privateTick = 0; //网络数据包大小 = 1KB byte[] buffer = new byte[1024]; //网络流 Stream st; //文件流 Stream fs; //Deflate/gzip 解压流 Stream decompressStream = null; //缓冲流 BufferedStream bs; //服务器是否支持range bool supportrange = false; //是否启用断点续传 bool enableResume = false; //提取缓存 bool extractcache = false; if (task != null) { extractcache = para.ExtractCache; } //修正代理服务器 //if (para.Proxy == null) // para.Proxy = new WebProxy(); //初始化重试管理器 bool needRedownload = false; //需要重试下载 int remainRetryTime = GlobalSettings.GetSettings().RetryTimes; //剩余的重试次数 //允许重试时才进行循环 do { //Http请求 HttpWebRequest request; //服务器回应 HttpWebResponse response; #region 获取多次跳转后的真实地址 bool needRedirect = false; //是否需要继续获取Location值(重定向) do { //创建http请求 request = (HttpWebRequest)HttpWebRequest.Create(para.Url); //设置超时 request.Timeout = GlobalSettings.GetSettings().NetworkTimeout; //设置代理服务器 if (para.Proxy != null) { request.Proxy = para.Proxy; } //设置Cookie if (para.Cookies != null) { request.CookieContainer = para.Cookies; } request.AllowAutoRedirect = false; //获取服务器回应 response = (HttpWebResponse)request.GetResponse(); if (!string.IsNullOrEmpty(response.Headers["Location"])) { para.Url = response.Headers["Location"]; needRedirect = true; } else { needRedirect = false; } } while (needRedirect); //重新获取服务器回应 #endregion #region 检查文件是否被下载过&是否支持断点续传 //检查服务器是否支持断点续传 if (response != null) { supportrange = (response.Headers[HttpResponseHeader.AcceptRanges] == "bytes"); } //设置文件长度和已下载的长度 //文件长度 para.TotalLength = response.ContentLength; #region 检查系统缓存 try { if (extractcache && para.TotalLength > 0) //如果允许提取缓存且文件长度大于0时 { //获取temp文件夹 string tempfolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Temp\"); //获取internet cache文件夹 string internettemp = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); //查找到的文件名称 string filename = null; //查找文件 //internet cache文件夹 string[] files = Directory.GetFiles(internettemp, para.ExtractCachePattern, SearchOption.AllDirectories); foreach (var file in files) { FileInfo fi = new FileInfo(file); if (fi.Length == para.TotalLength) { filename = file; break; } } if (String.IsNullOrEmpty(filename)) //系统temp文件夹 { files = Directory.GetFiles(tempfolder, para.ExtractCachePattern, SearchOption.AllDirectories); foreach (var file in files) { FileInfo fi = new FileInfo(file); if (fi.Length == para.TotalLength) { filename = file; break; } } } //释放空间 files = null; //如果找到文件则直接复制 if (!String.IsNullOrEmpty(filename)) { para.DoneBytes = para.TotalLength; File.Copy(filename, para.FilePath); //不需要继续下载 needRedownload = false; //返回下载成功 return(true); } } } catch { //如果复制过程中出错则继续下载 para.DoneBytes = 0; needRedownload = true; } #endregion //建立文件夹 string dir = Directory.GetParent(para.FilePath).ToString(); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } //如果要下载的文件存在 long filelength = 0; if (File.Exists(para.FilePath)) { filelength = new FileInfo(para.FilePath).Length; if (filelength > 0) { //如果文件长度相同 if (filelength == para.TotalLength) { //返回下载成功 return(true); } //如果【已有文件长度小于网络文件总长度】且【服务器支持断点续传】才启用断点续传功能 enableResume = (filelength < para.TotalLength) && supportrange; //如果服务器支持断点续传 if (enableResume) { //重新获取服务器回应 if (response != null) { response.Close(); } //创建http请求 var newrequest = (HttpWebRequest)HttpWebRequest.Create(para.Url); //设置超时 newrequest.Timeout = GlobalSettings.GetSettings().NetworkTimeout; //设置代理服务器 if (para.Proxy != null) { newrequest.Proxy = para.Proxy; } //设置Cookie if (para.Cookies != null) { request.CookieContainer = para.Cookies; } //设置Range newrequest.AddRange(int.Parse(filelength.ToString())); var newresponse = (HttpWebResponse)newrequest.GetResponse(); //检测服务器是否存在欺诈(宣称支持断点续传且返回200 OK,但是内容为报错信息。经常出现在新浪视频服务器的返回信息中) //判定为欺诈的条件为:返回的长度小于剩余(未下载的)文件长度的90% if (newresponse.ContentLength < (para.TotalLength - filelength) * 9 / 10) { //重新获取文件 response = (HttpWebResponse)request.GetResponse(); //服务器不支持断点续传 enableResume = false; //设置"已完成字节数" para.DoneBytes = 0; } else { //服务器支持断点续传 para.DoneBytes = filelength; //设置新连接 response = newresponse; } } } } #endregion int t, limitcount = 0; //系统计数 para.LastTick = System.Environment.TickCount; //获取下载流 using (st = response.GetResponseStream()) { //设置gzip/deflate解压缩 if (response.ContentEncoding == "gzip") { decompressStream = new GZipStream(st, CompressionMode.Decompress); } else if (response.ContentEncoding == "deflate") { decompressStream = new DeflateStream(st, CompressionMode.Decompress); } else { decompressStream = st; } //设置FileStream if (enableResume) //若允许断点续传 { fs = new FileStream(para.FilePath, FileMode.Open, FileAccess.Write, FileShare.Read, 8); fs.Seek(filelength, SeekOrigin.Begin); } else //不允许断点续传 { fs = new FileStream(para.FilePath, FileMode.Create, FileAccess.Write, FileShare.Read, 8); } //打开文件流 using (fs) { //使用缓冲流 bs = new BufferedStream(fs, GlobalSettings.GetSettings().CacheSize * 1024 * 1024); try { //读取第一块数据 Int32 osize = decompressStream.Read(buffer, 0, buffer.Length); //开始循环 while (osize > 0) { #region 判断是否取消下载 //如果用户终止则返回false if (para.IsStop) { //关闭流 bs.Close(); st.Close(); fs.Close(); return(false); } #endregion //增加已完成字节数 para.DoneBytes += osize; //写文件(缓存) bs.Write(buffer, 0, osize); //设置限速 int limit = 0; if (task != null) { if (task.SpeedLimit >= 0) { limit = task.SpeedLimit; } } if (limit > 0) { //下载计数加一count++ limitcount++; //下载1KB osize = decompressStream.Read(buffer, 0, buffer.Length); //累积到limit KB后 if (limitcount >= limit) { t = System.Environment.TickCount - privateTick; //检查是否大于一秒 if (t < 1000) //如果小于一秒则等待至一秒 { Thread.Sleep(1000 - t); } //重置count和计时器,继续下载 limitcount = 0; privateTick = System.Environment.TickCount; } } else //如果不限速 { osize = decompressStream.Read(buffer, 0, buffer.Length); } } //end while //如果下载完成的数据没有到达服务器宣称的长度的90%就报告错误 if (para.TotalLength > 0) { if (para.DoneBytes < (para.TotalLength * 9 / 10)) { throw new Exception("Data downloaded is less than the server announced."); } } //下载成功完成,不需要重新下载 needRedownload = false; } //end bufferedstream catch (Exception ex) { //可重试次数减1 remainRetryTime--; //不再重试直接抛出异常的规则: //1.没有可重试次数 //2.服务器不支持断点续传 if (remainRetryTime < 0 || (!enableResume)) { needRedownload = false; throw ex; } else //否则继续重试 { needRedownload = true; //重试前等待的时间 Thread.Sleep(GlobalSettings.GetSettings().RetryWaitingTime); } } finally { bs.Close(); } } // end filestream } //end netstream } while (needRedownload); //end while(needReDownload) //一切顺利返回true return(true); }
/// <summary> /// 下载视频 /// </summary> public override bool Download() { //开始下载 TipText("正在分析视频地址"); //修正井号 Info.Url = Info.Url.ToLower().TrimEnd('#'); //修正旧版URL Info.Url = Info.Url.Replace("bilibili.tv", "bilibili.com"); Info.Url = Info.Url.Replace("bilibili.us", "bilibili.com"); Info.Url = Info.Url.Replace("bilibili.smgbb.cn", "www.bilibili.com"); Info.Url = Info.Url.Replace("bilibili.kankanews.com", "www.bilibili.com"); //修正简写URL if (Regex.Match(Info.Url, @"^av\d{2,6}$").Success) Info.Url = "http://www.bilibili.com/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\.kankanews\.com(?<part>/video/av\d+/index_\d+\.html)").Groups["part"].Value; string suburl = Regex.Match(Info.Url, @"www\.bilibili\.com(?<part>/video/av\d+/index_\d+\.html)").Groups["part"].Value; //取得AV号和子编号 //Match mAVNumber = Regex.Match(Info.Url, @"(?<av>av\d+)/index_(?<sub>\d+)\.html"); Match mAVNumber = BilibiliPlugin.RegexBili.Match(Info.Url); if (!mAVNumber.Success) mAVNumber = BilibiliPlugin.RegexAcg.Match(Info.Url); Settings["AVNumber"] = mAVNumber.Groups["id"].Value; Settings["AVSubNumber"] = mAVNumber.Groups["page"].Value; Settings["AVSubNumber"] = string.IsNullOrEmpty(Settings["AVSubNumber"]) ? "1" : Settings["AVSubNumber"]; //设置自定义文件名 Settings["CustomFileName"] = BilibiliPlugin.DefaultFileNameFormat; if (Info.BasePlugin.Configuration.ContainsKey("CustomFileName")) { Settings["CustomFileName"] = Info.BasePlugin.Configuration["CustomFileName"]; } //是否通过【自动应答】禁用对话框 bool disableDialog = AutoAnswer.IsInAutoAnswers(Info.AutoAnswer, "bilibili", "auto"); //视频地址数组 string[] videos = null; try { //解析关联项需要同时满足的条件: //1.这个任务不是被其他任务所添加的 //2.用户设置了“解析关联项” if (!Info.IsBeAdded || Info.ParseRelated) { //取得网页源文件 string src = Network.GetHtmlSource(url, Encoding.UTF8, Info.Proxy); string subtitle = ""; //取得子标题 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) { subtitle = item.Groups["content"].Value; break; } } //准备(地址-标题)字典 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) { NewTask(u); } } } //获取视频信息API var ts = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds); var apiAddress = string.Format(@"http://api.bilibili.cn/view?appkey={0}&ts={1}&id={2}&page={3}", BilibiliPlugin.AppKey, ts, Settings["AVNumber"], Settings["AVSubNumber"]); //AcDown所使用的AppKey是旧AppKey,权限比新申请的要高,而且不需要加上sign验证 //如果将来要使用sign验证的话可以使用下面的代码来算出sign //但是这段代码目前加上后还是不能正确工作的状态,不知道为什么 //Tools.GetStringHash("appkey=" + BilibiliPlugin.AppKey + // "&id=" + Settings["AVNumber"] + // "&page=" + Settings["AVSubNumber"] + // "&ts=" + ts + // BilibiliPlugin.AppSecret)); var webrequest = (HttpWebRequest)WebRequest.Create(apiAddress); webrequest.Accept = @"application/json"; webrequest.UserAgent = "AcDown/" + Application.ProductVersion + " ([email protected])"; webrequest.Proxy = Info.Proxy; var viewSrc = Network.GetHtmlSource(webrequest, Encoding.UTF8); //登录获取API结果 if (viewSrc.Contains("no perm error")) { viewSrc = LoginApi(url, apiAddress, out m_cookieContainer); } AvInfo avInfo; try { //解析JSON avInfo = JsonConvert.DeserializeObject<AvInfo>(viewSrc); } catch { //由于接口原因,有时候虽然请求了json但是会返回XML格式(呃 var viewDoc = new XmlDocument(); viewDoc.LoadXml(viewSrc); avInfo = new AvInfo(); avInfo.title = viewDoc.SelectSingleNode(@"/info/title").InnerText.Replace("&", "&"); avInfo.partname = viewDoc.SelectSingleNode(@"/info/partname").InnerText.Replace("&", "&"); avInfo.cid = Regex.Match(viewSrc, @"(?<=\<cid\>)\d+(?=\</cid\>)", RegexOptions.IgnoreCase).Value; } //视频标题和子标题 string title = avInfo.title ?? ""; string stitle = avInfo.partname ?? ""; if (String.IsNullOrEmpty(stitle)) { Info.Title = title; stitle = title; } else Info.Title = title + " - " + stitle; //过滤非法字符 title = Tools.InvalidCharacterFilter(title, ""); stitle = Tools.InvalidCharacterFilter(stitle, ""); //清空地址 Info.FilePath.Clear(); Info.SubFilePath.Clear(); //CID Settings["chatid"] = avInfo.cid; //下载弹幕 DownloadComment(title, stitle, Settings["chatid"]); //解析器的解析结果 ParseResult pr = null; //如果允许下载视频 if ((Info.DownloadTypes & DownloadType.Video) != 0) { //var playurlSrc = Network.GetHtmlSource(@"http://interface.bilibili.tv/playurl?otype=xml&cid=" + Settings["chatid"] + "&type=flv", Encoding.UTF8); //var playurlDoc = new XmlDocument(); //playurlDoc.LoadXml(playurlSrc); //获得视频列表 var prRequest = new ParseRequest() { Id = Settings["chatid"], Proxy = Info.Proxy, AutoAnswers = Info.AutoAnswer, CookieContainer = m_cookieContainer }; pr = new BilibiliInterfaceParser().Parse(prRequest); videos = pr.ToArray(); //支持导出列表 if (videos != null) { StringBuilder sb = new StringBuilder(videos.Length * 2); foreach (string item in videos) { sb.Append(item); sb.Append("|"); } if (Settings.ContainsKey("ExportUrl")) Settings["ExportUrl"] = sb.ToString(); else Settings.Add("ExportUrl", sb.ToString()); } //下载视频 //确定视频共有几个段落 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, stitle, Info.PartCount == 1 ? "" : Info.CurrentPart.ToString(), ext.Replace(".", ""), Settings["AVNumber"], Settings["AVSubNumber"]); filename = Path.Combine(Info.SaveDirectory.ToString(), filename); //生成父文件夹 if (!Directory.Exists(Path.GetDirectoryName(filename))) Directory.CreateDirectory(Path.GetDirectoryName(filename)); //设置当前DownloadParameter currentParameter = new DownloadParameter() { //文件名 例: c:\123(1).flv FilePath = filename, //文件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 //下载文件时出现错误 { //如果此任务由一个视频组成,则报错(下载失败) if (Info.PartCount == 1) { throw; } 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, stitle); //支持AcPlay直接播放 Settings["AcPlay"] = acplay; } //生成视频自动合并参数 if (Info.FilePath.Count > 1 && !Info.PartialFinished) { Info.Settings.Remove("VideoCombine"); var arg = new StringBuilder(); foreach (var item in Info.FilePath) { arg.Append(item); arg.Append("|"); } var renamehelper = new CustomFileNameHelper(); string filename = renamehelper.CombineFileName(Settings["CustomFileName"], title, stitle, "", "mp4", Info.Settings["AVNumber"], Info.Settings["AVSubNumber"]); filename = Path.Combine(Info.SaveDirectory.ToString(), filename); arg.Append(filename); Info.Settings["VideoCombine"] = arg.ToString(); } } catch { Settings["user"] = ""; Settings["password"] = ""; throw; } return true; }