예제 #1
0
        public static async Task DownloadFile(string url, string path, bool aria2c)
        {
            LogDebug("Start downloading: {0}", url);
            if (aria2c)
            {
                BBDownAria2c.DownloadFileByAria2c(url, path);
                if (File.Exists(path + ".aria2") || !File.Exists(path))
                {
                    throw new Exception("aria2下载可能存在错误");
                }
                Console.WriteLine();
                return;
            }
            string tmpName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path) + ".tmp");

            using (var progress = new ProgressBar())
            {
                long      totalLength = -1;
                WebClient client      = new WebClient();
                if (!url.Contains("platform=android_tv_yst"))
                {
                    client.Headers.Add("Referer", "https://www.bilibili.com");
                }
                client.Headers.Add("User-Agent", "Mozilla/5.0");
                client.Headers.Add("Cookie", Program.COOKIE);
                client.Credentials = CredentialCache.DefaultCredentials;
                Uri uri = new Uri(url);
                client.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e)
                {
                    if (totalLength == -1)
                    {
                        totalLength = e.TotalBytesToReceive;
                    }
                    progress.Report((double)e.BytesReceived / e.TotalBytesToReceive);
                };
                await client.DownloadFileTaskAsync(uri, tmpName);

                if (new FileInfo(tmpName).Length == totalLength)
                {
                    File.Move(tmpName, path, true);
                }
                else
                {
                    throw new Exception("文件下载可能不完整, 请重新下载");
                }
            }
        }
예제 #2
0
        public static async Task DownloadFile(string url, string path, bool aria2c, string aria2cProxy, bool forceHttp = false)
        {
            if (forceHttp)
            {
                url = ReplaceUrl(url);
            }
            LogDebug("Start downloading: {0}", url);
            if (!Directory.Exists(Path.GetDirectoryName(Path.GetFullPath(path))))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
            }
            if (aria2c)
            {
                await BBDownAria2c.DownloadFileByAria2cAsync(url, path, aria2cProxy);

                if (File.Exists(path + ".aria2") || !File.Exists(path))
                {
                    throw new Exception("aria2下载可能存在错误");
                }
                Console.WriteLine();
                return;
            }
            int    retry   = 0;
            string tmpName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path) + ".tmp");

reDown:
            try
            {
                using (var progress = new ProgressBar())
                {
                    await RangeDownloadToTmpAsync(0, url, tmpName, 0, null, (_, downloaded, total) => progress.Report((double)downloaded / total));

                    File.Move(tmpName, path, true);
                }
            }
            catch (Exception)
            {
                if (++retry == 3)
                {
                    throw;
                }
                goto reDown;
            }
        }
