diff --git a/DownKyi.Core.Test/Database/BinaryTest.cs b/DownKyi.Core.Test/Database/BinaryTest.cs new file mode 100644 index 0000000..33bfdd0 --- /dev/null +++ b/DownKyi.Core.Test/Database/BinaryTest.cs @@ -0,0 +1,30 @@ +using DownKyi.Core.BiliApi.VideoStream; +using DownKyi.Core.Storage.Database.Download; +using DownKyi.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DownKyi.Core.Test.Database +{ + [TestClass] + public class BinaryTest + { + [TestMethod] + public void TestMethod1() + { + Downloading downloading = new Downloading + { + Gid = "gid", + PlayStreamType = PlayStreamType.VIDEO, + DownloadContent = "视频", + DownloadStatusTitle = "下载中", + Progress = 50, + DownloadingFileSize = "60MB/120MB", + MaxSpeed = 123456, + SpeedDisplay = "5MB/s", + }; + + DownloadingDb db = new DownloadingDb(); + db.Insert("testId", downloading); + } + } +} diff --git a/DownKyi.Core.Test/DownKyi.Core.Test.csproj b/DownKyi.Core.Test/DownKyi.Core.Test.csproj index 71fb1f9..85a7801 100644 --- a/DownKyi.Core.Test/DownKyi.Core.Test.csproj +++ b/DownKyi.Core.Test/DownKyi.Core.Test.csproj @@ -1,6 +1,6 @@  - + Debug @@ -40,22 +40,27 @@ - ..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + ..\packages\MSTest.TestFramework.2.2.8\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - ..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + ..\packages\MSTest.TestFramework.2.2.8\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\System.Data.SQLite.Core.1.0.112.2\lib\net40\System.Data.SQLite.dll + + @@ -72,6 +77,10 @@ {4fde0364-f65b-4812-bfe8-34e886624fbd} DownKyi.Core + + {97075FCD-6E8F-4FF9-B73A-994197F3765A} + DownKyi + @@ -79,8 +88,10 @@ 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - + + + - + + \ No newline at end of file diff --git a/DownKyi.Core.Test/packages.config b/DownKyi.Core.Test/packages.config index 5cc7691..82bdd21 100644 --- a/DownKyi.Core.Test/packages.config +++ b/DownKyi.Core.Test/packages.config @@ -1,6 +1,7 @@  - - + + + \ No newline at end of file diff --git a/DownKyi.Core/Aria2cNet/Server/AriaServer.cs b/DownKyi.Core/Aria2cNet/Server/AriaServer.cs index 6089865..c78853d 100644 --- a/DownKyi.Core/Aria2cNet/Server/AriaServer.cs +++ b/DownKyi.Core/Aria2cNet/Server/AriaServer.cs @@ -28,14 +28,16 @@ namespace DownKyi.Core.Aria2cNet.Server ListenPort = config.ListenPort; // aria目录 string ariaDir = Environment.CurrentDirectory + "\\aria\\"; + //string ariaDir = StorageManager.GetAriaDir(); // 会话文件 #if DEBUG - string sessionFile = ariaDir + "aira.session"; + string sessionFile = Path.Combine(ariaDir, "aira.session"); + #else - string sessionFile = ariaDir + "aira.session.gz"; + string sessionFile =Path.Combine(ariaDir, "aira.session.gz"); #endif // 日志文件 - string logFile = ariaDir + "aira.log"; + string logFile = Path.Combine(ariaDir, "aira.log"); // 自动保存会话文件的时间间隔 int saveSessionInterval = 30; diff --git a/DownKyi/Models/PlayStreamType.cs b/DownKyi.Core/BiliApi/VideoStream/PlayStreamType.cs similarity index 78% rename from DownKyi/Models/PlayStreamType.cs rename to DownKyi.Core/BiliApi/VideoStream/PlayStreamType.cs index 959d7b0..e54edbb 100644 --- a/DownKyi/Models/PlayStreamType.cs +++ b/DownKyi.Core/BiliApi/VideoStream/PlayStreamType.cs @@ -1,4 +1,4 @@ -namespace DownKyi.Models +namespace DownKyi.Core.BiliApi.VideoStream { public enum PlayStreamType { diff --git a/DownKyi.Core/DownKyi.Core.csproj b/DownKyi.Core/DownKyi.Core.csproj index 7e57e38..52019d0 100644 --- a/DownKyi.Core/DownKyi.Core.csproj +++ b/DownKyi.Core/DownKyi.Core.csproj @@ -174,6 +174,7 @@ + @@ -239,6 +240,10 @@ + + + + diff --git a/DownKyi.Core/Storage/Constant.cs b/DownKyi.Core/Storage/Constant.cs index 2fe9aa4..633ece9 100644 --- a/DownKyi.Core/Storage/Constant.cs +++ b/DownKyi.Core/Storage/Constant.cs @@ -10,6 +10,9 @@ namespace DownKyi.Core.Storage // 根目录 private static string Root { get; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/Downkyi"; + // Aria + public static string Aria { get; } = $"{Root}/Aria"; + // 日志 public static string Logs { get; } = $"{Root}/Logs"; @@ -17,6 +20,7 @@ namespace DownKyi.Core.Storage public static string Database { get; } = $"{Root}/Storage"; // 历史(搜索、下载) (加密) + public static string Download { get; } = $"{Database}/Download.db"; public static string History { get; } = $"{Database}/History.db"; // 配置 diff --git a/DownKyi.Core/Storage/Database/CoverDb.cs b/DownKyi.Core/Storage/Database/CoverDb.cs index 15ba8ea..5852275 100644 --- a/DownKyi.Core/Storage/Database/CoverDb.cs +++ b/DownKyi.Core/Storage/Database/CoverDb.cs @@ -8,6 +8,7 @@ namespace DownKyi.Core.Storage.Database { private const string key = "b5018ecc-09d1-4da2-aa49-4625e41e623e"; private readonly DbHelper dbHelper = new DbHelper(StorageManager.GetCoverIndex(), key); + private readonly string tableName = "cover"; public CoverDb() { @@ -30,7 +31,7 @@ namespace DownKyi.Core.Storage.Database { try { - string sql = $"insert into cover values ({cover.Avid}, '{cover.Bvid}', {cover.Cid}, '{cover.Url}', '{cover.Md5}')"; + string sql = $"insert into {tableName} values ({cover.Avid}, '{cover.Bvid}', {cover.Cid}, '{cover.Url}', '{cover.Md5}')"; dbHelper.ExecuteNonQuery(sql); } catch (Exception e) @@ -48,7 +49,7 @@ namespace DownKyi.Core.Storage.Database { try { - string sql = $"update cover set avid={cover.Avid}, bvid='{cover.Bvid}', cid={cover.Cid}, md5='{cover.Md5}' where url glob '{cover.Url}'"; + string sql = $"update {tableName} set avid={cover.Avid}, bvid='{cover.Bvid}', cid={cover.Cid}, md5='{cover.Md5}' where url glob '{cover.Url}'"; dbHelper.ExecuteNonQuery(sql); } catch (Exception e) @@ -65,7 +66,7 @@ namespace DownKyi.Core.Storage.Database /// public List QueryAll() { - string sql = $"select * from cover"; + string sql = $"select * from {tableName}"; return Query(sql); } @@ -76,17 +77,10 @@ namespace DownKyi.Core.Storage.Database /// public Cover QueryByUrl(string url) { - string sql = $"select * from cover where url glob '{url}'"; - var query = Query(sql); + string sql = $"select * from {tableName} where url glob '{url}'"; + List query = Query(sql); - if (query.Count > 0) - { - return query[0]; - } - else - { - return null; - } + return query.Count > 0 ? query[0] : null; } /// @@ -96,7 +90,7 @@ namespace DownKyi.Core.Storage.Database /// public Cover QueryByMd5(string md5) { - string sql = $"select * from cover where md5 glob '{md5}'"; + string sql = $"select * from {tableName} where md5 glob '{md5}'"; var query = Query(sql); if (query.Count > 0) @@ -141,7 +135,7 @@ namespace DownKyi.Core.Storage.Database /// private void CreateTable() { - string sql = "create table if not exists cover (avid unsigned big int, bvid varchar(20), cid unsigned big int, url varchar(255) unique, md5 varchar(32) unique)"; + string sql = $"create table if not exists {tableName} (avid unsigned big int, bvid varchar(20), cid unsigned big int, url varchar(255) unique, md5 varchar(32) unique)"; dbHelper.ExecuteNonQuery(sql); } diff --git a/DownKyi.Core/Storage/Database/DbHelper.cs b/DownKyi.Core/Storage/Database/DbHelper.cs index d2c67af..8b6db35 100644 --- a/DownKyi.Core/Storage/Database/DbHelper.cs +++ b/DownKyi.Core/Storage/Database/DbHelper.cs @@ -64,7 +64,7 @@ namespace DownKyi.Core.Storage.Database /// 执行一条SQL语句 /// /// - public void ExecuteNonQuery(string sql) + public void ExecuteNonQuery(string sql, Action action = null) { lock (conn) { @@ -74,6 +74,8 @@ namespace DownKyi.Core.Storage.Database using (var command = conn.CreateCommand()) { command.CommandText = sql; + // 添加参数 + action?.Invoke(command.Parameters); command.ExecuteNonQuery(); } tr.Commit(); diff --git a/DownKyi.Core/Storage/Database/Download/DownloadBaseDb.cs b/DownKyi.Core/Storage/Database/Download/DownloadBaseDb.cs new file mode 100644 index 0000000..2d56986 --- /dev/null +++ b/DownKyi.Core/Storage/Database/Download/DownloadBaseDb.cs @@ -0,0 +1,11 @@ +namespace DownKyi.Core.Storage.Database.Download +{ + public class DownloadBaseDb : DownloadDb + { + public DownloadBaseDb() + { + tableName = "download_base"; + CreateTable(); + } + } +} diff --git a/DownKyi.Core/Storage/Database/Download/DownloadDb.cs b/DownKyi.Core/Storage/Database/Download/DownloadDb.cs new file mode 100644 index 0000000..e39a658 --- /dev/null +++ b/DownKyi.Core/Storage/Database/Download/DownloadDb.cs @@ -0,0 +1,99 @@ +using DownKyi.Core.Logging; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SQLite; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace DownKyi.Core.Storage.Database.Download +{ + public class DownloadDb + { + private const string key = "bdb8eb69-3698-4af9-b722-9312d0fba623"; + private readonly DbHelper dbHelper = new DbHelper(StorageManager.GetDownload()); + //private readonly DbHelper dbHelper = new DbHelper(StorageManager.GetDownload(), key); + protected string tableName = "download"; + + //public DownloadDb() + //{ + // CreateTable(); + //} + + /// + /// 关闭数据库连接 + /// + public void Close() + { + dbHelper.Close(); + } + + /// + /// 插入新的数据 + /// + /// + public void Insert(string uuid, object obj) + { + // 定义一个流 + Stream stream = new MemoryStream(); + // 定义一个格式化器 + BinaryFormatter formatter = new BinaryFormatter(); + // 序列化 + formatter.Serialize(stream, obj); + + byte[] array = null; + array = new byte[stream.Length]; + + //将二进制流写入数组 + stream.Position = 0; + stream.Read(array, 0, (int)stream.Length); + + //关闭流 + stream.Close(); + + try + { + string sql = $"insert into {tableName}(id, data) values (@id, @data)"; + dbHelper.ExecuteNonQuery(sql, new Action((para) => + { + para.Add("@id", DbType.String).Value = uuid; + para.Add("@data", DbType.Binary).Value = array; + })); + } + catch (Exception e) + { + Utils.Debugging.Console.PrintLine("Insert()发生异常: {0}", e); + LogManager.Error("DownloadingDb", e); + } + } + + /// + /// 查询所有数据 + /// + /// + /// + public Dictionary QueryAll(string sql) + { + Dictionary objects = new Dictionary(); + + dbHelper.ExecuteQuery(sql, reader => + { + while (reader.Read()) + { + objects.Add((string)reader["id"], reader["data"]); + } + }); + return objects; + } + + + /// + /// 如果表不存在则创建表 + /// + protected void CreateTable() + { + string sql = $"create table if not exists {tableName} (id varchar(255), data blob)"; + dbHelper.ExecuteNonQuery(sql); + } + } +} diff --git a/DownKyi.Core/Storage/Database/Download/DownloadedDb.cs b/DownKyi.Core/Storage/Database/Download/DownloadedDb.cs new file mode 100644 index 0000000..7f69652 --- /dev/null +++ b/DownKyi.Core/Storage/Database/Download/DownloadedDb.cs @@ -0,0 +1,11 @@ +namespace DownKyi.Core.Storage.Database.Download +{ + public class DownloadedDb : DownloadDb + { + public DownloadedDb() + { + tableName = "downloaded"; + CreateTable(); + } + } +} diff --git a/DownKyi.Core/Storage/Database/Download/DownloadingDb.cs b/DownKyi.Core/Storage/Database/Download/DownloadingDb.cs new file mode 100644 index 0000000..8569318 --- /dev/null +++ b/DownKyi.Core/Storage/Database/Download/DownloadingDb.cs @@ -0,0 +1,11 @@ +namespace DownKyi.Core.Storage.Database.Download +{ + public class DownloadingDb : DownloadDb + { + public DownloadingDb() + { + tableName = "downloading"; + CreateTable(); + } + } +} diff --git a/DownKyi.Core/Storage/Database/HeaderDb.cs b/DownKyi.Core/Storage/Database/HeaderDb.cs index 67d3d06..6fe2645 100644 --- a/DownKyi.Core/Storage/Database/HeaderDb.cs +++ b/DownKyi.Core/Storage/Database/HeaderDb.cs @@ -8,6 +8,7 @@ namespace DownKyi.Core.Storage.Database { private const string key = "7c1f1f40-7cdf-4d11-ad28-f0137a3c5308"; private readonly DbHelper dbHelper = new DbHelper(StorageManager.GetHeaderIndex(), key); + private readonly string tableName = "header"; public HeaderDb() { @@ -30,7 +31,7 @@ namespace DownKyi.Core.Storage.Database { try { - string sql = $"insert into header values ({header.Mid}, '{header.Name}', '{header.Url}', '{header.Md5}')"; + string sql = $"insert into {tableName} values ({header.Mid}, '{header.Name}', '{header.Url}', '{header.Md5}')"; dbHelper.ExecuteNonQuery(sql); } catch (Exception e) @@ -48,7 +49,7 @@ namespace DownKyi.Core.Storage.Database { try { - string sql = $"update header set name='{header.Name}', url='{header.Url}', md5='{header.Md5}' where mid={header.Mid}"; + string sql = $"update {tableName} set name='{header.Name}', url='{header.Url}', md5='{header.Md5}' where mid={header.Mid}"; dbHelper.ExecuteNonQuery(sql); } catch (Exception e) @@ -64,7 +65,7 @@ namespace DownKyi.Core.Storage.Database /// public List
QueryAll() { - string sql = $"select * from header"; + string sql = $"select * from {tableName}"; return Query(sql); } @@ -75,17 +76,10 @@ namespace DownKyi.Core.Storage.Database /// public Header QueryByMid(long mid) { - string sql = $"select * from header where mid={mid}"; - var query = Query(sql); + string sql = $"select * from {tableName} where mid={mid}"; + List
query = Query(sql); - if (query.Count > 0) - { - return query[0]; - } - else - { - return null; - } + return query.Count > 0 ? query[0] : null; } @@ -120,7 +114,7 @@ namespace DownKyi.Core.Storage.Database /// private void CreateTable() { - string sql = "create table if not exists header (mid unsigned big int unique, name varchar(255), url varchar(255), md5 varchar(32))"; + string sql = $"create table if not exists {tableName} (mid unsigned big int unique, name varchar(255), url varchar(255), md5 varchar(32))"; dbHelper.ExecuteNonQuery(sql); } diff --git a/DownKyi.Core/Storage/StorageManager.cs b/DownKyi.Core/Storage/StorageManager.cs index 7531ef3..d8671ab 100644 --- a/DownKyi.Core/Storage/StorageManager.cs +++ b/DownKyi.Core/Storage/StorageManager.cs @@ -4,6 +4,26 @@ namespace DownKyi.Core.Storage { public static class StorageManager { + /// + /// 获取历史记录的文件路径 + /// + /// + public static string GetAriaDir() + { + CreateDirectory(Constant.Aria); + return Constant.Aria; + } + + /// + /// 获取历史记录的文件路径 + /// + /// + public static string GetDownload() + { + CreateDirectory(Constant.Database); + return Constant.Download; + } + /// /// 获取历史记录的文件路径 /// diff --git a/DownKyi/App.xaml.cs b/DownKyi/App.xaml.cs index d9b8f33..e8bc972 100644 --- a/DownKyi/App.xaml.cs +++ b/DownKyi/App.xaml.cs @@ -1,4 +1,5 @@ -using DownKyi.Models; +using DownKyi.Core.Settings; +using DownKyi.Models; using DownKyi.Services.Download; using DownKyi.Utils; using DownKyi.ViewModels; @@ -13,7 +14,9 @@ using DownKyi.Views.Settings; using DownKyi.Views.Toolbox; using Prism.Ioc; using System; +using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using System.Windows; namespace DownKyi @@ -104,5 +107,39 @@ namespace DownKyi Current.Dispatcher.Invoke(callback); } + /// + /// 下载完成列表排序 + /// + /// + public static void SortDownloadedList(DownloadFinishedSort finishedSort) + { + List list = DownloadedList.ToList(); + switch (finishedSort) + { + case DownloadFinishedSort.DOWNLOAD: + // 按下载先后排序 + list.Sort((x, y) => { return x.Downloaded.FinishedTimestamp.CompareTo(y.Downloaded.FinishedTimestamp); }); + break; + case DownloadFinishedSort.NUMBER: + // 按序号排序 + list.Sort((x, y) => + { + int compare = x.MainTitle.CompareTo(y.MainTitle); + return compare == 0 ? x.Order.CompareTo(y.Order) : compare; + }); + break; + default: + break; + } + + // 更新下载完成列表 + // 如果有更好的方法再重写 + DownloadedList.Clear(); + foreach (DownloadedItem item in list) + { + DownloadedList.Add(item); + } + } + } } diff --git a/DownKyi/DownKyi.csproj b/DownKyi/DownKyi.csproj index dfab557..4458ad1 100644 --- a/DownKyi/DownKyi.csproj +++ b/DownKyi/DownKyi.csproj @@ -88,20 +88,19 @@ - - - + + + - - - + + + - - - - - - + + + + + @@ -119,6 +118,9 @@ + + + diff --git a/DownKyi/Images/VectorImage.cs b/DownKyi/Images/VectorImage.cs index 921d09a..8e8fb9d 100644 --- a/DownKyi/Images/VectorImage.cs +++ b/DownKyi/Images/VectorImage.cs @@ -7,29 +7,29 @@ namespace DownKyi.Images private double width; public double Width { - get { return width; } - set { SetProperty(ref width, value); } + get => width; + set => SetProperty(ref width, value); } private double height; public double Height { - get { return height; } - set { SetProperty(ref height, value); } + get => height; + set => SetProperty(ref height, value); } private string data; public string Data { - get { return data; } - set { SetProperty(ref data, value); } + get => data; + set => SetProperty(ref data, value); } private string fill; public string Fill { - get { return fill; } - set { SetProperty(ref fill, value); } + get => fill; + set => SetProperty(ref fill, value); } } diff --git a/DownKyi/Languages/Default.xaml b/DownKyi/Languages/Default.xaml index 71c49b6..565c157 100644 --- a/DownKyi/Languages/Default.xaml +++ b/DownKyi/Languages/Default.xaml @@ -91,6 +91,12 @@ 全部开始 全部删除 + 已下载 + 个视频! + 按下载先后排序 + 按序号排序 + 清空所有记录 + 按回车键应用设置 diff --git a/DownKyi/Models/DownloadBase.cs b/DownKyi/Models/DownloadBase.cs new file mode 100644 index 0000000..53b3514 --- /dev/null +++ b/DownKyi/Models/DownloadBase.cs @@ -0,0 +1,75 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using System; +using System.Collections.Generic; + +namespace DownKyi.Models +{ + [Serializable] + public class DownloadBase + { + public DownloadBase() + { + // 唯一id + Uuid = Guid.NewGuid().ToString("N"); + + // 初始化需要下载的内容 + NeedDownloadContent = new Dictionary + { + { "downloadAudio", true }, + { "downloadVideo", true }, + { "downloadDanmaku", true }, + { "downloadSubtitle", true }, + { "downloadCover", true } + }; + } + + // 此条下载项的id + public string Uuid { get; } + + // 需要下载的内容 + public Dictionary NeedDownloadContent { get; private set; } + + // 视频的id + public string Bvid { get; set; } + public long Avid { get; set; } + public long Cid { get; set; } + public long EpisodeId { get; set; } + + // 视频封面的url + public string CoverUrl { get; set; } + + // 视频page的封面的url + public string PageCoverUrl { get; set; } + + // 分区id + public int ZoneId { get; set; } + + // 视频序号 + public int Order { get; set; } + + // 视频主标题 + public string MainTitle { get; set; } + + // 视频标题 + public string Name { get; set; } + + // 时长 + public string Duration { get; set; } + + // 视频编码名称,AVC、HEVC + public string VideoCodecName { get; set; } + + // 视频画质 + public Quality Resolution { get; set; } + + // 音频编码 + public Quality AudioCodec { get; set; } + + // 文件路径,不包含扩展名,所有内容均以此路径下载 + public string FilePath { get; set; } + + // 文件大小 + public string FileSize { get; set; } + + } +} diff --git a/DownKyi/Models/DownloadBaseItem.cs b/DownKyi/Models/DownloadBaseItem.cs deleted file mode 100644 index 488f572..0000000 --- a/DownKyi/Models/DownloadBaseItem.cs +++ /dev/null @@ -1,125 +0,0 @@ -using DownKyi.Core.BiliApi.BiliUtils; -using Prism.Mvvm; -using System; -using System.Collections.Generic; -using System.Windows.Media; - -namespace DownKyi.Models -{ - public class DownloadBaseItem : BindableBase - { - public DownloadBaseItem() - { - // 唯一id - Uuid = Guid.NewGuid().ToString("N"); - - // 初始化需要下载的内容 - NeedDownloadContent = new Dictionary - { - { "downloadAudio", true }, - { "downloadVideo", true }, - { "downloadDanmaku", true }, - { "downloadSubtitle", true }, - { "downloadCover", true } - }; - } - - // 此条下载项的id - public string Uuid { get; } - - // 需要下载的内容 - public Dictionary NeedDownloadContent { get; private set; } - - // 视频的id - public string Bvid { get; set; } - public long Avid { get; set; } - public long Cid { get; set; } - public long EpisodeId { get; set; } - - // 视频封面的url - public string CoverUrl { get; set; } - - // 视频page的封面的url - public string PageCoverUrl { get; set; } - - private DrawingImage zoneImage; - public DrawingImage ZoneImage - { - get => zoneImage; - set => SetProperty(ref zoneImage, value); - } - - // 视频序号 - private int order; - public int Order - { - get => order; - set => SetProperty(ref order, value); - } - - // 视频主标题 - private string mainTitle; - public string MainTitle - { - get => mainTitle; - set => SetProperty(ref mainTitle, value); - } - - // 视频标题 - private string name; - public string Name - { - get => name; - set => SetProperty(ref name, value); - } - - // 时长 - private string duration; - public string Duration - { - get => duration; - set => SetProperty(ref duration, value); - } - - // 视频编码 - // "hev1.2.4.L156.90" - // "avc1.640034" - //public string VideoCodecId { get; set; } - - // 视频编码名称,AVC、HEVC - private string videoCodecName; - public string VideoCodecName - { - get => videoCodecName; - set => SetProperty(ref videoCodecName, value); - } - - // 视频画质 - private Quality resolution; - public Quality Resolution - { - get => resolution; - set => SetProperty(ref resolution, value); - } - - // 音频编码 - private Quality audioCodec; - public Quality AudioCodec - { - get => audioCodec; - set => SetProperty(ref audioCodec, value); - } - - // 文件路径,不包含扩展名,所有内容均以此路径下载 - public string FilePath { get; set; } - - // 文件大小 - private string fileSize; - public string FileSize - { - get => fileSize; - set => SetProperty(ref fileSize, value); - } - - } -} diff --git a/DownKyi/Models/Downloaded.cs b/DownKyi/Models/Downloaded.cs new file mode 100644 index 0000000..4c31142 --- /dev/null +++ b/DownKyi/Models/Downloaded.cs @@ -0,0 +1,30 @@ +using System; + +namespace DownKyi.Models +{ + [Serializable] + public class Downloaded// : DownloadBase + { + public Downloaded() : base() + { + } + + // 下载速度 + public string MaxSpeedDisplay { get; set; } + + // 完成时间戳 + public long FinishedTimestamp { get; set; } + public void SetFinishedTimestamp(long finishedTimestamp) + { + FinishedTimestamp = finishedTimestamp; + + DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区 + DateTime dateTime = startTime.AddSeconds(finishedTimestamp); + FinishedTime = dateTime.ToString("yyyy-MM-dd HH:mm:ss"); + } + + // 完成时间 + public string FinishedTime { get; set; } + + } +} diff --git a/DownKyi/Models/DownloadedItem.cs b/DownKyi/Models/DownloadedItem.cs deleted file mode 100644 index c985651..0000000 --- a/DownKyi/Models/DownloadedItem.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace DownKyi.Models -{ - public class DownloadedItem : DownloadBaseItem - { - public DownloadedItem() : base() - { - } - } -} diff --git a/DownKyi/Models/Downloading.cs b/DownKyi/Models/Downloading.cs new file mode 100644 index 0000000..7147489 --- /dev/null +++ b/DownKyi/Models/Downloading.cs @@ -0,0 +1,47 @@ +using DownKyi.Core.BiliApi.VideoStream; +using System; +using System.Collections.Generic; + +namespace DownKyi.Models +{ + [Serializable] + public class Downloading// : DownloadBase + { + public Downloading() : base() + { + // 初始化下载的文件列表 + DownloadFiles = new List(); + } + + // Aria相关 + public string Gid { get; set; } + + // 下载的文件 + public List DownloadFiles { get; private set; } + + // 视频类别 + public PlayStreamType PlayStreamType { get; set; } + + // 下载状态 + public DownloadStatus DownloadStatus { get; set; } + + // 正在下载内容(音频、视频、弹幕、字幕、封面) + public string DownloadContent { get; set; } + + // 下载状态显示 + public string DownloadStatusTitle { get; set; } + + // 下载进度 + public float Progress { get; set; } + + // 已下载大小/文件大小 + public string DownloadingFileSize { get; set; } + + // 下载的最高速度 + public long MaxSpeed { get; set; } + + // 下载速度 + public string SpeedDisplay { get; set; } + + } +} diff --git a/DownKyi/Services/BangumiInfoService.cs b/DownKyi/Services/BangumiInfoService.cs index cd89dbf..270c0d4 100644 --- a/DownKyi/Services/BangumiInfoService.cs +++ b/DownKyi/Services/BangumiInfoService.cs @@ -2,10 +2,11 @@ using DownKyi.Core.BiliApi.Bangumi.Models; using DownKyi.Core.BiliApi.BiliUtils; using DownKyi.Core.BiliApi.VideoStream; +using DownKyi.Core.BiliApi.VideoStream.Models; using DownKyi.Core.Storage; using DownKyi.Core.Utils; -using DownKyi.Models; using DownKyi.Utils; +using DownKyi.ViewModels.PageViewModels; using System; using System.Collections.Generic; using System.Text.RegularExpressions; @@ -39,7 +40,7 @@ namespace DownKyi.Services if (ParseEntrance.IsBangumiMediaId(input) || ParseEntrance.IsBangumiMediaUrl(input)) { long mediaId = ParseEntrance.GetBangumiMediaId(input); - var bangumiMedia = BangumiInfo.BangumiMediaInfo(mediaId); + BangumiMedia bangumiMedia = BangumiInfo.BangumiMediaInfo(mediaId); bangumiSeason = BangumiInfo.BangumiSeasonInfo(bangumiMedia.SeasonId); } } @@ -56,7 +57,7 @@ namespace DownKyi.Services if (bangumiSeason.Episodes.Count == 0) { return pages; } int order = 0; - foreach (var episode in bangumiSeason.Episodes) + foreach (BangumiEpisode episode in bangumiSeason.Episodes) { order++; @@ -125,25 +126,16 @@ namespace DownKyi.Services } }; - foreach (var section in bangumiSeason.Section) + foreach (BangumiSection section in bangumiSeason.Section) { List pages = new List(); int order = 0; - foreach (var episode in section.Episodes) + foreach (BangumiEpisode episode in section.Episodes) { order++; // 标题 - string name; - if (episode.LongTitle != null && episode.LongTitle != "") - { - name = $"{episode.Title} {episode.LongTitle}"; - } - else - { - name = episode.Title; - } - + string name = episode.LongTitle != null && episode.LongTitle != "" ? $"{episode.Title} {episode.LongTitle}" : episode.Title; VideoPage page = new VideoPage { Avid = episode.Aid, @@ -176,7 +168,7 @@ namespace DownKyi.Services /// public void GetVideoStream(VideoPage page) { - var playUrl = VideoStream.GetBangumiPlayUrl(page.Avid, page.Bvid, page.Cid); + PlayUrl playUrl = VideoStream.GetBangumiPlayUrl(page.Avid, page.Bvid, page.Cid); Utils.VideoPageInfo(playUrl, page); } diff --git a/DownKyi/Services/CheeseInfoService.cs b/DownKyi/Services/CheeseInfoService.cs index 81f0987..359e11a 100644 --- a/DownKyi/Services/CheeseInfoService.cs +++ b/DownKyi/Services/CheeseInfoService.cs @@ -2,10 +2,11 @@ using DownKyi.Core.BiliApi.Cheese; using DownKyi.Core.BiliApi.Cheese.Models; using DownKyi.Core.BiliApi.VideoStream; +using DownKyi.Core.BiliApi.VideoStream.Models; using DownKyi.Core.Storage; using DownKyi.Core.Utils; -using DownKyi.Models; using DownKyi.Utils; +using DownKyi.ViewModels.PageViewModels; using System; using System.Collections.Generic; using System.Windows.Media.Imaging; @@ -48,7 +49,7 @@ namespace DownKyi.Services if (cheeseView.Episodes.Count == 0) { return pages; } int order = 0; - foreach (var episode in cheeseView.Episodes) + foreach (CheeseEpisode episode in cheeseView.Episodes) { order++; string name = episode.Title; @@ -87,7 +88,7 @@ namespace DownKyi.Services /// public void GetVideoStream(VideoPage page) { - var playUrl = VideoStream.GetCheesePlayUrl(page.Avid, page.Bvid, page.Cid, page.EpisodeId); + PlayUrl playUrl = VideoStream.GetCheesePlayUrl(page.Avid, page.Bvid, page.Cid, page.EpisodeId); Utils.VideoPageInfo(playUrl, page); } diff --git a/DownKyi/Services/Download/AriaDownloadService.cs b/DownKyi/Services/Download/AriaDownloadService.cs index d972c38..8bebe9c 100644 --- a/DownKyi/Services/Download/AriaDownloadService.cs +++ b/DownKyi/Services/Download/AriaDownloadService.cs @@ -13,6 +13,7 @@ using DownKyi.Core.Storage; using DownKyi.Core.Utils; using DownKyi.Models; using DownKyi.Utils; +using DownKyi.ViewModels.DownloadManager; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -118,14 +119,14 @@ namespace DownKyi.Services.Download if (downloadVideo.BackupUrl != null) { urls.AddRange(downloadVideo.BackupUrl); } // 路径 - string[] temp = downloading.FilePath.Split('/'); - string path = downloading.FilePath.Replace(temp[temp.Length - 1], ""); + string[] temp = downloading.DownloadBase.FilePath.Split('/'); + string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], ""); // 下载文件名 string fileName = Guid.NewGuid().ToString("N"); // 记录本次下载的文件 - downloading.DownloadFiles.Add(fileName); + downloading.Downloading.DownloadFiles.Add(fileName); // 开始下载 DownloadResult downloadStatus = DownloadByAria(downloading, urls, path, fileName); @@ -160,7 +161,7 @@ namespace DownKyi.Services.Download // 查询、保存封面 StorageCover storageCover = new StorageCover(); - string cover = storageCover.GetCover(downloading.Avid, downloading.Bvid, downloading.Cid, coverUrl); + string cover = storageCover.GetCover(downloading.DownloadBase.Avid, downloading.DownloadBase.Bvid, downloading.DownloadBase.Cid, coverUrl); if (cover == null) { return null; @@ -172,7 +173,7 @@ namespace DownKyi.Services.Download File.Copy(cover, fileName, true); // 记录本次下载的文件 - downloading.DownloadFiles.Add(fileName); + downloading.Downloading.DownloadFiles.Add(fileName); return fileName; } @@ -200,10 +201,10 @@ namespace DownKyi.Services.Download downloading.SpeedDisplay = string.Empty; string title = $"{downloading.Name}"; - string assFile = $"{downloading.FilePath}.ass"; + string assFile = $"{downloading.DownloadBase.FilePath}.ass"; // 记录本次下载的文件 - downloading.DownloadFiles.Add(assFile); + downloading.Downloading.DownloadFiles.Add(assFile); int screenWidth = SettingsManager.GetInstance().GetDanmakuScreenWidth(); int screenHeight = SettingsManager.GetInstance().GetDanmakuScreenHeight(); @@ -236,7 +237,7 @@ namespace DownKyi.Services.Download .SetTopFilter(SettingsManager.GetInstance().GetDanmakuTopFilter() == AllowStatus.YES) .SetBottomFilter(SettingsManager.GetInstance().GetDanmakuBottomFilter() == AllowStatus.YES) .SetScrollFilter(SettingsManager.GetInstance().GetDanmakuScrollFilter() == AllowStatus.YES) - .Create(downloading.Avid, downloading.Cid, subtitleConfig, assFile); + .Create(downloading.DownloadBase.Avid, downloading.DownloadBase.Cid, subtitleConfig, assFile); return assFile; } @@ -257,7 +258,7 @@ namespace DownKyi.Services.Download List srtFiles = new List(); - var subRipTexts = VideoStream.GetSubtitle(downloading.Avid, downloading.Bvid, downloading.Cid); + var subRipTexts = VideoStream.GetSubtitle(downloading.DownloadBase.Avid, downloading.DownloadBase.Bvid, downloading.DownloadBase.Cid); if (subRipTexts == null) { return null; @@ -265,13 +266,13 @@ namespace DownKyi.Services.Download foreach (var subRip in subRipTexts) { - string srtFile = $"{downloading.FilePath}_{subRip.LanDoc}.srt"; + string srtFile = $"{downloading.DownloadBase.FilePath}_{subRip.LanDoc}.srt"; try { File.WriteAllText(srtFile, subRip.SrtString); // 记录本次下载的文件 - downloading.DownloadFiles.Add(srtFile); + downloading.Downloading.DownloadFiles.Add(srtFile); srtFiles.Add(srtFile); } @@ -302,10 +303,10 @@ namespace DownKyi.Services.Download // 下载速度 downloading.SpeedDisplay = string.Empty; - string finalFile = $"{downloading.FilePath}.mp4"; + string finalFile = $"{downloading.DownloadBase.FilePath}.mp4"; if (videoUid == null) { - finalFile = $"{downloading.FilePath}.aac"; + finalFile = $"{downloading.DownloadBase.FilePath}.aac"; } // 合并音视频 @@ -339,22 +340,22 @@ namespace DownKyi.Services.Download // 下载速度 downloading.SpeedDisplay = string.Empty; - if (downloading.PlayUrl != null && downloading.DownloadStatus == DownloadStatus.NOT_STARTED) + if (downloading.PlayUrl != null && downloading.Downloading.DownloadStatus == DownloadStatus.NOT_STARTED) { return; } // 解析 - switch (downloading.PlayStreamType) + switch (downloading.Downloading.PlayStreamType) { case PlayStreamType.VIDEO: - downloading.PlayUrl = VideoStream.GetVideoPlayUrl(downloading.Avid, downloading.Bvid, downloading.Cid); + downloading.PlayUrl = VideoStream.GetVideoPlayUrl(downloading.DownloadBase.Avid, downloading.DownloadBase.Bvid, downloading.DownloadBase.Cid); break; case PlayStreamType.BANGUMI: - downloading.PlayUrl = VideoStream.GetBangumiPlayUrl(downloading.Avid, downloading.Bvid, downloading.Cid); + downloading.PlayUrl = VideoStream.GetBangumiPlayUrl(downloading.DownloadBase.Avid, downloading.DownloadBase.Bvid, downloading.DownloadBase.Cid); break; case PlayStreamType.CHEESE: - downloading.PlayUrl = VideoStream.GetCheesePlayUrl(downloading.Avid, downloading.Bvid, downloading.Cid, downloading.EpisodeId); + downloading.PlayUrl = VideoStream.GetCheesePlayUrl(downloading.DownloadBase.Avid, downloading.DownloadBase.Bvid, downloading.DownloadBase.Cid, downloading.DownloadBase.EpisodeId); break; default: break; @@ -399,7 +400,7 @@ namespace DownKyi.Services.Download int downloadingCount = 0; foreach (DownloadingItem downloading in downloadingList) { - if (downloading.DownloadStatus == DownloadStatus.DOWNLOADING) + if (downloading.Downloading.DownloadStatus == DownloadStatus.DOWNLOADING) { downloadingCount++; } @@ -413,7 +414,7 @@ namespace DownKyi.Services.Download } // 开始下载 - if (downloading.DownloadStatus == DownloadStatus.NOT_STARTED || downloading.DownloadStatus == DownloadStatus.WAIT_FOR_DOWNLOAD) + if (downloading.Downloading.DownloadStatus == DownloadStatus.NOT_STARTED || downloading.Downloading.DownloadStatus == DownloadStatus.WAIT_FOR_DOWNLOAD) { SingleDownload(downloading); downloadingCount++; @@ -441,8 +442,8 @@ namespace DownKyi.Services.Download private async void SingleDownload(DownloadingItem downloading) { // 路径 - string[] temp = downloading.FilePath.Split('/'); - string path = downloading.FilePath.Replace(temp[temp.Length - 1], ""); + string[] temp = downloading.DownloadBase.FilePath.Split('/'); + string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], ""); // 路径不存在则创建 if (!Directory.Exists(path)) { @@ -451,12 +452,12 @@ namespace DownKyi.Services.Download await Task.Run(new Action(() => { - downloading.DownloadStatus = DownloadStatus.DOWNLOADING; + downloading.Downloading.DownloadStatus = DownloadStatus.DOWNLOADING; // 初始化 downloading.DownloadStatusTitle = string.Empty; downloading.DownloadContent = string.Empty; - downloading.DownloadFiles.Clear(); + downloading.Downloading.DownloadFiles.Clear(); // 解析并依次下载音频、视频、弹幕、字幕、封面等内容 Parse(downloading); @@ -466,7 +467,7 @@ namespace DownKyi.Services.Download string audioUid = null; // 如果需要下载音频 - if (downloading.NeedDownloadContent["downloadAudio"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadAudio"]) { audioUid = DownloadAudio(downloading); } @@ -476,7 +477,7 @@ namespace DownKyi.Services.Download string videoUid = null; // 如果需要下载视频 - if (downloading.NeedDownloadContent["downloadVideo"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadVideo"]) { videoUid = DownloadVideo(downloading); } @@ -486,7 +487,7 @@ namespace DownKyi.Services.Download string outputDanmaku = null; // 如果需要下载弹幕 - if (downloading.NeedDownloadContent["downloadDanmaku"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadDanmaku"]) { outputDanmaku = DownloadDanmaku(downloading); } @@ -496,7 +497,7 @@ namespace DownKyi.Services.Download List outputSubtitles = null; // 如果需要下载字幕 - if (downloading.NeedDownloadContent["downloadSubtitle"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadSubtitle"]) { outputSubtitles = DownloadSubtitle(downloading); } @@ -506,15 +507,15 @@ namespace DownKyi.Services.Download string outputCover = null; // 如果需要下载封面 - if (downloading.NeedDownloadContent["downloadCover"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadCover"]) { - string fileName = $"{downloading.FilePath}.{GetImageExtension(downloading.PageCoverUrl)}"; + string fileName = $"{downloading.DownloadBase.FilePath}.{GetImageExtension(downloading.DownloadBase.PageCoverUrl)}"; // page的封面 - outputCover = DownloadCover(downloading, downloading.PageCoverUrl, fileName); + outputCover = DownloadCover(downloading, downloading.DownloadBase.PageCoverUrl, fileName); // 封面 - DownloadCover(downloading, downloading.CoverUrl, $"{path}/Cover.{GetImageExtension(downloading.CoverUrl)}"); + DownloadCover(downloading, downloading.DownloadBase.CoverUrl, $"{path}/Cover.{GetImageExtension(downloading.DownloadBase.CoverUrl)}"); } // 暂停 @@ -522,7 +523,7 @@ namespace DownKyi.Services.Download // 混流 string outputMedia = string.Empty; - if (downloading.NeedDownloadContent["downloadAudio"] || downloading.NeedDownloadContent["downloadVideo"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadAudio"] || downloading.DownloadBase.NeedDownloadContent["downloadVideo"]) { outputMedia = MixedFlow(downloading, audioUid, videoUid); } @@ -531,7 +532,7 @@ namespace DownKyi.Services.Download Pause(downloading); // 检测音频、视频是否下载成功 - if (downloading.NeedDownloadContent["downloadAudio"] || downloading.NeedDownloadContent["downloadVideo"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadAudio"] || downloading.DownloadBase.NeedDownloadContent["downloadVideo"]) { // 只有下载音频不下载视频时才输出aac // 只要下载视频就输出mp4 @@ -542,13 +543,13 @@ namespace DownKyi.Services.Download } // 检测弹幕是否下载成功 - if (downloading.NeedDownloadContent["downloadDanmaku"] && File.Exists(outputDanmaku)) + if (downloading.DownloadBase.NeedDownloadContent["downloadDanmaku"] && File.Exists(outputDanmaku)) { // 成功 } // 检测字幕是否下载成功 - if (downloading.NeedDownloadContent["downloadSubtitle"]) + if (downloading.DownloadBase.NeedDownloadContent["downloadSubtitle"]) { if (outputSubtitles == null) { @@ -567,7 +568,7 @@ namespace DownKyi.Services.Download } // 检测封面是否下载成功 - if (downloading.NeedDownloadContent["downloadCover"] && File.Exists(outputCover)) + if (downloading.DownloadBase.NeedDownloadContent["downloadCover"] && File.Exists(outputCover)) { // 成功 } @@ -578,6 +579,29 @@ namespace DownKyi.Services.Download // 下载结果是否成功等 // 对是否成功的判断:只要outputMedia存在则成功,否则失败 + Downloaded downloaded = new Downloaded + { + MaxSpeedDisplay = Format.FormatSpeed(downloading.Downloading.MaxSpeed), + }; + // 设置完成时间 + downloaded.SetFinishedTimestamp(new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds()); + + DownloadedItem downloadedItem = new DownloadedItem + { + DownloadBase = downloading.DownloadBase, + Downloaded = downloaded + }; + + App.PropertyChangeAsync(new Action(() => + { + // 加入到下载完成list中,并从下载中list去除 + App.DownloadedList.Add(downloadedItem); + App.DownloadingList.Remove(downloading); + + // 下载完成列表排序 + DownloadFinishedSort finishedSort = SettingsManager.GetInstance().GetDownloadFinishedSort(); + App.SortDownloadedList(finishedSort); + })); })); } @@ -607,7 +631,7 @@ namespace DownKyi.Services.Download { string oldStatus = downloading.DownloadStatusTitle; downloading.DownloadStatusTitle = DictionaryResource.GetString("Pausing"); - while (downloading.DownloadStatus == DownloadStatus.PAUSE) + while (downloading.Downloading.DownloadStatus == DownloadStatus.PAUSE) { // 降低CPU占用 Thread.Sleep(100); @@ -621,7 +645,7 @@ namespace DownKyi.Services.Download downloadingCount = 0; foreach (DownloadingItem item in downloadingList) { - if (item.DownloadStatus == DownloadStatus.DOWNLOADING) + if (item.Downloading.DownloadStatus == DownloadStatus.DOWNLOADING) { downloadingCount++; } @@ -731,7 +755,7 @@ namespace DownKyi.Services.Download // 保存gid string gid = ariaAddUri.Result.Result; - downloading.Gid = gid; + downloading.Downloading.Gid = gid; // 管理下载 AriaManager ariaManager = new AriaManager(); @@ -739,15 +763,15 @@ namespace DownKyi.Services.Download ariaManager.DownloadFinish += AriaDownloadFinish; return ariaManager.GetDownloadStatus(gid, new Action(() => { - switch (downloading.DownloadStatus) + switch (downloading.Downloading.DownloadStatus) { case DownloadStatus.PAUSE: - Task ariaPause = AriaClient.PauseAsync(downloading.Gid); + Task ariaPause = AriaClient.PauseAsync(downloading.Downloading.Gid); // 通知UI,并阻塞当前线程 Pause(downloading); break; case DownloadStatus.DOWNLOADING: - Task ariaUnpause = AriaClient.UnpauseAsync(downloading.Gid); + Task ariaUnpause = AriaClient.UnpauseAsync(downloading.Downloading.Gid); break; } })); @@ -756,7 +780,7 @@ namespace DownKyi.Services.Download private void AriaTellStatus(long totalLength, long completedLength, long speed, string gid) { // 当前的下载视频 - DownloadingItem video = downloadingList.FirstOrDefault(it => it.Gid == gid); + DownloadingItem video = downloadingList.FirstOrDefault(it => it.Downloading.Gid == gid); if (video == null) { return; } float percent = 0; @@ -778,9 +802,9 @@ namespace DownKyi.Services.Download video.SpeedDisplay = Format.FormatSpeed(speed); // 最大下载速度 - if (video.MaxSpeed < speed) + if (video.Downloading.MaxSpeed < speed) { - video.MaxSpeed = speed; + video.Downloading.MaxSpeed = speed; } } diff --git a/DownKyi/Services/Download/DownloadService.cs b/DownKyi/Services/Download/DownloadService.cs index 07288ee..f8612a8 100644 --- a/DownKyi/Services/Download/DownloadService.cs +++ b/DownKyi/Services/Download/DownloadService.cs @@ -1,4 +1,4 @@ -using DownKyi.Models; +using DownKyi.ViewModels.DownloadManager; using System.Collections.ObjectModel; namespace DownKyi.Services.Download diff --git a/DownKyi/Services/Download/IDownloadService.cs b/DownKyi/Services/Download/IDownloadService.cs index 3621dad..fea9835 100644 --- a/DownKyi/Services/Download/IDownloadService.cs +++ b/DownKyi/Services/Download/IDownloadService.cs @@ -1,4 +1,4 @@ -using DownKyi.Models; +using DownKyi.ViewModels.DownloadManager; using System.Collections.Generic; namespace DownKyi.Services.Download diff --git a/DownKyi/Services/FavoritesService.cs b/DownKyi/Services/FavoritesService.cs index b4bfe9a..2363556 100644 --- a/DownKyi/Services/FavoritesService.cs +++ b/DownKyi/Services/FavoritesService.cs @@ -1,7 +1,7 @@ using DownKyi.Core.BiliApi.Favorites; using DownKyi.Core.Storage; using DownKyi.Core.Utils; -using DownKyi.Models; +using DownKyi.ViewModels.PageViewModels; using Prism.Events; using System; using System.Collections.ObjectModel; diff --git a/DownKyi/Services/IFavoritesService.cs b/DownKyi/Services/IFavoritesService.cs index 0fb7d82..f83e761 100644 --- a/DownKyi/Services/IFavoritesService.cs +++ b/DownKyi/Services/IFavoritesService.cs @@ -1,4 +1,4 @@ -using DownKyi.Models; +using DownKyi.ViewModels.PageViewModels; using Prism.Events; using System.Collections.ObjectModel; diff --git a/DownKyi/Services/IInfoService.cs b/DownKyi/Services/IInfoService.cs index 4aacf84..a882569 100644 --- a/DownKyi/Services/IInfoService.cs +++ b/DownKyi/Services/IInfoService.cs @@ -1,4 +1,4 @@ -using DownKyi.Models; +using DownKyi.ViewModels.PageViewModels; using System.Collections.Generic; namespace DownKyi.Services diff --git a/DownKyi/Services/Utils.cs b/DownKyi/Services/Utils.cs index ed54eb9..b0f55b3 100644 --- a/DownKyi/Services/Utils.cs +++ b/DownKyi/Services/Utils.cs @@ -3,7 +3,7 @@ using DownKyi.Core.BiliApi.VideoStream.Models; using DownKyi.Core.Settings; using DownKyi.Core.Settings.Models; using DownKyi.Core.Utils; -using DownKyi.Models; +using DownKyi.ViewModels.PageViewModels; using System.Collections.Generic; using System.Linq; diff --git a/DownKyi/Services/VideoInfoService.cs b/DownKyi/Services/VideoInfoService.cs index a807aaa..5659cca 100644 --- a/DownKyi/Services/VideoInfoService.cs +++ b/DownKyi/Services/VideoInfoService.cs @@ -4,7 +4,7 @@ using DownKyi.Core.BiliApi.Video.Models; using DownKyi.Core.BiliApi.VideoStream; using DownKyi.Core.Storage; using DownKyi.Core.Utils; -using DownKyi.Models; +using DownKyi.ViewModels.PageViewModels; using System; using System.Collections.Generic; using System.Windows.Media.Imaging; @@ -39,13 +39,13 @@ namespace DownKyi.Services /// 获取视频剧集 /// /// - public List GetVideoPages() + public List GetVideoPages() { if (videoView == null) { return null; } if (videoView.Pages == null) { return null; } if (videoView.Pages.Count == 0) { return null; } - List videoPages = new List(); + List videoPages = new List(); int order = 0; foreach (var page in videoView.Pages) @@ -72,7 +72,7 @@ namespace DownKyi.Services } } - Models.VideoPage videoPage = new Models.VideoPage + ViewModels.PageViewModels.VideoPage videoPage = new ViewModels.PageViewModels.VideoPage { Avid = videoView.Aid, Bvid = videoView.Bvid, @@ -104,12 +104,12 @@ namespace DownKyi.Services foreach (var section in videoView.UgcSeason.Sections) { - List pages = new List(); + List pages = new List(); int order = 0; foreach (var episode in section.Episodes) { order++; - Models.VideoPage page = new Models.VideoPage + ViewModels.PageViewModels.VideoPage page = new ViewModels.PageViewModels.VideoPage { Avid = episode.Aid, Bvid = episode.Bvid, @@ -141,7 +141,7 @@ namespace DownKyi.Services /// 获取视频流的信息,从VideoPage返回 /// /// - public void GetVideoStream(Models.VideoPage page) + public void GetVideoStream(ViewModels.PageViewModels.VideoPage page) { var playUrl = VideoStream.GetVideoPlayUrl(page.Avid, page.Bvid, page.Cid); Utils.VideoPageInfo(playUrl, page); diff --git a/DownKyi/Utils/DictionaryResource.cs b/DownKyi/Utils/DictionaryResource.cs index 71147da..a6fa53c 100644 --- a/DownKyi/Utils/DictionaryResource.cs +++ b/DownKyi/Utils/DictionaryResource.cs @@ -15,8 +15,10 @@ namespace DownKyi.Utils /// public static string GetColor(string resourceKey) { - Color color = (Color)Application.Current.Resources[resourceKey]; - return color.ToString(); + //Color color = (Color)Application.Current.Resources[resourceKey]; + //return color.ToString(); + + return Application.Current == null ? "#00000000" : ((Color)Application.Current.Resources[resourceKey]).ToString(); } /// diff --git a/DownKyi/ViewModels/BaseViewModel.cs b/DownKyi/ViewModels/BaseViewModel.cs index 9710162..54d623f 100644 --- a/DownKyi/ViewModels/BaseViewModel.cs +++ b/DownKyi/ViewModels/BaseViewModel.cs @@ -41,6 +41,8 @@ namespace DownKyi.ViewModels /// protected void PropertyChangeAsync(Action callback) { + if (Application.Current == null) { return; } + Application.Current.Dispatcher.Invoke(callback); } diff --git a/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs b/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs new file mode 100644 index 0000000..454f94b --- /dev/null +++ b/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs @@ -0,0 +1,122 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.Zone; +using DownKyi.Models; +using Prism.Mvvm; +using System.Windows; +using System.Windows.Media; + +namespace DownKyi.ViewModels.DownloadManager +{ + public class DownloadBaseItem : BindableBase + { + // model数据 + private DownloadBase downloadBase; + public DownloadBase DownloadBase + { + get => downloadBase; + set + { + downloadBase = value; + + ZoneImage = (DrawingImage)Application.Current.Resources[VideoZoneIcon.Instance().GetZoneImageKey(DownloadBase.ZoneId)]; + } + } + + // 视频分区image + private DrawingImage zoneImage; + public DrawingImage ZoneImage + { + get => zoneImage; + set => SetProperty(ref zoneImage, value); + } + + // 视频序号 + public int Order + { + get => DownloadBase.Order; + set + { + DownloadBase.Order = value; + RaisePropertyChanged("Order"); + } + } + + // 视频主标题 + public string MainTitle + { + get => DownloadBase.MainTitle; + set + { + DownloadBase.MainTitle = value; + RaisePropertyChanged("MainTitle"); + } + } + + // 视频标题 + public string Name + { + get => DownloadBase.Name; + set + { + DownloadBase.Name = value; + RaisePropertyChanged("Name"); + } + } + + // 时长 + public string Duration + { + get => DownloadBase.Duration; + set + { + DownloadBase.Duration = value; + RaisePropertyChanged("Duration"); + } + } + + // 视频编码名称,AVC、HEVC + public string VideoCodecName + { + get => DownloadBase.VideoCodecName; + set + { + DownloadBase.VideoCodecName = value; + RaisePropertyChanged("VideoCodecName"); + } + } + + // 视频画质 + public Quality Resolution + { + get => DownloadBase.Resolution; + set + { + DownloadBase.Resolution = value; + RaisePropertyChanged("Resolution"); + } + } + + // 音频编码 + public Quality AudioCodec + { + get => DownloadBase.AudioCodec; + set + { + DownloadBase.AudioCodec = value; + RaisePropertyChanged("AudioCodec"); + } + } + + // 文件大小 + public string FileSize + { + get => DownloadBase.FileSize; + set + { + DownloadBase.FileSize = value; + RaisePropertyChanged("FileSize"); + } + } + + } +} diff --git a/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs b/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs new file mode 100644 index 0000000..5149d28 --- /dev/null +++ b/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs @@ -0,0 +1,122 @@ +using DownKyi.Images; +using DownKyi.Models; +using Prism.Commands; +using System.IO; + +namespace DownKyi.ViewModels.DownloadManager +{ + public class DownloadedItem : DownloadBaseItem + { + public DownloadedItem() : base() + { + } + + // model数据 + public Downloaded Downloaded { get; set; } + + // 下载速度 + public string MaxSpeedDisplay + { + get => Downloaded.MaxSpeedDisplay; + set + { + Downloaded.MaxSpeedDisplay = value; + RaisePropertyChanged("MaxSpeedDisplay"); + } + } + + // 完成时间 + public string FinishedTime + { + get => Downloaded.FinishedTime; + set + { + Downloaded.FinishedTime = value; + RaisePropertyChanged("FinishedTime"); + } + } + + #region 控制按钮 + + private VectorImage openFolder; + public VectorImage OpenFolder + { + get => openFolder; + set => SetProperty(ref openFolder, value); + } + + private VectorImage openVideo; + public VectorImage OpenVideo + { + get => openVideo; + set => SetProperty(ref openVideo, value); + } + + private VectorImage removeVideo; + public VectorImage RemoveVideo + { + get => removeVideo; + set => SetProperty(ref removeVideo, value); + } + + #endregion + + #region 命令申明 + + // 打开文件夹事件 + private DelegateCommand openFolderCommand; + public DelegateCommand OpenFolderCommand => openFolderCommand ?? (openFolderCommand = new DelegateCommand(ExecuteOpenFolderCommand)); + + /// + /// 打开文件夹事件 + /// + private void ExecuteOpenFolderCommand() + { + string videoPath = $"{DownloadBase.FilePath}.mp4"; + if (File.Exists(videoPath)) + { + System.Diagnostics.Process.Start("Explorer", "/select," + videoPath); + } + else + { + //eventAggregator.GetEvent().Publish("没有找到视频文件,可能被删除或移动!"); + } + } + + // 打开视频事件 + private DelegateCommand openVideoCommand; + public DelegateCommand OpenVideoCommand => openVideoCommand ?? (openVideoCommand = new DelegateCommand(ExecuteOpenVideoCommand)); + + /// + /// 打开视频事件 + /// + private void ExecuteOpenVideoCommand() + { + string videoPath = $"{DownloadBase.FilePath}.mp4"; + if (File.Exists(videoPath)) + { + System.Diagnostics.Process.Start(videoPath); + } + else + { + //eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipAddDownloadingZero")); + //eventAggregator.GetEvent().Publish("没有找到视频文件,可能被删除或移动!"); + } + } + + // 删除事件 + private DelegateCommand removeVideoCommand; + public DelegateCommand RemoveVideoCommand => removeVideoCommand ?? (removeVideoCommand = new DelegateCommand(ExecuteRemoveVideoCommand)); + + /// + /// 删除事件 + /// + private void ExecuteRemoveVideoCommand() + { + App.DownloadedList.Remove(this); + } + + #endregion + + } +} diff --git a/DownKyi/Models/DownloadingItem.cs b/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs similarity index 70% rename from DownKyi/Models/DownloadingItem.cs rename to DownKyi/ViewModels/DownloadManager/DownloadingItem.cs index acde187..e727366 100644 --- a/DownKyi/Models/DownloadingItem.cs +++ b/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs @@ -1,18 +1,15 @@ using DownKyi.Core.BiliApi.VideoStream.Models; using DownKyi.Images; +using DownKyi.Models; using DownKyi.Utils; using Prism.Commands; -using System.Collections.Generic; -namespace DownKyi.Models +namespace DownKyi.ViewModels.DownloadManager { public class DownloadingItem : DownloadBaseItem { public DownloadingItem() : base() { - // 初始化下载的文件列表 - DownloadFiles = new List(); - // 暂停继续按钮 StartOrPause = ButtonIcon.Instance().Pause; StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary"); @@ -22,62 +19,65 @@ namespace DownKyi.Models Delete.Fill = DictionaryResource.GetColor("ColorPrimary"); } - public PlayUrl PlayUrl { get; set; } - - // Aria相关 - public string Gid { get; set; } - - // 下载的文件 - public List DownloadFiles { get; private set; } - - // 视频类别 - public PlayStreamType PlayStreamType { get; set; } + // model数据 + public Downloading Downloading { get; set; } + // 视频流链接 + public PlayUrl PlayUrl { get; set; } // 正在下载内容(音频、视频、弹幕、字幕、封面) - private string downloadContent; public string DownloadContent { - get => downloadContent; - set => SetProperty(ref downloadContent, value); + get => Downloading.DownloadContent; + set + { + Downloading.DownloadContent = value; + RaisePropertyChanged("DownloadContent"); + } } - // 下载状态 - public DownloadStatus DownloadStatus { get; set; } - // 下载状态显示 - private string downloadStatusTitle; public string DownloadStatusTitle { - get => downloadStatusTitle; - set => SetProperty(ref downloadStatusTitle, value); + get => Downloading.DownloadStatusTitle; + set + { + Downloading.DownloadStatusTitle = value; + RaisePropertyChanged("DownloadStatusTitle"); + } } // 下载进度 - private float progress; public float Progress { - get => progress; - set => SetProperty(ref progress, value); + get => Downloading.Progress; + set + { + Downloading.Progress = value; + RaisePropertyChanged("Progress"); + } } // 已下载大小/文件大小 - private string downloadingFileSize; public string DownloadingFileSize { - get => downloadingFileSize; - set => SetProperty(ref downloadingFileSize, value); + get => Downloading.DownloadingFileSize; + set + { + Downloading.DownloadingFileSize = value; + RaisePropertyChanged("DownloadingFileSize"); + } } - // 下载的最高速度 - public long MaxSpeed { get; set; } - // 下载速度 - private string speedDisplay; public string SpeedDisplay { - get => speedDisplay; - set => SetProperty(ref speedDisplay, value); + get => Downloading.SpeedDisplay; + set + { + Downloading.SpeedDisplay = value; + RaisePropertyChanged("SpeedDisplay"); + } } @@ -110,26 +110,26 @@ namespace DownKyi.Models /// private void ExecuteStartOrPauseCommand() { - switch (DownloadStatus) + switch (Downloading.DownloadStatus) { case DownloadStatus.NOT_STARTED: case DownloadStatus.WAIT_FOR_DOWNLOAD: - DownloadStatus = DownloadStatus.PAUSE_STARTED; + Downloading.DownloadStatus = DownloadStatus.PAUSE_STARTED; StartOrPause = ButtonIcon.Instance().Start; StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary"); break; case DownloadStatus.PAUSE_STARTED: - DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; + Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; StartOrPause = ButtonIcon.Instance().Pause; StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary"); break; case DownloadStatus.PAUSE: - DownloadStatus = DownloadStatus.DOWNLOADING; + Downloading.DownloadStatus = DownloadStatus.DOWNLOADING; StartOrPause = ButtonIcon.Instance().Pause; StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary"); break; case DownloadStatus.DOWNLOADING: - DownloadStatus = DownloadStatus.PAUSE; + Downloading.DownloadStatus = DownloadStatus.PAUSE; StartOrPause = ButtonIcon.Instance().Start; StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary"); break; @@ -138,7 +138,7 @@ namespace DownKyi.Models // 不会出现此分支 break; case DownloadStatus.DOWNLOAD_FAILED: - DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; + Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; StartOrPause = ButtonIcon.Instance().Pause; StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary"); break; diff --git a/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs b/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs index a305a98..492cf1d 100644 --- a/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs +++ b/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs @@ -1,11 +1,7 @@ -using DownKyi.Models; +using DownKyi.Core.Settings; using Prism.Commands; using Prism.Events; -using Prism.Mvvm; -using System; -using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Linq; namespace DownKyi.ViewModels.DownloadManager { @@ -18,15 +14,55 @@ namespace DownKyi.ViewModels.DownloadManager private ObservableCollection downloadedList; public ObservableCollection DownloadedList { - get { return downloadedList; } - set { SetProperty(ref downloadedList, value); } + get => downloadedList; + set => SetProperty(ref downloadedList, value); } #endregion public ViewDownloadFinishedViewModel(IEventAggregator eventAggregator) : base(eventAggregator) { + // 初始化DownloadedList DownloadedList = App.DownloadedList; } + + #region 命令申明 + + // 下载完成列表排序事件 + private DelegateCommand finishedSortCommand; + public DelegateCommand FinishedSortCommand => finishedSortCommand ?? (finishedSortCommand = new DelegateCommand(ExecuteFinishedSortCommand)); + + /// + /// 下载完成列表排序事件 + /// + /// + private void ExecuteFinishedSortCommand(object parameter) + { + if (!(parameter is int index)) { return; } + + switch (index) + { + case 1: + App.SortDownloadedList(DownloadFinishedSort.DOWNLOAD); + break; + case 2: + App.SortDownloadedList(DownloadFinishedSort.NUMBER); + break; + } + } + + // 清空下载完成列表事件 + private DelegateCommand clearAllDownloadedCommand; + public DelegateCommand ClearAllDownloadedCommand => clearAllDownloadedCommand ?? (clearAllDownloadedCommand = new DelegateCommand(ExecuteClearAllDownloadedCommand)); + + /// + /// 清空下载完成列表事件 + /// + private void ExecuteClearAllDownloadedCommand() + { + } + + #endregion + } } diff --git a/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs b/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs index 547438a..d4bc070 100644 --- a/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs +++ b/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs @@ -41,18 +41,18 @@ namespace DownKyi.ViewModels.DownloadManager { foreach (DownloadingItem downloading in downloadingList) { - switch (downloading.DownloadStatus) + switch (downloading.Downloading.DownloadStatus) { case DownloadStatus.NOT_STARTED: case DownloadStatus.WAIT_FOR_DOWNLOAD: - downloading.DownloadStatus = DownloadStatus.PAUSE_STARTED; + downloading.Downloading.DownloadStatus = DownloadStatus.PAUSE_STARTED; break; case DownloadStatus.PAUSE_STARTED: break; case DownloadStatus.PAUSE: break; case DownloadStatus.DOWNLOADING: - downloading.DownloadStatus = DownloadStatus.PAUSE; + downloading.Downloading.DownloadStatus = DownloadStatus.PAUSE; break; case DownloadStatus.DOWNLOAD_SUCCEED: // 下载成功后会从下载列表中删除 @@ -80,16 +80,16 @@ namespace DownKyi.ViewModels.DownloadManager { foreach (DownloadingItem downloading in downloadingList) { - switch (downloading.DownloadStatus) + switch (downloading.Downloading.DownloadStatus) { case DownloadStatus.NOT_STARTED: case DownloadStatus.WAIT_FOR_DOWNLOAD: break; case DownloadStatus.PAUSE_STARTED: - downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; + downloading.Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; break; case DownloadStatus.PAUSE: - downloading.DownloadStatus = DownloadStatus.DOWNLOADING; + downloading.Downloading.DownloadStatus = DownloadStatus.DOWNLOADING; break; case DownloadStatus.DOWNLOADING: break; @@ -98,7 +98,7 @@ namespace DownKyi.ViewModels.DownloadManager // 不会出现此分支 break; case DownloadStatus.DOWNLOAD_FAILED: - downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; + downloading.Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD; break; default: break; diff --git a/DownKyi/Models/Favorites.cs b/DownKyi/ViewModels/PageViewModels/Favorites.cs similarity index 52% rename from DownKyi/Models/Favorites.cs rename to DownKyi/ViewModels/PageViewModels/Favorites.cs index e5098ea..96f1db8 100644 --- a/DownKyi/Models/Favorites.cs +++ b/DownKyi/ViewModels/PageViewModels/Favorites.cs @@ -1,7 +1,7 @@ using Prism.Mvvm; using System.Windows.Media.Imaging; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { public class Favorites : BindableBase { @@ -11,78 +11,78 @@ namespace DownKyi.Models private BitmapImage cover; public BitmapImage Cover { - get { return cover; } - set { SetProperty(ref cover, value); } + get => cover; + set => SetProperty(ref cover, value); } private string title; public string Title { - get { return title; } - set { SetProperty(ref title, value); } + get => title; + set => SetProperty(ref title, value); } private string createTime; public string CreateTime { - get { return createTime; } - set { SetProperty(ref createTime, value); } + get => createTime; + set => SetProperty(ref createTime, value); } private string playNumber; public string PlayNumber { - get { return playNumber; } - set { SetProperty(ref playNumber, value); } + get => playNumber; + set => SetProperty(ref playNumber, value); } private string likeNumber; public string LikeNumber { - get { return likeNumber; } - set { SetProperty(ref likeNumber, value); } + get => likeNumber; + set => SetProperty(ref likeNumber, value); } private string favoriteNumber; public string FavoriteNumber { - get { return favoriteNumber; } - set { SetProperty(ref favoriteNumber, value); } + get => favoriteNumber; + set => SetProperty(ref favoriteNumber, value); } private string shareNumber; public string ShareNumber { - get { return shareNumber; } - set { SetProperty(ref shareNumber, value); } + get => shareNumber; + set => SetProperty(ref shareNumber, value); } private string description; public string Description { - get { return description; } - set { SetProperty(ref description, value); } + get => description; + set => SetProperty(ref description, value); } private int mediaCount; public int MediaCount { - get { return mediaCount; } - set { SetProperty(ref mediaCount, value); } + get => mediaCount; + set => SetProperty(ref mediaCount, value); } private string upName; public string UpName { - get { return upName; } - set { SetProperty(ref upName, value); } + get => upName; + set => SetProperty(ref upName, value); } private BitmapImage upHeader; public BitmapImage UpHeader { - get { return upHeader; } - set { SetProperty(ref upHeader, value); } + get => upHeader; + set => SetProperty(ref upHeader, value); } } } diff --git a/DownKyi/Models/FavoritesMedia.cs b/DownKyi/ViewModels/PageViewModels/FavoritesMedia.cs similarity index 75% rename from DownKyi/Models/FavoritesMedia.cs rename to DownKyi/ViewModels/PageViewModels/FavoritesMedia.cs index 99f30b8..b9db2a5 100644 --- a/DownKyi/Models/FavoritesMedia.cs +++ b/DownKyi/ViewModels/PageViewModels/FavoritesMedia.cs @@ -1,12 +1,11 @@ using DownKyi.Core.BiliApi.BiliUtils; using DownKyi.Utils; -using DownKyi.ViewModels; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using System.Windows.Media.Imaging; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { public class FavoritesMedia : BindableBase { @@ -26,64 +25,64 @@ namespace DownKyi.Models private bool isSelected; public bool IsSelected { - get { return isSelected; } - set { SetProperty(ref isSelected, value); } + get => isSelected; + set => SetProperty(ref isSelected, value); } private int order; public int Order { - get { return order; } - set { SetProperty(ref order, value); } + get => order; + set => SetProperty(ref order, value); } private BitmapImage cover; public BitmapImage Cover { - get { return cover; } - set { SetProperty(ref cover, value); } + get => cover; + set => SetProperty(ref cover, value); } private string title; public string Title { - get { return title; } - set { SetProperty(ref title, value); } + get => title; + set => SetProperty(ref title, value); } private string playNumber; public string PlayNumber { - get { return playNumber; } - set { SetProperty(ref playNumber, value); } + get => playNumber; + set => SetProperty(ref playNumber, value); } private string danmakuNumber; public string DanmakuNumber { - get { return danmakuNumber; } - set { SetProperty(ref danmakuNumber, value); } + get => danmakuNumber; + set => SetProperty(ref danmakuNumber, value); } private string favoriteNumber; public string FavoriteNumber { - get { return favoriteNumber; } - set { SetProperty(ref favoriteNumber, value); } + get => favoriteNumber; + set => SetProperty(ref favoriteNumber, value); } private string duration; public string Duration { - get { return duration; } - set { SetProperty(ref duration, value); } + get => duration; + set => SetProperty(ref duration, value); } private string upName; public string UpName { - get { return upName; } - set { SetProperty(ref upName, value); } + get => upName; + set => SetProperty(ref upName, value); } #endregion diff --git a/DownKyi/Models/TabHeader.cs b/DownKyi/ViewModels/PageViewModels/TabHeader.cs similarity index 53% rename from DownKyi/Models/TabHeader.cs rename to DownKyi/ViewModels/PageViewModels/TabHeader.cs index 3fb6b17..ad37256 100644 --- a/DownKyi/Models/TabHeader.cs +++ b/DownKyi/ViewModels/PageViewModels/TabHeader.cs @@ -1,36 +1,36 @@ using DownKyi.Images; using Prism.Mvvm; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { public class TabHeader : BindableBase { private int id; public int Id { - get { return id; } - set { SetProperty(ref id, value); } + get => id; + set => SetProperty(ref id, value); } private VectorImage image; public VectorImage Image { - get { return image; } - set { SetProperty(ref image, value); } + get => image; + set => SetProperty(ref image, value); } private string title; public string Title { - get { return title; } - set { SetProperty(ref title, value); } + get => title; + set => SetProperty(ref title, value); } private string subTitle; public string SubTitle { - get { return subTitle; } - set { SetProperty(ref subTitle, value); } + get => subTitle; + set => SetProperty(ref subTitle, value); } } diff --git a/DownKyi/Models/VideoInfoView.cs b/DownKyi/ViewModels/PageViewModels/VideoInfoView.cs similarity index 97% rename from DownKyi/Models/VideoInfoView.cs rename to DownKyi/ViewModels/PageViewModels/VideoInfoView.cs index d0d15d7..c4f93a3 100644 --- a/DownKyi/Models/VideoInfoView.cs +++ b/DownKyi/ViewModels/PageViewModels/VideoInfoView.cs @@ -1,10 +1,8 @@ using Prism.Mvvm; -using System; using System.Windows.Media.Imaging; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { - [Serializable] public class VideoInfoView : BindableBase { public string CoverUrl { get; set; } diff --git a/DownKyi/Models/VideoPage.cs b/DownKyi/ViewModels/PageViewModels/VideoPage.cs similarity index 97% rename from DownKyi/Models/VideoPage.cs rename to DownKyi/ViewModels/PageViewModels/VideoPage.cs index 7b93e92..6d7704e 100644 --- a/DownKyi/Models/VideoPage.cs +++ b/DownKyi/ViewModels/PageViewModels/VideoPage.cs @@ -2,7 +2,7 @@ using Prism.Mvvm; using System.Collections.Generic; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { public class VideoPage : BindableBase { diff --git a/DownKyi/Models/VideoQuality.cs b/DownKyi/ViewModels/PageViewModels/VideoQuality.cs similarity index 95% rename from DownKyi/Models/VideoQuality.cs rename to DownKyi/ViewModels/PageViewModels/VideoQuality.cs index 41b966d..da4bfe2 100644 --- a/DownKyi/Models/VideoQuality.cs +++ b/DownKyi/ViewModels/PageViewModels/VideoQuality.cs @@ -1,7 +1,7 @@ using Prism.Mvvm; using System.Collections.Generic; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { public class VideoQuality : BindableBase { diff --git a/DownKyi/Models/VideoSection.cs b/DownKyi/ViewModels/PageViewModels/VideoSection.cs similarity index 58% rename from DownKyi/Models/VideoSection.cs rename to DownKyi/ViewModels/PageViewModels/VideoSection.cs index 748bc00..5fd4d09 100644 --- a/DownKyi/Models/VideoSection.cs +++ b/DownKyi/ViewModels/PageViewModels/VideoSection.cs @@ -1,7 +1,7 @@ using Prism.Mvvm; using System.Collections.Generic; -namespace DownKyi.Models +namespace DownKyi.ViewModels.PageViewModels { public class VideoSection : BindableBase { @@ -10,22 +10,22 @@ namespace DownKyi.Models private string title; public string Title { - get { return title; } - set { SetProperty(ref title, value); } + get => title; + set => SetProperty(ref title, value); } private bool isSelected; public bool IsSelected { - get { return isSelected; } - set { SetProperty(ref isSelected, value); } + get => isSelected; + set => SetProperty(ref isSelected, value); } private List videoPages; public List VideoPages { - get { return videoPages; } - set { SetProperty(ref videoPages, value); } + get => videoPages; + set => SetProperty(ref videoPages, value); } } } diff --git a/DownKyi/Models/DisplayFileNamePart.cs b/DownKyi/ViewModels/Settings/DisplayFileNamePart.cs similarity index 89% rename from DownKyi/Models/DisplayFileNamePart.cs rename to DownKyi/ViewModels/Settings/DisplayFileNamePart.cs index 4d8ab20..70dcf58 100644 --- a/DownKyi/Models/DisplayFileNamePart.cs +++ b/DownKyi/ViewModels/Settings/DisplayFileNamePart.cs @@ -1,7 +1,7 @@ using DownKyi.Core.FileName; using Prism.Mvvm; -namespace DownKyi.Models +namespace DownKyi.ViewModels.Settings { public class DisplayFileNamePart : BindableBase { diff --git a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs index d100b8c..f2cd1f0 100644 --- a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs +++ b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs @@ -2,7 +2,6 @@ using DownKyi.Core.FileName; using DownKyi.Core.Settings; using DownKyi.Events; -using DownKyi.Models; using DownKyi.Utils; using Prism.Commands; using Prism.Events; diff --git a/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs b/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs index 7125753..74236d9 100644 --- a/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs +++ b/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs @@ -1,8 +1,8 @@ using DownKyi.Events; using DownKyi.Images; -using DownKyi.Models; using DownKyi.Utils; using DownKyi.ViewModels.DownloadManager; +using DownKyi.ViewModels.PageViewModels; using Prism.Commands; using Prism.Events; using Prism.Regions; @@ -21,22 +21,22 @@ namespace DownKyi.ViewModels private VectorImage arrowBack; public VectorImage ArrowBack { - get { return arrowBack; } - set { SetProperty(ref arrowBack, value); } + get => arrowBack; + set => SetProperty(ref arrowBack, value); } private List tabHeaders; public List TabHeaders { - get { return tabHeaders; } - set { SetProperty(ref tabHeaders, value); } + get => tabHeaders; + set => SetProperty(ref tabHeaders, value); } private int selectTabId; public int SelectTabId { - get { return selectTabId; } - set { SetProperty(ref selectTabId, value); } + get => selectTabId; + set => SetProperty(ref selectTabId, value); } #endregion diff --git a/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs b/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs index 7db9b83..87dc5ce 100644 --- a/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs +++ b/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs @@ -1,9 +1,9 @@ using DownKyi.Core.Logging; using DownKyi.Events; using DownKyi.Images; -using DownKyi.Models; using DownKyi.Services; using DownKyi.Utils; +using DownKyi.ViewModels.PageViewModels; using Prism.Commands; using Prism.Events; using Prism.Regions; @@ -23,71 +23,71 @@ namespace DownKyi.ViewModels private string pageName = Tag; public string PageName { - get { return pageName; } - set { SetProperty(ref pageName, value); } + get => pageName; + set => SetProperty(ref pageName, value); } private VectorImage arrowBack; public VectorImage ArrowBack { - get { return arrowBack; } - set { SetProperty(ref arrowBack, value); } + get => arrowBack; + set => SetProperty(ref arrowBack, value); } private VectorImage play; public VectorImage Play { - get { return play; } - set { SetProperty(ref play, value); } + get => play; + set => SetProperty(ref play, value); } private VectorImage like; public VectorImage Like { - get { return like; } - set { SetProperty(ref like, value); } + get => like; + set => SetProperty(ref like, value); } private VectorImage favorite; public VectorImage Favorite { - get { return favorite; } - set { SetProperty(ref favorite, value); } + get => favorite; + set => SetProperty(ref favorite, value); } private VectorImage share; public VectorImage Share { - get { return share; } - set { SetProperty(ref share, value); } + get => share; + set => SetProperty(ref share, value); } private Favorites favorites; public Favorites Favorites { - get { return favorites; } - set { SetProperty(ref favorites, value); } + get => favorites; + set => SetProperty(ref favorites, value); } private ObservableCollection favoritesMedias; public ObservableCollection FavoritesMedias { - get { return favoritesMedias; } - set { SetProperty(ref favoritesMedias, value); } + get => favoritesMedias; + set => SetProperty(ref favoritesMedias, value); } private Visibility contentVisibility; public Visibility ContentVisibility { - get { return contentVisibility; } - set { SetProperty(ref contentVisibility, value); } + get => contentVisibility; + set => SetProperty(ref contentVisibility, value); } private Visibility noDataVisibility; public Visibility NoDataVisibility { - get { return noDataVisibility; } - set { SetProperty(ref noDataVisibility, value); } + get => noDataVisibility; + set => SetProperty(ref noDataVisibility, value); } #endregion diff --git a/DownKyi/ViewModels/ViewSettingsViewModel.cs b/DownKyi/ViewModels/ViewSettingsViewModel.cs index 6518b94..c197f03 100644 --- a/DownKyi/ViewModels/ViewSettingsViewModel.cs +++ b/DownKyi/ViewModels/ViewSettingsViewModel.cs @@ -1,7 +1,7 @@ using DownKyi.Events; using DownKyi.Images; -using DownKyi.Models; using DownKyi.Utils; +using DownKyi.ViewModels.PageViewModels; using DownKyi.ViewModels.Settings; using Prism.Commands; using Prism.Events; @@ -21,22 +21,22 @@ namespace DownKyi.ViewModels private VectorImage arrowBack; public VectorImage ArrowBack { - get { return arrowBack; } - set { SetProperty(ref arrowBack, value); } + get => arrowBack; + set => SetProperty(ref arrowBack, value); } private List tabHeaders; public List TabHeaders { - get { return tabHeaders; } - set { SetProperty(ref tabHeaders, value); } + get => tabHeaders; + set => SetProperty(ref tabHeaders, value); } private int selectTabId; public int SelectTabId { - get { return selectTabId; } - set { SetProperty(ref selectTabId, value); } + get => selectTabId; + set => SetProperty(ref selectTabId, value); } #endregion diff --git a/DownKyi/ViewModels/ViewToolboxViewModel.cs b/DownKyi/ViewModels/ViewToolboxViewModel.cs index e476c17..a161d2d 100644 --- a/DownKyi/ViewModels/ViewToolboxViewModel.cs +++ b/DownKyi/ViewModels/ViewToolboxViewModel.cs @@ -1,7 +1,7 @@ using DownKyi.Events; using DownKyi.Images; -using DownKyi.Models; using DownKyi.Utils; +using DownKyi.ViewModels.PageViewModels; using DownKyi.ViewModels.Toolbox; using Prism.Commands; using Prism.Events; @@ -21,22 +21,22 @@ namespace DownKyi.ViewModels private VectorImage arrowBack; public VectorImage ArrowBack { - get { return arrowBack; } - set { SetProperty(ref arrowBack, value); } + get => arrowBack; + set => SetProperty(ref arrowBack, value); } private List tabHeaders; public List TabHeaders { - get { return tabHeaders; } - set { SetProperty(ref tabHeaders, value); } + get => tabHeaders; + set => SetProperty(ref tabHeaders, value); } private int selectTabId; public int SelectTabId { - get { return selectTabId; } - set { SetProperty(ref selectTabId, value); } + get => selectTabId; + set => SetProperty(ref selectTabId, value); } #endregion diff --git a/DownKyi/ViewModels/ViewVideoDetailViewModel.cs b/DownKyi/ViewModels/ViewVideoDetailViewModel.cs index b9a4b19..11486e3 100644 --- a/DownKyi/ViewModels/ViewVideoDetailViewModel.cs +++ b/DownKyi/ViewModels/ViewVideoDetailViewModel.cs @@ -1,4 +1,5 @@ using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.VideoStream; using DownKyi.Core.BiliApi.Zone; using DownKyi.Core.FileName; using DownKyi.Core.Logging; @@ -11,6 +12,8 @@ using DownKyi.Models; using DownKyi.Services; using DownKyi.Utils; using DownKyi.ViewModels.Dialogs; +using DownKyi.ViewModels.DownloadManager; +using DownKyi.ViewModels.PageViewModels; using Prism.Commands; using Prism.Events; using Prism.Regions; @@ -22,7 +25,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; -using System.Windows.Media; namespace DownKyi.ViewModels { @@ -568,7 +570,7 @@ namespace DownKyi.ViewModels // 如果存在正在下载列表,则跳过,并提示 foreach (DownloadingItem item in App.DownloadingList) { - if (item.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec) + if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec) { eventAggregator.GetEvent().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloading")}"); continue; @@ -578,7 +580,7 @@ namespace DownKyi.ViewModels // 如果存在下载完成列表,弹出选择框是否再次下载 foreach (DownloadedItem item in App.DownloadedList) { - if (item.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec) + if (item.DownloadBase.Cid == page.Cid && item.Resolution.Id == page.VideoQuality.Quality && item.AudioCodec.Name == page.AudioQualityFormat && item.VideoCodecName == page.VideoQuality.SelectedVideoCodec) { eventAggregator.GetEvent().Publish($"{page.Name}{DictionaryResource.GetString("TipAlreadyToAddDownloaded")}"); continue; @@ -661,18 +663,16 @@ namespace DownKyi.ViewModels } // 如果不存在,直接添加到下载列表 - DownloadingItem downloading = new DownloadingItem + DownloadBase downloadBase = new DownloadBase { - PlayUrl = page.PlayUrl, - Bvid = page.Bvid, Avid = page.Avid, Cid = page.Cid, EpisodeId = page.EpisodeId, - CoverUrl = VideoInfoView.CoverUrl, PageCoverUrl = page.FirstFrame, - ZoneImage = (DrawingImage)Application.Current.Resources[VideoZoneIcon.Instance().GetZoneImageKey(zoneId)], + ZoneId = zoneId, + FilePath = filePath, Order = page.Order, MainTitle = VideoInfoView.Title, @@ -681,21 +681,30 @@ namespace DownKyi.ViewModels VideoCodecName = page.VideoQuality.SelectedVideoCodec, Resolution = new Quality { Name = page.VideoQuality.QualityFormat, Id = page.VideoQuality.Quality }, AudioCodec = Constant.GetAudioQualities().FirstOrDefault(t => { return t.Name == page.AudioQualityFormat; }), - FilePath = filePath, - + }; + Downloading downloading = new Downloading + { PlayStreamType = playStreamType, DownloadStatus = DownloadStatus.NOT_STARTED, }; // 需要下载的内容 - downloading.NeedDownloadContent["downloadAudio"] = downloadAudio; - downloading.NeedDownloadContent["downloadVideo"] = downloadVideo; - downloading.NeedDownloadContent["downloadDanmaku"] = downloadDanmaku; - downloading.NeedDownloadContent["downloadSubtitle"] = downloadSubtitle; - downloading.NeedDownloadContent["downloadCover"] = downloadCover; + downloadBase.NeedDownloadContent["downloadAudio"] = downloadAudio; + downloadBase.NeedDownloadContent["downloadVideo"] = downloadVideo; + downloadBase.NeedDownloadContent["downloadDanmaku"] = downloadDanmaku; + downloadBase.NeedDownloadContent["downloadSubtitle"] = downloadSubtitle; + downloadBase.NeedDownloadContent["downloadCover"] = downloadCover; + + DownloadingItem downloadingItem = new DownloadingItem + { + DownloadBase = downloadBase, + Downloading = downloading, + PlayUrl = page.PlayUrl, + //ZoneImage = (DrawingImage)Application.Current.Resources[VideoZoneIcon.Instance().GetZoneImageKey(zoneId)], + }; // 添加到下载列表 - App.DownloadingList.Add(downloading); + App.DownloadingList.Add(downloadingItem); i++; } } diff --git a/DownKyi/Views/DownloadManager/ViewDownloadFinished.xaml b/DownKyi/Views/DownloadManager/ViewDownloadFinished.xaml index 1c03fd9..49b63b6 100644 --- a/DownKyi/Views/DownloadManager/ViewDownloadFinished.xaml +++ b/DownKyi/Views/DownloadManager/ViewDownloadFinished.xaml @@ -2,9 +2,303 @@ x:Class="DownKyi.Views.DownloadManager.ViewDownloadFinished" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:converter="clr-namespace:DownKyi.Converter" + xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> + + + + + + - 已下载 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +