完成内建下载器

croire 3 years ago
parent 6e6e17e10a
commit c7e4719152

@ -385,10 +385,34 @@ namespace DownKyi.Core.Downloader
/// <summary>
/// 开始下载
/// </summary>
public void Start()
public void StartAsync()
{
//Task th = new Task(CreateFirstPartitions);
//th.Start();
StartAsync(false);
}
/// <summary>
/// 开始下载
/// </summary>
/// <param name="isWait"></param>
public void StartAsync(bool isWait)
{
Task th = new Task(CreateFirstPartitions);
th.Start();
if (isWait)
{
th.Wait();
}
}
/// <summary>
/// 开始下载
/// </summary>
public void Start()
{
CreateFirstPartitions();
}
/// <summary>

@ -122,7 +122,8 @@ namespace DownKyi
});
// 启动下载服务
downloadService = new AriaDownloadService(DownloadingList, DownloadedList);
//downloadService = new AriaDownloadService(DownloadingList, DownloadedList);
downloadService = new BuiltinDownloadService(DownloadingList, DownloadedList);
downloadService.Start();
return Container.Resolve<MainWindow>();

@ -218,6 +218,7 @@ namespace DownKyi.Services.Download
/// 强制暂停
/// </summary>
/// <param name="downloading"></param>
/// <exception cref="OperationCanceledException"></exception>
protected override void Pause(DownloadingItem downloading)
{
cancellationToken.ThrowIfCancellationRequested();
@ -422,6 +423,7 @@ namespace DownKyi.Services.Download
if (video == null) { return; }
// 下载进度百分比
float percent = 0;
if (totalLength != 0)
{

@ -1,10 +1,16 @@
using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Core.BiliApi.Login;
using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Core.Downloader;
using DownKyi.Core.Utils;
using DownKyi.Models;
using DownKyi.Utils;
using DownKyi.ViewModels.DownloadManager;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace DownKyi.Services.Download
@ -50,8 +56,68 @@ namespace DownKyi.Services.Download
/// <returns></returns>
private string DownloadVideo(DownloadingItem downloading, PlayUrlDashVideo downloadVideo)
{
// 如果为空,说明没有匹配到可下载的音频视频
if (downloadVideo == null) { return null; }
return null;
// 下载链接
List<string> urls = new List<string>();
if (downloadVideo.BaseUrl != null) { urls.Add(downloadVideo.BaseUrl); }
if (downloadVideo.BackupUrl != null) { urls.AddRange(downloadVideo.BackupUrl); }
// 路径
downloading.DownloadBase.FilePath = downloading.DownloadBase.FilePath.Replace("\\", "/");
string[] temp = downloading.DownloadBase.FilePath.Split('/');
//string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], "");
string path = downloading.DownloadBase.FilePath.TrimEnd(temp[temp.Length - 1].ToCharArray());
// 下载文件名
string fileName = Guid.NewGuid().ToString("N");
string key = $"{downloadVideo.Id}_{downloadVideo.Codecs}";
// 老版本数据库没有这一项会变成null
if (downloading.Downloading.DownloadedFiles == null)
{
downloading.Downloading.DownloadedFiles = new List<string>();
}
if (downloading.Downloading.DownloadFiles.ContainsKey(key))
{
// 如果存在,表示下载过,
// 则继续使用上次下载的文件名
fileName = downloading.Downloading.DownloadFiles[key];
// 还要检查一下文件有没有被人删掉,删掉的话重新下载
// 如果下载视频之后音频文件被人删了。此时gid还是视频的会下错文件
if (downloading.Downloading.DownloadedFiles.Contains(key) && File.Exists(Path.Combine(path, fileName)))
{
return Path.Combine(path, fileName);
}
}
else
{
// 记录本次下载的文件
try
{
downloading.Downloading.DownloadFiles.Add(key, fileName);
}
catch (ArgumentException) { }
// Gid最好能是每个文件单独存储现在复用有可能会混
// 不过好消息是下载是按固定顺序的,而且下载了两个音频会混流不过
downloading.Downloading.Gid = null;
}
// 开始下载
var downloadStatus = DownloadByBuiltin(downloading, urls, path, fileName);
if (downloadStatus)
{
downloading.Downloading.DownloadedFiles.Add(key);
downloading.Downloading.Gid = null;
return Path.Combine(path, fileName);
}
else
{
return nullMark;
}
}
#endregion
@ -136,6 +202,7 @@ namespace DownKyi.Services.Download
/// 强制暂停
/// </summary>
/// <param name="downloading"></param>
/// <exception cref="OperationCanceledException"></exception>
protected override void Pause(DownloadingItem downloading)
{
cancellationToken.ThrowIfCancellationRequested();
@ -173,7 +240,104 @@ namespace DownKyi.Services.Download
#region 内建下载器
/// <summary>
/// 下载文件
/// </summary>
/// <param name="downloading"></param>
/// <param name="urls"></param>
/// <param name="path"></param>
/// <param name="localFileName"></param>
/// <returns></returns>
private bool DownloadByBuiltin(DownloadingItem downloading, List<string> urls, string path, string localFileName)
{
// path已斜杠结尾去掉斜杠
path = path.TrimEnd('/').TrimEnd('\\');
foreach (var url in urls)
{
// 创建下载器
// 配置网络请求
var mtd = new MultiThreadDownloader(url, Environment.GetEnvironmentVariable("temp"), Path.Combine(path, localFileName), 8);
mtd.Configure(req =>
{
req.CookieContainer = LoginHelper.GetLoginInfoCookies();
req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36";
req.Referer = "https://www.bilibili.com";
req.Headers.Add("Origin", "https://www.bilibili.com");
if (false)
{
// TODO
req.Proxy = new WebProxy("127.0.0.1", 1080);
}
});
// 下载进度回调
mtd.TotalProgressChanged += (sender, e) =>
{
// 状态更新
var downloader = sender as MultiThreadDownloader;
// 下载进度百分比
float percent = downloader.TotalProgress;
// 根据进度判断本次是否需要更新UI
if (Math.Abs(percent - downloading.Progress) < 0.01) { return; }
if (Math.Abs(percent - downloading.Progress) > 5) { return; }
// 下载进度
downloading.Progress = percent;
// 下载大小
downloading.DownloadingFileSize = Format.FormatFileSize(downloader.TotalBytesReceived) + "/" + Format.FormatFileSize(downloader.Size);
// 下载速度
long speed = (long)downloader.TotalSpeedInBytes;
// 下载速度显示
downloading.SpeedDisplay = Format.FormatSpeed(speed);
// 最大下载速度
if (downloading.Downloading.MaxSpeed < speed)
{
downloading.Downloading.MaxSpeed = speed;
}
};
// 文件合并完成回调
bool isComplete = false;
mtd.FileMergedComplete += (sender, e) =>
{
// 跳出循环
if (File.Exists(Path.Combine(path, localFileName))) { isComplete = true; }
};
// 开始下载
mtd.StartAsync();
// 阻塞当前任务,监听暂停事件
while (!isComplete)
{
cancellationToken.ThrowIfCancellationRequested();
switch (downloading.Downloading.DownloadStatus)
{
case DownloadStatus.PAUSE:
// 暂停下载
mtd.Pause();
// 通知UI并阻塞当前线程
Pause(downloading);
break;
case DownloadStatus.DOWNLOADING:
break;
}
Thread.Sleep(100);
}
return isComplete;
}
return false;
}
#endregion

@ -50,6 +50,11 @@ namespace DownKyi.Services.Download
// 更新状态显示
downloading.DownloadStatusTitle = DictionaryResource.GetString("WhileDownloading");
downloading.DownloadContent = DictionaryResource.GetString("DownloadingAudio");
// 下载大小
downloading.DownloadingFileSize = string.Empty;
downloading.Progress = 0;
// 下载速度
downloading.SpeedDisplay = string.Empty;
// 如果没有Dash返回null
if (downloading.PlayUrl == null || downloading.PlayUrl.Dash == null) { return null; }
@ -88,6 +93,11 @@ namespace DownKyi.Services.Download
// 更新状态显示
downloading.DownloadStatusTitle = DictionaryResource.GetString("WhileDownloading");
downloading.DownloadContent = DictionaryResource.GetString("DownloadingVideo");
// 下载大小
downloading.DownloadingFileSize = string.Empty;
downloading.Progress = 0;
// 下载速度
downloading.SpeedDisplay = string.Empty;
// 如果没有Dash返回null
if (downloading.PlayUrl == null || downloading.PlayUrl.Dash == null) { return null; }
@ -293,6 +303,7 @@ namespace DownKyi.Services.Download
downloading.DownloadContent = string.Empty;
// 下载大小
downloading.DownloadingFileSize = string.Empty;
downloading.Progress = 0;
// 下载速度
downloading.SpeedDisplay = string.Empty;
@ -634,8 +645,10 @@ namespace DownKyi.Services.Download
}));
}));
}
catch (OperationCanceledException)
catch (OperationCanceledException e)
{
Core.Utils.Debugging.Console.PrintLine(Tag, e.ToString());
LogManager.Debug(Tag, e.Message);
}
}
@ -649,6 +662,7 @@ namespace DownKyi.Services.Download
downloading.DownloadContent = string.Empty;
downloading.DownloadingFileSize = string.Empty;
downloading.SpeedDisplay = string.Empty;
downloading.Progress = 0;
downloading.Downloading.DownloadStatus = DownloadStatus.DOWNLOAD_FAILED;
downloading.StartOrPause = ButtonIcon.Instance().Retry;

Loading…
Cancel
Save