예제 #3
0
        public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c)
        {
            if (aria2c)
            {
                BBDownAria2c.DownloadFileByAria2c(url, path);
                if (File.Exists(path + ".aria2") || !File.Exists(path))
                {
                    throw new Exception("aria2下载可能存在错误");
                }
                Console.WriteLine();
                return;
            }
            long fileSize = GetFileSize(url);

            LogDebug("文件大小:{0} bytes", fileSize);
            List <Clip> allClips = GetAllClips(url, fileSize);
            int         total    = allClips.Count;

            LogDebug("分段数量:{0}", total);
            long done = 0;

            using (var progress = new ProgressBar())
            {
                progress.Report(0);
                await RunWithMaxDegreeOfConcurrency(8, allClips, async clip =>
                {
                    string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip"));
                    if (!(File.Exists(tmp) && new FileInfo(tmp).Length == clip.to - clip.from + 1))
                    {
reDown:
                        try
                        {
                            using (var client = new HttpClient())
                            {
                                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
                                client.DefaultRequestHeaders.Add("Cookie", Program.COOKIE);
                                if (clip.to != -1)
                                {
                                    client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-{clip.to}");
                                }
                                else
                                {
                                    client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-");
                                }
                                if (!url.Contains("platform=android_tv_yst"))
                                {
                                    client.DefaultRequestHeaders.Referrer = new Uri("https://www.bilibili.com");
                                }

                                var response = await client.GetAsync(url);

                                using (var stream = await response.Content.ReadAsStreamAsync())
                                {
                                    using (var fileStream = new FileStream(tmp, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
                                    {
                                        var buffer = new byte[8192];
                                        int bytesRead;
                                        while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                        {
                                            await fileStream.WriteAsync(buffer, 0, bytesRead);
                                            done += bytesRead;
                                            progress.Report((double)done / fileSize);
                                        }
                                        //await stream.CopyToAsync(fileStream);
                                    }
                                }
                            }
                        }
                        catch { goto reDown; }
                    }
                    else
                    {
                        done += new FileInfo(tmp).Length;
                        progress.Report((double)done / fileSize);
                    }
                });
            }
        }
예제 #4
0
        public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c)
        {
            if (aria2c)
            {
                BBDownAria2c.DownloadFileByAria2c(url, path);
                if (File.Exists(path + ".aria2") || !File.Exists(path))
                {
                    throw new Exception("aria2下载可能存在错误");
                }
                Console.WriteLine();
                return;
            }
            long fileSize = GetFileSize(url);

            LogDebug("文件大小:{0} bytes", fileSize);
            List <Clip> allClips = GetAllClips(url, fileSize);
            int         total    = allClips.Count;

            LogDebug("分段数量:{0}", total);
            long done = 0;

            using (var progress = new ProgressBar())
            {
                progress.Report(0);
                await RunWithMaxDegreeOfConcurrency(8, allClips, async clip =>
                {
                    string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip"));
                    if (!(File.Exists(tmp) && new FileInfo(tmp).Length == clip.to - clip.from + 1))
                    {
reDown:
                        try
                        {
                            using (var client = new HttpClient())
                            {
                                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
                                client.DefaultRequestHeaders.Add("Cookie", Program.COOKIE);
                                if (clip.to != -1)
                                {
                                    client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-{clip.to}");
                                }
                                else
                                {
                                    client.DefaultRequestHeaders.Add("Range", $"bytes={clip.from}-");
                                }
                                if (!url.Contains("platform=android_tv_yst"))
                                {
                                    client.DefaultRequestHeaders.Referrer = new Uri("https://www.bilibili.com");
                                }

                                var response = await client.GetAsync(url);

                                using (var stream = await response.Content.ReadAsStreamAsync())
                                {
                                    using (var fileStream = new FileStream(tmp, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
                                    {
                                        var buffer = new byte[8192];
                                        int bytesRead;
                                        while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                        {
                                            await fileStream.WriteAsync(buffer, 0, bytesRead);
                                            done += bytesRead;
                                            progress.Report((double)done / fileSize);
                                        }
                                        //await stream.CopyToAsync(fileStream);
                                    }
                                }
                            }
                        }
                        catch { goto reDown; }
                    }
                    else
                    {
                        done += new FileInfo(tmp).Length;
                        progress.Report((double)done / fileSize);
                    }
                });

                /*//多线程设置
                 * ParallelOptions parallelOptions = new ParallelOptions
                 * {
                 *  MaxDegreeOfParallelism = 8
                 * };
                 * Parallel.ForEach(allClips, parallelOptions, async clip =>
                 * {
                 *  string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip"));
                 *  if (!(File.Exists(tmp) && new FileInfo(tmp).Length == clip.to - clip.from + 1))
                 *  {
                 *  reDown:
                 *      try
                 *      {
                 *//*HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                 *          request.Timeout = 30000;
                 *          request.ReadWriteTimeout = 30000; //重要
                 *          request.AllowAutoRedirect = true;
                 *          request.KeepAlive = false;
                 *          request.Method = "GET";
                 *          if (!url.Contains("platform=android_tv_yst"))
                 *              request.Referer = "https://www.bilibili.com";
                 *          request.UserAgent = "Mozilla/5.0";
                 *          request.Headers.Add("Cookie", Program.COOKIE);
                 *          if (clip.to != -1)
                 *              request.AddRange("bytes", clip.from, clip.to);
                 *          else
                 *              request.AddRange("bytes", clip.from);
                 *          using (var response = (HttpWebResponse)request.GetResponse())
                 *          {
                 *              using (var responseStream = response.GetResponseStream())
                 *              {
                 *                  using (var stream = new FileStream(tmp, FileMode.Create, FileAccess.Write, FileShare.Write))
                 *                  {
                 *                      byte[] bArr = new byte[1024];
                 *                      int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                 *                      while (size > 0)
                 *                      {
                 *                          stream.Write(bArr, 0, size);
                 *                          done += size;
                 *                          progress.Report((double)done / fileSize);
                 *                          size = responseStream.Read(bArr, 0, (int)bArr.Length);
                 *                      }
                 *                  }
                 *              }
                 *          }*//*
                 *      }
                 *      catch { goto reDown; }
                 *  }
                 *  else
                 *  {
                 *      done += new FileInfo(tmp).Length;
                 *      progress.Report((double)done / fileSize);
                 *  }
                 * });*/
            }
        }
예제 #5
0
        public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c, string aria2cProxy, bool forceHttp = false)
        {
            if (forceHttp)
            {
                url = ReplaceUrl(url);
            }
            LogDebug("Start downloading: {0}", url);
            if (aria2c)
            {
                await BBDownAria2c.DownloadFileByAria2cAsync(url, path, aria2cProxy);

                if (File.Exists(path + ".aria2") || !File.Exists(path))
                {
                    throw new Exception("aria2下载可能存在错误");
                }
                Console.WriteLine();
                return;
            }
            long fileSize = await GetFileSizeAsync(url);

            LogDebug("文件大小:{0} bytes", fileSize);
            //已下载过, 跳过下载
            if (File.Exists(path) && new FileInfo(path).Length == fileSize)
            {
                LogDebug("文件已下载过, 跳过下载");
                return;
            }
            List <Clip> allClips = GetAllClips(url, fileSize);
            int         total    = allClips.Count;

            LogDebug("分段数量:{0}", total);
            ConcurrentDictionary <int, long> clipProgress = new();

            foreach (var i in allClips)
            {
                clipProgress[i.index] = 0;
            }

            using (var progress = new ProgressBar())
            {
                progress.Report(0);
                await Parallel.ForEachAsync(allClips, async (clip, _) =>
                {
                    int retry  = 0;
                    string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip"));
reDown:
                    try
                    {
                        await RangeDownloadToTmpAsync(clip.index, url, tmp, clip.from, clip.to == -1 ? null : clip.to, (index, downloaded, _) =>
                        {
                            clipProgress[index] = downloaded;
                            progress.Report((double)clipProgress.Values.Sum() / fileSize);
                        }, true);
                    }
                    catch (NotSupportedException)
                    {
                        if (++retry == 3)
                        {
                            throw new Exception($"服务器可能并不支持多线程下载,请使用 --multi-thread false 关闭多线程");
                        }
                        goto reDown;
                    }
                    catch (Exception)
                    {
                        if (++retry == 3)
                        {
                            throw new Exception($"Failed to download clip {clip.index}");
                        }
                        goto reDown;
                    }
                });
            }
        }