mirror of
https://github.com/leiurayer/downkyi.git
synced 2025-04-27 05:30:47 +08:00
下载列表的数据库设计;异常处理;整理代码
This commit is contained in:
parent
9f443cb809
commit
740abfa602
src
DownKyi.Core
DownKyi
App.xaml.cs
Converter
DownKyi.csprojImages
Languages
Models
Resources
Services
BangumiInfoService.csCheeseInfoService.cs
Download
FavoritesService.csIFavoritesService.csIInfoService.csUtils.csVideoInfoService.csUtils
ViewModels
BaseViewModel.cs
DownloadManager
DownloadBaseItem.csDownloadedItem.csDownloadingItem.csViewDownloadFinishedViewModel.csViewDownloadingViewModel.cs
PageViewModels
Settings
ViewDownloadManagerViewModel.csViewPublicFavoritesViewModel.csViewSettingsViewModel.csViewToolboxViewModel.csViewVideoDetailViewModel.csViews/DownloadManager
@ -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;
|
||||
|
||||
|
9
src/DownKyi.Core/BiliApi/VideoStream/PlayStreamType.cs
Normal file
9
src/DownKyi.Core/BiliApi/VideoStream/PlayStreamType.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace DownKyi.Core.BiliApi.VideoStream
|
||||
{
|
||||
public enum PlayStreamType
|
||||
{
|
||||
VIDEO = 1, // 普通视频
|
||||
BANGUMI, // 番剧、电影、电视剧等
|
||||
CHEESE, // 课程
|
||||
}
|
||||
}
|
@ -174,6 +174,7 @@
|
||||
<Compile Include="BiliApi\VideoStream\Models\PlayUrlSupportFormat.cs" />
|
||||
<Compile Include="BiliApi\VideoStream\Models\Subtitle.cs" />
|
||||
<Compile Include="BiliApi\VideoStream\Models\SubtitleInfo.cs" />
|
||||
<Compile Include="BiliApi\VideoStream\PlayStreamType.cs" />
|
||||
<Compile Include="BiliApi\VideoStream\VideoStream.cs" />
|
||||
<Compile Include="BiliApi\Video\Dynamic.cs" />
|
||||
<Compile Include="BiliApi\Video\Models\RankingVideoView.cs" />
|
||||
@ -239,6 +240,10 @@
|
||||
<Compile Include="Settings\Models\VideoSettings.cs" />
|
||||
<Compile Include="Settings\SettingsManager.cs" />
|
||||
<Compile Include="Storage\Constant.cs" />
|
||||
<Compile Include="Storage\Database\Download\DownloadBaseDb.cs" />
|
||||
<Compile Include="Storage\Database\Download\DownloadDb.cs" />
|
||||
<Compile Include="Storage\Database\Download\DownloadedDb.cs" />
|
||||
<Compile Include="Storage\Database\Download\DownloadingDb.cs" />
|
||||
<Compile Include="Storage\Database\Header.cs" />
|
||||
<Compile Include="Storage\Database\HeaderDb.cs" />
|
||||
<Compile Include="Storage\StorageCover.cs" />
|
||||
|
@ -63,7 +63,7 @@ namespace DownKyi.Core.Settings
|
||||
/// <returns></returns>
|
||||
private bool SetSettings()
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(appSettings, Formatting.Indented);
|
||||
string json = JsonConvert.SerializeObject(appSettings);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -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";
|
||||
|
||||
// 配置
|
||||
|
@ -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)
|
||||
@ -56,7 +57,7 @@ namespace DownKyi.Core.Storage.Database
|
||||
Utils.Debugging.Console.PrintLine("Update()发生异常: {0}", e);
|
||||
LogManager.Error("CoverDb", e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -65,7 +66,7 @@ namespace DownKyi.Core.Storage.Database
|
||||
/// <returns></returns>
|
||||
public List<Cover> QueryAll()
|
||||
{
|
||||
string sql = $"select * from cover";
|
||||
string sql = $"select * from {tableName}";
|
||||
return Query(sql);
|
||||
}
|
||||
|
||||
@ -76,17 +77,10 @@ namespace DownKyi.Core.Storage.Database
|
||||
/// <returns></returns>
|
||||
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<Cover> query = Query(sql);
|
||||
|
||||
if (query.Count > 0)
|
||||
{
|
||||
return query[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return query.Count > 0 ? query[0] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -96,7 +90,7 @@ namespace DownKyi.Core.Storage.Database
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ namespace DownKyi.Core.Storage.Database
|
||||
/// 执行一条SQL语句
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
public void ExecuteNonQuery(string sql)
|
||||
public void ExecuteNonQuery(string sql, Action<SQLiteParameterCollection> 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();
|
||||
|
11
src/DownKyi.Core/Storage/Database/Download/DownloadBaseDb.cs
Normal file
11
src/DownKyi.Core/Storage/Database/Download/DownloadBaseDb.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace DownKyi.Core.Storage.Database.Download
|
||||
{
|
||||
public class DownloadBaseDb : DownloadDb
|
||||
{
|
||||
public DownloadBaseDb()
|
||||
{
|
||||
tableName = "download_base";
|
||||
CreateTable();
|
||||
}
|
||||
}
|
||||
}
|
113
src/DownKyi.Core/Storage/Database/Download/DownloadDb.cs
Normal file
113
src/DownKyi.Core/Storage/Database/Download/DownloadDb.cs
Normal file
@ -0,0 +1,113 @@
|
||||
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(), key);
|
||||
protected string tableName = "download";
|
||||
|
||||
/// <summary>
|
||||
/// 关闭数据库连接
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
dbHelper.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插入新的数据
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
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<SQLiteParameterCollection>((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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询所有数据
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, object> QueryAll()
|
||||
{
|
||||
string sql = $"select * from {tableName}";
|
||||
return Query(sql);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询数据
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
private Dictionary<string, object> Query(string sql)
|
||||
{
|
||||
Dictionary<string, object> objects = new Dictionary<string, object>();
|
||||
|
||||
dbHelper.ExecuteQuery(sql, reader =>
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
// 读取字节数组
|
||||
byte[] array = (byte[])reader["data"];
|
||||
// 定义一个流
|
||||
MemoryStream stream = new MemoryStream(null);
|
||||
//定义一个格式化器
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
// 反序列化
|
||||
object obj = formatter.Deserialize(stream);
|
||||
|
||||
objects.Add((string)reader["id"], obj);
|
||||
}
|
||||
});
|
||||
return objects;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 如果表不存在则创建表
|
||||
/// </summary>
|
||||
protected void CreateTable()
|
||||
{
|
||||
string sql = $"create table if not exists {tableName} (id varchar(255) unique, data blob)";
|
||||
dbHelper.ExecuteNonQuery(sql);
|
||||
}
|
||||
}
|
||||
}
|
11
src/DownKyi.Core/Storage/Database/Download/DownloadedDb.cs
Normal file
11
src/DownKyi.Core/Storage/Database/Download/DownloadedDb.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace DownKyi.Core.Storage.Database.Download
|
||||
{
|
||||
public class DownloadedDb : DownloadDb
|
||||
{
|
||||
public DownloadedDb()
|
||||
{
|
||||
tableName = "downloaded";
|
||||
CreateTable();
|
||||
}
|
||||
}
|
||||
}
|
11
src/DownKyi.Core/Storage/Database/Download/DownloadingDb.cs
Normal file
11
src/DownKyi.Core/Storage/Database/Download/DownloadingDb.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace DownKyi.Core.Storage.Database.Download
|
||||
{
|
||||
public class DownloadingDb : DownloadDb
|
||||
{
|
||||
public DownloadingDb()
|
||||
{
|
||||
tableName = "downloading";
|
||||
CreateTable();
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
/// <returns></returns>
|
||||
public List<Header> QueryAll()
|
||||
{
|
||||
string sql = $"select * from header";
|
||||
string sql = $"select * from {tableName}";
|
||||
return Query(sql);
|
||||
}
|
||||
|
||||
@ -75,17 +76,10 @@ namespace DownKyi.Core.Storage.Database
|
||||
/// <returns></returns>
|
||||
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<Header> 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
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,26 @@ namespace DownKyi.Core.Storage
|
||||
{
|
||||
public static class StorageManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取历史记录的文件路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetAriaDir()
|
||||
{
|
||||
CreateDirectory(Constant.Aria);
|
||||
return Constant.Aria;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取历史记录的文件路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetDownload()
|
||||
{
|
||||
CreateDirectory(Constant.Database);
|
||||
return Constant.Download;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取历史记录的文件路径
|
||||
/// </summary>
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DownKyi.Models;
|
||||
using DownKyi.Core.Settings;
|
||||
using DownKyi.Services.Download;
|
||||
using DownKyi.Utils;
|
||||
using DownKyi.ViewModels;
|
||||
@ -13,7 +13,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 +106,39 @@ namespace DownKyi
|
||||
Current.Dispatcher.Invoke(callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载完成列表排序
|
||||
/// </summary>
|
||||
/// <param name="finishedSort"></param>
|
||||
public static void SortDownloadedList(DownloadFinishedSort finishedSort)
|
||||
{
|
||||
List<DownloadedItem> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
21
src/DownKyi/Converter/CountConverter.cs
Normal file
21
src/DownKyi/Converter/CountConverter.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace DownKyi.Converter
|
||||
{
|
||||
public class CountConverter : IValueConverter
|
||||
{
|
||||
public int Count { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return ((int)value) > Count;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -79,6 +79,7 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Converter\CountConverter.cs" />
|
||||
<Compile Include="CustomControl\GifImage.cs" />
|
||||
<Compile Include="Events\MessageEvent.cs" />
|
||||
<Compile Include="Events\NavigationEvent.cs" />
|
||||
@ -87,20 +88,19 @@
|
||||
<Compile Include="Images\LogoIcon.cs" />
|
||||
<Compile Include="Images\NavigationIcon.cs" />
|
||||
<Compile Include="Images\NormalIcon.cs" />
|
||||
<Compile Include="Models\DownloadBaseItem.cs" />
|
||||
<Compile Include="Models\DownloadedItem.cs" />
|
||||
<Compile Include="Models\DownloadingItem.cs" />
|
||||
<Compile Include="Models\DownloadBase.cs" />
|
||||
<Compile Include="Models\Downloaded.cs" />
|
||||
<Compile Include="Models\Downloading.cs" />
|
||||
<Compile Include="Models\DownloadStatus.cs" />
|
||||
<Compile Include="Models\Favorites.cs" />
|
||||
<Compile Include="Models\FavoritesMedia.cs" />
|
||||
<Compile Include="Models\DisplayFileNamePart.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\Favorites.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\FavoritesMedia.cs" />
|
||||
<Compile Include="ViewModels\Settings\DisplayFileNamePart.cs" />
|
||||
<Compile Include="Models\ParseScopeDisplay.cs" />
|
||||
<Compile Include="Models\PlayStreamType.cs" />
|
||||
<Compile Include="Models\TabHeader.cs" />
|
||||
<Compile Include="Models\VideoQuality.cs" />
|
||||
<Compile Include="Models\VideoInfoView.cs" />
|
||||
<Compile Include="Models\VideoPage.cs" />
|
||||
<Compile Include="Models\VideoSection.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\TabHeader.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\VideoQuality.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\VideoInfoView.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\VideoPage.cs" />
|
||||
<Compile Include="ViewModels\PageViewModels\VideoSection.cs" />
|
||||
<Compile Include="Services\BangumiInfoService.cs" />
|
||||
<Compile Include="Services\CheeseInfoService.cs" />
|
||||
<Compile Include="Services\Download\AriaDownloadService.cs" />
|
||||
@ -118,6 +118,9 @@
|
||||
<Compile Include="ViewModels\BaseViewModel.cs" />
|
||||
<Compile Include="ViewModels\Dialogs\ViewDownloadSetterViewModel.cs" />
|
||||
<Compile Include="ViewModels\Dialogs\BaseDialogViewModel.cs" />
|
||||
<Compile Include="ViewModels\DownloadManager\DownloadBaseItem.cs" />
|
||||
<Compile Include="ViewModels\DownloadManager\DownloadedItem.cs" />
|
||||
<Compile Include="ViewModels\DownloadManager\DownloadingItem.cs" />
|
||||
<Compile Include="ViewModels\Settings\ViewBasicViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\ViewAboutViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\ViewDanmakuViewModel.cs" />
|
||||
@ -447,6 +450,7 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Resource Include="Resources\checked.png" />
|
||||
<Resource Include="Resources\nodata02.png" />
|
||||
<Content Include="打不开DownKyi请点我.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -91,6 +91,12 @@
|
||||
<system:String x:Key="ContinueAllDownloading">全部开始</system:String>
|
||||
<system:String x:Key="DeleteAllDownloading">全部删除</system:String>
|
||||
|
||||
<system:String x:Key="TotalDownloaded1">已下载</system:String>
|
||||
<system:String x:Key="TotalDownloaded2">个视频!</system:String>
|
||||
<system:String x:Key="DownloadedSortByTime">按下载先后排序</system:String>
|
||||
<system:String x:Key="DownloadedSortByOrder">按序号排序</system:String>
|
||||
<system:String x:Key="ClearAllDownloaded">清空所有记录</system:String>
|
||||
|
||||
<!-- Settings -->
|
||||
<system:String x:Key="PressEnterToApplySettingTip">按回车键应用设置</system:String>
|
||||
|
||||
|
75
src/DownKyi/Models/DownloadBase.cs
Normal file
75
src/DownKyi/Models/DownloadBase.cs
Normal file
@ -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<string, bool>
|
||||
{
|
||||
{ "downloadAudio", true },
|
||||
{ "downloadVideo", true },
|
||||
{ "downloadDanmaku", true },
|
||||
{ "downloadSubtitle", true },
|
||||
{ "downloadCover", true }
|
||||
};
|
||||
}
|
||||
|
||||
// 此条下载项的id
|
||||
public string Uuid { get; }
|
||||
|
||||
// 需要下载的内容
|
||||
public Dictionary<string, bool> 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; }
|
||||
|
||||
}
|
||||
}
|
30
src/DownKyi/Models/Downloaded.cs
Normal file
30
src/DownKyi/Models/Downloaded.cs
Normal file
@ -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; }
|
||||
|
||||
}
|
||||
}
|
47
src/DownKyi/Models/Downloading.cs
Normal file
47
src/DownKyi/Models/Downloading.cs
Normal file
@ -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<string>();
|
||||
}
|
||||
|
||||
// Aria相关
|
||||
public string Gid { get; set; }
|
||||
|
||||
// 下载的文件
|
||||
public List<string> 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; }
|
||||
|
||||
}
|
||||
}
|
BIN
src/DownKyi/Resources/nodata02.png
Normal file
BIN
src/DownKyi/Resources/nodata02.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 11 KiB |
@ -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<VideoPage> pages = new List<VideoPage>();
|
||||
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
|
||||
/// <param name="page"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
/// <param name="page"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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<string> srtFiles = new List<string>();
|
||||
|
||||
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<string> 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> ariaPause = AriaClient.PauseAsync(downloading.Gid);
|
||||
Task<AriaPause> ariaPause = AriaClient.PauseAsync(downloading.Downloading.Gid);
|
||||
// 通知UI,并阻塞当前线程
|
||||
Pause(downloading);
|
||||
break;
|
||||
case DownloadStatus.DOWNLOADING:
|
||||
Task<AriaPause> ariaUnpause = AriaClient.UnpauseAsync(downloading.Gid);
|
||||
Task<AriaPause> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DownKyi.Models;
|
||||
using DownKyi.ViewModels.DownloadManager;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace DownKyi.Services.Download
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DownKyi.Models;
|
||||
using DownKyi.ViewModels.DownloadManager;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.Services.Download
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DownKyi.Models;
|
||||
using DownKyi.ViewModels.PageViewModels;
|
||||
using Prism.Events;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DownKyi.Models;
|
||||
using DownKyi.ViewModels.PageViewModels;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.Services
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
/// 获取视频剧集
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<Models.VideoPage> GetVideoPages()
|
||||
public List<ViewModels.PageViewModels.VideoPage> GetVideoPages()
|
||||
{
|
||||
if (videoView == null) { return null; }
|
||||
if (videoView.Pages == null) { return null; }
|
||||
if (videoView.Pages.Count == 0) { return null; }
|
||||
|
||||
List<Models.VideoPage> videoPages = new List<Models.VideoPage>();
|
||||
List<ViewModels.PageViewModels.VideoPage> videoPages = new List<ViewModels.PageViewModels.VideoPage>();
|
||||
|
||||
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<Models.VideoPage> pages = new List<Models.VideoPage>();
|
||||
List<ViewModels.PageViewModels.VideoPage> pages = new List<ViewModels.PageViewModels.VideoPage>();
|
||||
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返回
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
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);
|
||||
|
@ -15,8 +15,10 @@ namespace DownKyi.Utils
|
||||
/// <returns></returns>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -41,6 +41,8 @@ namespace DownKyi.ViewModels
|
||||
/// <param name="callback"></param>
|
||||
protected void PropertyChangeAsync(Action callback)
|
||||
{
|
||||
if (Application.Current == null) { return; }
|
||||
|
||||
Application.Current.Dispatcher.Invoke(callback);
|
||||
}
|
||||
|
||||
|
122
src/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs
Normal file
122
src/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs
Normal file
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
122
src/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs
Normal file
122
src/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs
Normal file
@ -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));
|
||||
|
||||
/// <summary>
|
||||
/// 打开文件夹事件
|
||||
/// </summary>
|
||||
private void ExecuteOpenFolderCommand()
|
||||
{
|
||||
string videoPath = $"{DownloadBase.FilePath}.mp4";
|
||||
if (File.Exists(videoPath))
|
||||
{
|
||||
System.Diagnostics.Process.Start("Explorer", "/select," + videoPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
//eventAggregator.GetEvent<MessageEvent>().Publish("没有找到视频文件,可能被删除或移动!");
|
||||
}
|
||||
}
|
||||
|
||||
// 打开视频事件
|
||||
private DelegateCommand openVideoCommand;
|
||||
public DelegateCommand OpenVideoCommand => openVideoCommand ?? (openVideoCommand = new DelegateCommand(ExecuteOpenVideoCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 打开视频事件
|
||||
/// </summary>
|
||||
private void ExecuteOpenVideoCommand()
|
||||
{
|
||||
string videoPath = $"{DownloadBase.FilePath}.mp4";
|
||||
if (File.Exists(videoPath))
|
||||
{
|
||||
System.Diagnostics.Process.Start(videoPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
//eventAggregator.GetEvent<MessageEvent>().Publish(DictionaryResource.GetString("TipAddDownloadingZero"));
|
||||
//eventAggregator.GetEvent<MessageEvent>().Publish("没有找到视频文件,可能被删除或移动!");
|
||||
}
|
||||
}
|
||||
|
||||
// 删除事件
|
||||
private DelegateCommand removeVideoCommand;
|
||||
public DelegateCommand RemoveVideoCommand => removeVideoCommand ?? (removeVideoCommand = new DelegateCommand(ExecuteRemoveVideoCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 删除事件
|
||||
/// </summary>
|
||||
private void ExecuteRemoveVideoCommand()
|
||||
{
|
||||
App.DownloadedList.Remove(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
165
src/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs
Normal file
165
src/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs
Normal file
@ -0,0 +1,165 @@
|
||||
using DownKyi.Core.BiliApi.VideoStream.Models;
|
||||
using DownKyi.Images;
|
||||
using DownKyi.Models;
|
||||
using DownKyi.Utils;
|
||||
using Prism.Commands;
|
||||
|
||||
namespace DownKyi.ViewModels.DownloadManager
|
||||
{
|
||||
public class DownloadingItem : DownloadBaseItem
|
||||
{
|
||||
public DownloadingItem() : base()
|
||||
{
|
||||
// 暂停继续按钮
|
||||
StartOrPause = ButtonIcon.Instance().Pause;
|
||||
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
|
||||
// 删除按钮
|
||||
Delete = ButtonIcon.Instance().Delete;
|
||||
Delete.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
}
|
||||
|
||||
// model数据
|
||||
public Downloading Downloading { get; set; }
|
||||
|
||||
// 视频流链接
|
||||
public PlayUrl PlayUrl { get; set; }
|
||||
|
||||
// 正在下载内容(音频、视频、弹幕、字幕、封面)
|
||||
public string DownloadContent
|
||||
{
|
||||
get => Downloading.DownloadContent;
|
||||
set
|
||||
{
|
||||
Downloading.DownloadContent = value;
|
||||
RaisePropertyChanged("DownloadContent");
|
||||
}
|
||||
}
|
||||
|
||||
// 下载状态显示
|
||||
public string DownloadStatusTitle
|
||||
{
|
||||
get => Downloading.DownloadStatusTitle;
|
||||
set
|
||||
{
|
||||
Downloading.DownloadStatusTitle = value;
|
||||
RaisePropertyChanged("DownloadStatusTitle");
|
||||
}
|
||||
}
|
||||
|
||||
// 下载进度
|
||||
public float Progress
|
||||
{
|
||||
get => Downloading.Progress;
|
||||
set
|
||||
{
|
||||
Downloading.Progress = value;
|
||||
RaisePropertyChanged("Progress");
|
||||
}
|
||||
}
|
||||
|
||||
// 已下载大小/文件大小
|
||||
public string DownloadingFileSize
|
||||
{
|
||||
get => Downloading.DownloadingFileSize;
|
||||
set
|
||||
{
|
||||
Downloading.DownloadingFileSize = value;
|
||||
RaisePropertyChanged("DownloadingFileSize");
|
||||
}
|
||||
}
|
||||
|
||||
// 下载速度
|
||||
public string SpeedDisplay
|
||||
{
|
||||
get => Downloading.SpeedDisplay;
|
||||
set
|
||||
{
|
||||
Downloading.SpeedDisplay = value;
|
||||
RaisePropertyChanged("SpeedDisplay");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region 控制按钮
|
||||
|
||||
private VectorImage startOrPause;
|
||||
public VectorImage StartOrPause
|
||||
{
|
||||
get => startOrPause;
|
||||
set => SetProperty(ref startOrPause, value);
|
||||
}
|
||||
|
||||
private VectorImage delete;
|
||||
public VectorImage Delete
|
||||
{
|
||||
get => delete;
|
||||
set => SetProperty(ref delete, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 命令申明
|
||||
|
||||
// 下载列表暂停继续事件
|
||||
private DelegateCommand startOrPauseCommand;
|
||||
public DelegateCommand StartOrPauseCommand => startOrPauseCommand ?? (startOrPauseCommand = new DelegateCommand(ExecuteStartOrPauseCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 下载列表暂停继续事件
|
||||
/// </summary>
|
||||
private void ExecuteStartOrPauseCommand()
|
||||
{
|
||||
switch (Downloading.DownloadStatus)
|
||||
{
|
||||
case DownloadStatus.NOT_STARTED:
|
||||
case DownloadStatus.WAIT_FOR_DOWNLOAD:
|
||||
Downloading.DownloadStatus = DownloadStatus.PAUSE_STARTED;
|
||||
StartOrPause = ButtonIcon.Instance().Start;
|
||||
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
break;
|
||||
case DownloadStatus.PAUSE_STARTED:
|
||||
Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD;
|
||||
StartOrPause = ButtonIcon.Instance().Pause;
|
||||
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
break;
|
||||
case DownloadStatus.PAUSE:
|
||||
Downloading.DownloadStatus = DownloadStatus.DOWNLOADING;
|
||||
StartOrPause = ButtonIcon.Instance().Pause;
|
||||
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
break;
|
||||
case DownloadStatus.DOWNLOADING:
|
||||
Downloading.DownloadStatus = DownloadStatus.PAUSE;
|
||||
StartOrPause = ButtonIcon.Instance().Start;
|
||||
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
break;
|
||||
case DownloadStatus.DOWNLOAD_SUCCEED:
|
||||
// 下载成功后会从下载列表中删除
|
||||
// 不会出现此分支
|
||||
break;
|
||||
case DownloadStatus.DOWNLOAD_FAILED:
|
||||
Downloading.DownloadStatus = DownloadStatus.WAIT_FOR_DOWNLOAD;
|
||||
StartOrPause = ButtonIcon.Instance().Pause;
|
||||
StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 下载列表删除事件
|
||||
private DelegateCommand deleteCommand;
|
||||
public DelegateCommand DeleteCommand => deleteCommand ?? (deleteCommand = new DelegateCommand(ExecuteDeleteCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 下载列表删除事件
|
||||
/// </summary>
|
||||
private void ExecuteDeleteCommand()
|
||||
{
|
||||
App.DownloadingList.Remove(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@ -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<DownloadedItem> downloadedList;
|
||||
public ObservableCollection<DownloadedItem> 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<object> finishedSortCommand;
|
||||
public DelegateCommand<object> FinishedSortCommand => finishedSortCommand ?? (finishedSortCommand = new DelegateCommand<object>(ExecuteFinishedSortCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 下载完成列表排序事件
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
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));
|
||||
|
||||
/// <summary>
|
||||
/// 清空下载完成列表事件
|
||||
/// </summary>
|
||||
private void ExecuteClearAllDownloadedCommand()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
88
src/DownKyi/ViewModels/PageViewModels/Favorites.cs
Normal file
88
src/DownKyi/ViewModels/PageViewModels/Favorites.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using Prism.Mvvm;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class Favorites : BindableBase
|
||||
{
|
||||
public string CoverUrl { get; set; }
|
||||
public long UpperMid { get; set; }
|
||||
|
||||
private BitmapImage cover;
|
||||
public BitmapImage Cover
|
||||
{
|
||||
get => cover;
|
||||
set => SetProperty(ref cover, value);
|
||||
}
|
||||
|
||||
private string title;
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
private string createTime;
|
||||
public string CreateTime
|
||||
{
|
||||
get => createTime;
|
||||
set => SetProperty(ref createTime, value);
|
||||
}
|
||||
|
||||
private string playNumber;
|
||||
public string PlayNumber
|
||||
{
|
||||
get => playNumber;
|
||||
set => SetProperty(ref playNumber, value);
|
||||
}
|
||||
|
||||
private string likeNumber;
|
||||
public string LikeNumber
|
||||
{
|
||||
get => likeNumber;
|
||||
set => SetProperty(ref likeNumber, value);
|
||||
}
|
||||
|
||||
private string favoriteNumber;
|
||||
public string FavoriteNumber
|
||||
{
|
||||
get => favoriteNumber;
|
||||
set => SetProperty(ref favoriteNumber, value);
|
||||
}
|
||||
|
||||
private string shareNumber;
|
||||
public string ShareNumber
|
||||
{
|
||||
get => shareNumber;
|
||||
set => SetProperty(ref shareNumber, value);
|
||||
}
|
||||
|
||||
private string description;
|
||||
public string Description
|
||||
{
|
||||
get => description;
|
||||
set => SetProperty(ref description, value);
|
||||
}
|
||||
|
||||
private int mediaCount;
|
||||
public int MediaCount
|
||||
{
|
||||
get => mediaCount;
|
||||
set => SetProperty(ref mediaCount, value);
|
||||
}
|
||||
|
||||
private string upName;
|
||||
public string UpName
|
||||
{
|
||||
get => upName;
|
||||
set => SetProperty(ref upName, value);
|
||||
}
|
||||
|
||||
private BitmapImage upHeader;
|
||||
public BitmapImage UpHeader
|
||||
{
|
||||
get => upHeader;
|
||||
set => SetProperty(ref upHeader, value);
|
||||
}
|
||||
}
|
||||
}
|
125
src/DownKyi/ViewModels/PageViewModels/FavoritesMedia.cs
Normal file
125
src/DownKyi/ViewModels/PageViewModels/FavoritesMedia.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using DownKyi.Core.BiliApi.BiliUtils;
|
||||
using DownKyi.Utils;
|
||||
using Prism.Commands;
|
||||
using Prism.Events;
|
||||
using Prism.Mvvm;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class FavoritesMedia : BindableBase
|
||||
{
|
||||
protected readonly IEventAggregator eventAggregator;
|
||||
|
||||
public FavoritesMedia(IEventAggregator eventAggregator)
|
||||
{
|
||||
this.eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
public long Avid { get; set; }
|
||||
public string Bvid { get; set; }
|
||||
public long UpperMid { get; set; }
|
||||
|
||||
#region 页面属性申明
|
||||
|
||||
private bool isSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get => isSelected;
|
||||
set => SetProperty(ref isSelected, value);
|
||||
}
|
||||
|
||||
private int order;
|
||||
public int Order
|
||||
{
|
||||
get => order;
|
||||
set => SetProperty(ref order, value);
|
||||
}
|
||||
|
||||
private BitmapImage cover;
|
||||
public BitmapImage Cover
|
||||
{
|
||||
get => cover;
|
||||
set => SetProperty(ref cover, value);
|
||||
}
|
||||
|
||||
private string title;
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
private string playNumber;
|
||||
public string PlayNumber
|
||||
{
|
||||
get => playNumber;
|
||||
set => SetProperty(ref playNumber, value);
|
||||
}
|
||||
|
||||
private string danmakuNumber;
|
||||
public string DanmakuNumber
|
||||
{
|
||||
get => danmakuNumber;
|
||||
set => SetProperty(ref danmakuNumber, value);
|
||||
}
|
||||
|
||||
private string favoriteNumber;
|
||||
public string FavoriteNumber
|
||||
{
|
||||
get => favoriteNumber;
|
||||
set => SetProperty(ref favoriteNumber, value);
|
||||
}
|
||||
|
||||
private string duration;
|
||||
public string Duration
|
||||
{
|
||||
get => duration;
|
||||
set => SetProperty(ref duration, value);
|
||||
}
|
||||
|
||||
private string upName;
|
||||
public string UpName
|
||||
{
|
||||
get => upName;
|
||||
set => SetProperty(ref upName, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 命令申明
|
||||
|
||||
// 视频标题点击事件
|
||||
private DelegateCommand<object> titleCommand;
|
||||
public DelegateCommand<object> TitleCommand => titleCommand ?? (titleCommand = new DelegateCommand<object>(ExecuteTitleCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 视频标题点击事件
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
private void ExecuteTitleCommand(object parameter)
|
||||
{
|
||||
if (!(parameter is string tag)) { return; }
|
||||
|
||||
NavigateToView.NavigationView(eventAggregator, ViewVideoDetailViewModel.Tag, tag, $"{ParseEntrance.VideoUrl}{Bvid}");
|
||||
}
|
||||
|
||||
// 视频的UP主点击事件
|
||||
private DelegateCommand<object> videoUpperCommand;
|
||||
public DelegateCommand<object> VideoUpperCommand => videoUpperCommand ?? (videoUpperCommand = new DelegateCommand<object>(ExecuteVideoUpperCommand));
|
||||
|
||||
/// <summary>
|
||||
/// 视频的UP主点击事件
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
private void ExecuteVideoUpperCommand(object parameter)
|
||||
{
|
||||
if (!(parameter is string tag)) { return; }
|
||||
|
||||
NavigateToView.NavigateToViewUserSpace(eventAggregator, tag, UpperMid);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
37
src/DownKyi/ViewModels/PageViewModels/TabHeader.cs
Normal file
37
src/DownKyi/ViewModels/PageViewModels/TabHeader.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using DownKyi.Images;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class TabHeader : BindableBase
|
||||
{
|
||||
private int id;
|
||||
public int Id
|
||||
{
|
||||
get => id;
|
||||
set => SetProperty(ref id, value);
|
||||
}
|
||||
|
||||
private VectorImage image;
|
||||
public VectorImage Image
|
||||
{
|
||||
get => image;
|
||||
set => SetProperty(ref image, value);
|
||||
}
|
||||
|
||||
private string title;
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
private string subTitle;
|
||||
public string SubTitle
|
||||
{
|
||||
get => subTitle;
|
||||
set => SetProperty(ref subTitle, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
111
src/DownKyi/ViewModels/PageViewModels/VideoInfoView.cs
Normal file
111
src/DownKyi/ViewModels/PageViewModels/VideoInfoView.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using Prism.Mvvm;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class VideoInfoView : BindableBase
|
||||
{
|
||||
public string CoverUrl { get; set; }
|
||||
public long UpperMid { get; set; }
|
||||
public int TypeId { get; set; }
|
||||
|
||||
private BitmapImage cover;
|
||||
public BitmapImage Cover
|
||||
{
|
||||
get => cover;
|
||||
set => SetProperty(ref cover, value);
|
||||
}
|
||||
|
||||
private string title;
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
private string videoZone;
|
||||
public string VideoZone
|
||||
{
|
||||
get => videoZone;
|
||||
set => SetProperty(ref videoZone, value);
|
||||
}
|
||||
|
||||
private string createTime;
|
||||
public string CreateTime
|
||||
{
|
||||
get => createTime;
|
||||
set => SetProperty(ref createTime, value);
|
||||
}
|
||||
|
||||
private string playNumber;
|
||||
public string PlayNumber
|
||||
{
|
||||
get => playNumber;
|
||||
set => SetProperty(ref playNumber, value);
|
||||
}
|
||||
|
||||
private string danmakuNumber;
|
||||
public string DanmakuNumber
|
||||
{
|
||||
get => danmakuNumber;
|
||||
set => SetProperty(ref danmakuNumber, value);
|
||||
}
|
||||
|
||||
private string likeNumber;
|
||||
public string LikeNumber
|
||||
{
|
||||
get => likeNumber;
|
||||
set => SetProperty(ref likeNumber, value);
|
||||
}
|
||||
|
||||
private string coinNumber;
|
||||
public string CoinNumber
|
||||
{
|
||||
get => coinNumber;
|
||||
set => SetProperty(ref coinNumber, value);
|
||||
}
|
||||
|
||||
private string favoriteNumber;
|
||||
public string FavoriteNumber
|
||||
{
|
||||
get => favoriteNumber;
|
||||
set => SetProperty(ref favoriteNumber, value);
|
||||
}
|
||||
|
||||
private string shareNumber;
|
||||
public string ShareNumber
|
||||
{
|
||||
get => shareNumber;
|
||||
set => SetProperty(ref shareNumber, value);
|
||||
}
|
||||
|
||||
private string replyNumber;
|
||||
public string ReplyNumber
|
||||
{
|
||||
get => replyNumber;
|
||||
set => SetProperty(ref replyNumber, value);
|
||||
}
|
||||
|
||||
private string description;
|
||||
public string Description
|
||||
{
|
||||
get => description;
|
||||
set => SetProperty(ref description, value);
|
||||
}
|
||||
|
||||
private string upName;
|
||||
public string UpName
|
||||
{
|
||||
get => upName;
|
||||
set => SetProperty(ref upName, value);
|
||||
}
|
||||
|
||||
private BitmapImage upHeader;
|
||||
public BitmapImage UpHeader
|
||||
{
|
||||
get => upHeader;
|
||||
set => SetProperty(ref upHeader, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
75
src/DownKyi/ViewModels/PageViewModels/VideoPage.cs
Normal file
75
src/DownKyi/ViewModels/PageViewModels/VideoPage.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using DownKyi.Core.BiliApi.VideoStream.Models;
|
||||
using Prism.Mvvm;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class VideoPage : BindableBase
|
||||
{
|
||||
public PlayUrl PlayUrl { get; set; }
|
||||
|
||||
public long Avid { get; set; }
|
||||
public string Bvid { get; set; }
|
||||
public long Cid { get; set; }
|
||||
public long EpisodeId { get; set; }
|
||||
|
||||
public string FirstFrame { get; set; }
|
||||
|
||||
private bool isSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get => isSelected;
|
||||
set => SetProperty(ref isSelected, value);
|
||||
}
|
||||
|
||||
private int order;
|
||||
public int Order
|
||||
{
|
||||
get => order;
|
||||
set => SetProperty(ref order, 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);
|
||||
}
|
||||
|
||||
private List<string> audioQualityFormatList;
|
||||
public List<string> AudioQualityFormatList
|
||||
{
|
||||
get => audioQualityFormatList;
|
||||
set => SetProperty(ref audioQualityFormatList, value);
|
||||
}
|
||||
|
||||
private string audioQualityFormat;
|
||||
public string AudioQualityFormat
|
||||
{
|
||||
get => audioQualityFormat;
|
||||
set => SetProperty(ref audioQualityFormat, value);
|
||||
}
|
||||
|
||||
private List<VideoQuality> videoQualityList;
|
||||
public List<VideoQuality> VideoQualityList
|
||||
{
|
||||
get => videoQualityList;
|
||||
set => SetProperty(ref videoQualityList, value);
|
||||
}
|
||||
|
||||
private VideoQuality videoQuality;
|
||||
public VideoQuality VideoQuality
|
||||
{
|
||||
get => videoQuality;
|
||||
set => SetProperty(ref videoQuality, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
36
src/DownKyi/ViewModels/PageViewModels/VideoQuality.cs
Normal file
36
src/DownKyi/ViewModels/PageViewModels/VideoQuality.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using Prism.Mvvm;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class VideoQuality : BindableBase
|
||||
{
|
||||
private int quality;
|
||||
public int Quality
|
||||
{
|
||||
get => quality;
|
||||
set => SetProperty(ref quality, value);
|
||||
}
|
||||
|
||||
private string qualityFormat;
|
||||
public string QualityFormat
|
||||
{
|
||||
get => qualityFormat;
|
||||
set => SetProperty(ref qualityFormat, value);
|
||||
}
|
||||
|
||||
private List<string> videoCodecList;
|
||||
public List<string> VideoCodecList
|
||||
{
|
||||
get => videoCodecList;
|
||||
set => SetProperty(ref videoCodecList, value);
|
||||
}
|
||||
|
||||
private string selectedVideoCodec;
|
||||
public string SelectedVideoCodec
|
||||
{
|
||||
get => selectedVideoCodec;
|
||||
set => SetProperty(ref selectedVideoCodec, value);
|
||||
}
|
||||
}
|
||||
}
|
31
src/DownKyi/ViewModels/PageViewModels/VideoSection.cs
Normal file
31
src/DownKyi/ViewModels/PageViewModels/VideoSection.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Prism.Mvvm;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.ViewModels.PageViewModels
|
||||
{
|
||||
public class VideoSection : BindableBase
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
private string title;
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
private bool isSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get => isSelected;
|
||||
set => SetProperty(ref isSelected, value);
|
||||
}
|
||||
|
||||
private List<VideoPage> videoPages;
|
||||
public List<VideoPage> VideoPages
|
||||
{
|
||||
get => videoPages;
|
||||
set => SetProperty(ref videoPages, value);
|
||||
}
|
||||
}
|
||||
}
|
17
src/DownKyi/ViewModels/Settings/DisplayFileNamePart.cs
Normal file
17
src/DownKyi/ViewModels/Settings/DisplayFileNamePart.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using DownKyi.Core.FileName;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace DownKyi.ViewModels.Settings
|
||||
{
|
||||
public class DisplayFileNamePart : BindableBase
|
||||
{
|
||||
public FileNamePart Id { get; set; }
|
||||
|
||||
private string title;
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
set => SetProperty(ref title, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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<TabHeader> tabHeaders;
|
||||
public List<TabHeader> 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
|
||||
|
@ -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<FavoritesMedia> favoritesMedias;
|
||||
public ObservableCollection<FavoritesMedia> 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
|
||||
|
@ -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<TabHeader> tabHeaders;
|
||||
public List<TabHeader> 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
|
||||
|
@ -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<TabHeader> tabHeaders;
|
||||
public List<TabHeader> 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
|
||||
|
@ -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<MessageEvent>().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<MessageEvent>().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++;
|
||||
}
|
||||
}
|
||||
|
@ -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">
|
||||
<UserControl.Resources>
|
||||
<converter:CountConverter x:Key="CountConverter" Count="0" />
|
||||
|
||||
<Style x:Key="DownloadedStyle" TargetType="{x:Type ListBoxItem}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Grid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=ActualWidth}" Height="70">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="70" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="120" />
|
||||
<ColumnDefinition Width="20" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image
|
||||
Grid.Column="0"
|
||||
Width="48"
|
||||
Height="48"
|
||||
Source="{Binding ZoneImage}" />
|
||||
|
||||
<!-- 标题等视频信息 -->
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
Margin="0,0,10,0"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource BrushTextDark}"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding StringFormat="{}{0}-{1}-{2}">
|
||||
<Binding Path="Order" />
|
||||
<Binding Path="MainTitle" />
|
||||
<Binding Path="Name" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
<TextBlock.ToolTip>
|
||||
<TextBlock>
|
||||
<TextBlock.Text>
|
||||
<MultiBinding StringFormat="{}{0}-{1}">
|
||||
<Binding Path="MainTitle" />
|
||||
<Binding Path="Name" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</TextBlock.ToolTip>
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource BrushTextGrey2}">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding StringFormat="{}{0} · {1} · {2} · {3} · {4} · {5}">
|
||||
<Binding Path="Duration" />
|
||||
<Binding Path="Resolution.Name" />
|
||||
<Binding Path="VideoCodecName" />
|
||||
<Binding Path="AudioCodec.Name" />
|
||||
<Binding Path="FileSize" />
|
||||
<Binding Path="MaxSpeedDisplay" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource BrushTextDark}"
|
||||
Text="{Binding FinishedTime}" />
|
||||
|
||||
<!-- 控制面板,暂停继续删除 -->
|
||||
<Grid Grid.Column="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Background="{DynamicResource BrushBackground}"
|
||||
Cursor="Hand">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="MouseLeftButtonUp">
|
||||
<i:InvokeCommandAction Command="{Binding OpenFolderCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<ContentControl>
|
||||
<Path
|
||||
Width="{Binding OpenFolder.Width}"
|
||||
Height="{Binding OpenFolder.Height}"
|
||||
Data="{Binding OpenFolder.Data}"
|
||||
Fill="{Binding OpenFolder.Fill}"
|
||||
Stretch="UniformToFill" />
|
||||
</ContentControl>
|
||||
</Border>
|
||||
|
||||
<Border
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Background="{DynamicResource BrushBackground}"
|
||||
Cursor="Hand">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="MouseLeftButtonUp">
|
||||
<i:InvokeCommandAction Command="{Binding OpenVideoCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<ContentControl>
|
||||
<Path
|
||||
Width="{Binding OpenVideo.Width}"
|
||||
Height="{Binding OpenVideo.Height}"
|
||||
Data="{Binding OpenVideo.Data}"
|
||||
Fill="{Binding OpenVideo.Fill}"
|
||||
Stretch="UniformToFill" />
|
||||
</ContentControl>
|
||||
</Border>
|
||||
|
||||
<Border
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Background="{DynamicResource BrushBackground}"
|
||||
Cursor="Hand">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="MouseLeftButtonUp">
|
||||
<i:InvokeCommandAction Command="{Binding RemoveVideoCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<ContentControl>
|
||||
<Path
|
||||
Width="{Binding RemoveVideo.Width}"
|
||||
Height="{Binding RemoveVideo.Height}"
|
||||
Data="{Binding RemoveVideo.Data}"
|
||||
Fill="{Binding RemoveVideo.Fill}"
|
||||
Stretch="UniformToFill" />
|
||||
</ContentControl>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<TextBlock>已下载</TextBlock>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="1" />
|
||||
<RowDefinition Height="50" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.Style>
|
||||
<Style TargetType="{x:Type Grid}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding DownloadedList}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadedList.Count}" Value="0">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadedList.Count, Converter={StaticResource CountConverter}}" Value="true">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
|
||||
<ListBox
|
||||
Grid.Row="0"
|
||||
BorderThickness="0"
|
||||
ItemContainerStyle="{StaticResource DownloadedStyle}"
|
||||
ItemsSource="{Binding DownloadedList}">
|
||||
<ListBox.Style>
|
||||
<Style TargetType="ListBox">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBox">
|
||||
<Border
|
||||
x:Name="Bd"
|
||||
Padding="0"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<ScrollViewer CanContentScroll="False" Focusable="False">
|
||||
<ItemsPresenter />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ListBox.Style>
|
||||
</ListBox>
|
||||
|
||||
<TextBlock Grid.Row="1" Background="{DynamicResource BrushBorderTranslucent}" />
|
||||
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="130" />
|
||||
<ColumnDefinition Width="110" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Margin="10,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Text="{DynamicResource TotalDownloaded1}" />
|
||||
<TextBlock
|
||||
Margin="3,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource BrushPrimary}"
|
||||
Text="{Binding DownloadedList.Count}" />
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Text="{DynamicResource TotalDownloaded2}" />
|
||||
</StackPanel>
|
||||
|
||||
<ComboBox
|
||||
Name="nameFinishedSort"
|
||||
Grid.Column="1"
|
||||
Width="120"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="SelectionChanged">
|
||||
<i:InvokeCommandAction Command="{Binding FinishedSortCommand}" CommandParameter="{Binding ElementName=nameFinishedSort, Path=SelectedIndex}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<ComboBoxItem Content="{DynamicResource DownloadedSortByTime}" TabIndex="1" />
|
||||
<ComboBoxItem Content="{DynamicResource DownloadedSortByOrder}" TabIndex="2" />
|
||||
</ComboBox>
|
||||
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Width="100"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding ClearAllDownloadedCommand}"
|
||||
Content="{DynamicResource ClearAllDownloaded}"
|
||||
FontSize="12"
|
||||
Style="{StaticResource BtnBorderStyle}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- TODO 没有数据时显示图片或文字 -->
|
||||
<Image
|
||||
Width="256"
|
||||
Height="256"
|
||||
Source="/DownKyi;component/Resources/nodata02.png">
|
||||
<Image.Style>
|
||||
<Style TargetType="{x:Type Image}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding DownloadedList}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadedList.Count}" Value="0">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadedList.Count, Converter={StaticResource CountConverter}}" Value="true">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Image.Style>
|
||||
</Image>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
@ -2,15 +2,18 @@
|
||||
x:Class="DownKyi.Views.DownloadManager.ViewDownloading"
|
||||
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">
|
||||
<UserControl.Resources>
|
||||
<converter:CountConverter x:Key="CountConverter" Count="0" />
|
||||
|
||||
<Style x:Key="DownloadingStyle" TargetType="{x:Type ListBoxItem}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Grid Height="70">
|
||||
<Grid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=ActualWidth}" Height="70">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="70" />
|
||||
@ -27,7 +30,10 @@
|
||||
Source="{Binding ZoneImage}" />
|
||||
|
||||
<!-- 标题等视频信息 -->
|
||||
<Grid Grid.Column="1" HorizontalAlignment="Left">
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
Margin="0,0,10,0"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
@ -74,19 +80,6 @@
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
|
||||
<Grid.Style>
|
||||
<Style TargetType="{x:Type Grid}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource AncestorType=Window}}" Value="Maximized">
|
||||
<Setter Property="Width" Value="auto" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource AncestorType=Window}}" Value="Normal">
|
||||
<Setter Property="Width" Value="400" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
</Grid>
|
||||
|
||||
<!-- 进度条 -->
|
||||
@ -225,6 +218,21 @@
|
||||
<RowDefinition Height="1" />
|
||||
<RowDefinition Height="50" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.Style>
|
||||
<Style TargetType="{x:Type Grid}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding DownloadingList}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadingList.Count}" Value="0">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadingList.Count, Converter={StaticResource CountConverter}}" Value="true">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
|
||||
<ListBox
|
||||
Grid.Row="0"
|
||||
@ -311,10 +319,29 @@
|
||||
Content="{DynamicResource DeleteAllDownloading}"
|
||||
FontSize="12"
|
||||
Style="{StaticResource BtnBorderStyle}" />
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- TODO 没有数据时显示图片或文字 -->
|
||||
<Image
|
||||
Width="256"
|
||||
Height="256"
|
||||
Source="/DownKyi;component/Resources/nodata02.png">
|
||||
<Image.Style>
|
||||
<Style TargetType="{x:Type Image}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding DownloadingList}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadingList.Count}" Value="0">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DownloadingList.Count, Converter={StaticResource CountConverter}}" Value="true">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Image.Style>
|
||||
</Image>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
Loading…
Reference in New Issue
Block a user