private async Task mergeParts(VideoFragment fragment) { var title = getTitle(fragment); using (var writeStream = File.OpenWrite($"{title}.{fragment.Extension}")) { for (var part = 0; part < Config.Parts; part++) { using (var readStream = File.OpenRead($"{title}.part{part}")) { await readStream.CopyToAsync(writeStream); } } } }
private async Task <VideoDownloadResult> downloadFragment(VideoFragment fragment) { var partialLength = fragment.Size / Config.Parts + 1; var title = getTitle(fragment); var filename = title + fragment.Extension; if (File.Exists(filename)) { return(VideoDownloadResult.Skipped); } var startByte = 0; var part = 0; while (startByte < fragment.Size) { var partFilename = $"{title}.part{part}"; if (!File.Exists(partFilename)) { var endByte = Math.Min(fragment.Size, startByte + partialLength) - 1; var range = $"bytes={startByte}-{endByte}"; var client = new HttpClient(); client.DefaultRequestHeaders.Range = new RangeHeaderValue(startByte, endByte); client.DefaultRequestHeaders.Referrer = new Uri("https://www.bilibili.com", UriKind.Absolute); client.DefaultRequestHeaders.Add("Origin", "https://www.bilibili.com"); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"); //client.Headers[HttpRequestHeader.Range] = range; //client.Headers[HttpRequestHeader.Referer] = "https://www.bilibili.com"; //client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"; //client.Headers["Origin"] = "https://www.bilibili.com"; Task task = null; try { task = Task.Run(async() => { using (var response = await client.GetStreamAsync(fragment.Url)) using (var file = File.OpenWrite(partFilename)) { while (response.CanRead) { file.WriteByte((byte)response.ReadByte()); taskMap[task]++; updateProgress(); } } }); //task = client.DownloadFileTaskAsync(fragment.Url, partFilename); //client.DownloadProgressChanged += (s, e) => //{ // taskMap[task] = e.BytesReceived; //}; taskMap.Add(task, 0L); } catch (Exception ex) when(ex is WebException || ex is InvalidOperationException) { // TODO: handle web errors return(VideoDownloadResult.Failed); } } part++; startByte = startByte + partialLength; } Downloading = true; await Task.WhenAll(taskMap.Select(it => it.Key)); Downloading = false; return(VideoDownloadResult.Success); }
private string getTitle(VideoFragment fragment) { return(Video.Fragments.Length == 1 ? Video.Title : $"{Video.Title} - {Array.IndexOf(Video.Fragments, fragment) + 1}"); }