From 9f443cb809c4e89bf3c2b162279b0e892aec7984 Mon Sep 17 00:00:00 2001
From: flyself <1432593898@qq.com>
Date: Thu, 23 Dec 2021 12:05:16 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8B=E8=BD=BD=E4=B8=AD?=
=?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 3 +-
.../BiliApi/BiliUtils/Constant.cs | 44 +++++++----
src/DownKyi.Core/BiliApi/BiliUtils/Quality.cs | 8 ++
src/DownKyi.Core/DownKyi.Core.csproj | 17 +++--
src/DownKyi.Core/Properties/AssemblyInfo.cs | 6 +-
src/DownKyi.Core/app.config | 2 +-
src/DownKyi.Core/packages.config | 8 +-
src/DownKyi/DownKyi.csproj | 3 -
src/DownKyi/Languages/Default.xaml | 2 +
src/DownKyi/Models/DownloadBaseItem.cs | 27 ++++---
.../Services/Download/AriaDownloadService.cs | 57 ++++++++++----
.../Services/Download/IDownloadService.cs | 2 +-
src/DownKyi/Services/Utils.cs | 8 +-
.../ViewModels/Settings/ViewVideoViewModel.cs | 76 ++++++++++++++++---
.../ViewModels/ViewVideoDetailViewModel.cs | 26 ++++---
.../DownloadManager/ViewDownloading.xaml | 18 ++++-
src/DownKyi/Views/Settings/ViewAbout.xaml | 4 +-
src/DownKyi/Views/Settings/ViewVideo.xaml | 35 +++++++++
src/DownKyi/app.config | 8 ++
19 files changed, 267 insertions(+), 87 deletions(-)
create mode 100644 src/DownKyi.Core/BiliApi/BiliUtils/Quality.cs
diff --git a/README.md b/README.md
index 7cb9f87..eeae772 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,8 @@
- [x] 支持4K下载
- [x] 支持视频、番剧、剧集、电影、课程下载
- [x] **支持用户收藏夹、订阅、稍后再看、历史记录下载**
-- [x] ~~**支持港澳台番剧下载,解除地区限制**~~
- [x] 支持弹幕下载、样式设置
+- [x] 支持字幕下载
- [x] 支持封面下载
- [x] 支持断点续传
- [x] 支持Aria2c
@@ -20,6 +20,7 @@
- [x] 支持音视频分离
- [x] 支持去水印
- [x] 支持检查更新
+……
## 使用方法
diff --git a/src/DownKyi.Core/BiliApi/BiliUtils/Constant.cs b/src/DownKyi.Core/BiliApi/BiliUtils/Constant.cs
index 157c706..5e82b9c 100644
--- a/src/DownKyi.Core/BiliApi/BiliUtils/Constant.cs
+++ b/src/DownKyi.Core/BiliApi/BiliUtils/Constant.cs
@@ -4,25 +4,43 @@ namespace DownKyi.Core.BiliApi.BiliUtils
{
public static class Constant
{
- ///
- /// 音质id及含义
- ///
- public static Dictionary AudioQuality { get; } = new Dictionary()
+ private static readonly List resolutions = new List
{
- { 30216, "64K" },
- { 30232, "132K" },
- { 30280, "192K" }
+ new Quality { Name = "HDR 真彩", Id = 125 },
+ new Quality { Name = "4K 超清", Id = 120 },
+ new Quality { Name = "1080P 60帧", Id = 116 },
+ new Quality { Name = "1080P 高码率", Id = 112 },
+ new Quality { Name = "1080P 高清", Id = 80 },
+ new Quality { Name = "720P 60帧", Id = 74 },
+ new Quality { Name = "720P 高清", Id = 64 },
+ new Quality { Name = "480P 清晰", Id = 32 },
+ new Quality { Name = "360P 流畅", Id = 16 },
+ };
+
+ private static readonly List qualities = new List
+ {
+ new Quality { Name = "64K", Id = 30216 },
+ new Quality { Name = "132K", Id = 30232 },
+ new Quality { Name = "192K", Id = 30280 },
};
///
- /// 音质id及含义
+ /// 获取支持的视频画质
///
- public static Dictionary AudioQualityId { get; } = new Dictionary()
+ ///
+ public static List GetResolutions()
{
- { "64K", 30216 },
- { "132K", 30232 },
- { "192K", 30280 }
- };
+ return resolutions;
+ }
+
+ ///
+ /// 获取支持的视频音质
+ ///
+ ///
+ public static List GetAudioQualities()
+ {
+ return qualities;
+ }
}
}
diff --git a/src/DownKyi.Core/BiliApi/BiliUtils/Quality.cs b/src/DownKyi.Core/BiliApi/BiliUtils/Quality.cs
new file mode 100644
index 0000000..6295881
--- /dev/null
+++ b/src/DownKyi.Core/BiliApi/BiliUtils/Quality.cs
@@ -0,0 +1,8 @@
+namespace DownKyi.Core.BiliApi.BiliUtils
+{
+ public class Quality
+ {
+ public string Name { get; set; }
+ public int Id { get; set; }
+ }
+}
diff --git a/src/DownKyi.Core/DownKyi.Core.csproj b/src/DownKyi.Core/DownKyi.Core.csproj
index 131523f..7e57e38 100644
--- a/src/DownKyi.Core/DownKyi.Core.csproj
+++ b/src/DownKyi.Core/DownKyi.Core.csproj
@@ -36,16 +36,16 @@
..\packages\Brotli.NET.2.1.1\lib\net45\Brotli.Core.dll
-
- ..\packages\Google.Protobuf.3.18.1\lib\net45\Google.Protobuf.dll
+
+ ..\packages\Google.Protobuf.3.19.1\lib\net45\Google.Protobuf.dll
..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
-
- ..\packages\QRCoder.1.4.1\lib\net40\QRCoder.dll
+
+ ..\packages\QRCoder.1.4.3\lib\net40\QRCoder.dll
@@ -64,8 +64,8 @@
..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
@@ -129,6 +129,7 @@
+
@@ -279,8 +280,8 @@
-
+
-
+
\ No newline at end of file
diff --git a/src/DownKyi.Core/Properties/AssemblyInfo.cs b/src/DownKyi.Core/Properties/AssemblyInfo.cs
index e3405cb..18b88bb 100644
--- a/src/DownKyi.Core/Properties/AssemblyInfo.cs
+++ b/src/DownKyi.Core/Properties/AssemblyInfo.cs
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("DownKyi")]
[assembly: AssemblyProduct("DownKyi.Core")]
-[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyCopyright("Copyright © Downkyi 2020-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.0.0")]
-[assembly: AssemblyFileVersion("2.0.0.0")]
+[assembly: AssemblyVersion("2.1.0.0")]
+[assembly: AssemblyFileVersion("2.1.0.0")]
diff --git a/src/DownKyi.Core/app.config b/src/DownKyi.Core/app.config
index f10b4ac..1696df6 100644
--- a/src/DownKyi.Core/app.config
+++ b/src/DownKyi.Core/app.config
@@ -4,7 +4,7 @@
-
+
diff --git a/src/DownKyi.Core/packages.config b/src/DownKyi.Core/packages.config
index 25076d7..c49a756 100644
--- a/src/DownKyi.Core/packages.config
+++ b/src/DownKyi.Core/packages.config
@@ -1,14 +1,14 @@
-
-
+
+
-
+
-
+
\ No newline at end of file
diff --git a/src/DownKyi/DownKyi.csproj b/src/DownKyi/DownKyi.csproj
index e75cd65..f309c28 100644
--- a/src/DownKyi/DownKyi.csproj
+++ b/src/DownKyi/DownKyi.csproj
@@ -96,7 +96,6 @@
-
@@ -110,8 +109,6 @@
-
-
diff --git a/src/DownKyi/Languages/Default.xaml b/src/DownKyi/Languages/Default.xaml
index e3f29bb..71c49b6 100644
--- a/src/DownKyi/Languages/Default.xaml
+++ b/src/DownKyi/Languages/Default.xaml
@@ -119,6 +119,7 @@
视频
优先下载的视频编码:
优先下载的视频画质:
+ 优先下载的视频音质:
下载FLV视频后转码为mp4
使用默认下载目录
默认下载目录:
@@ -136,6 +137,7 @@
画质
视频编码
空格
+ 恢复默认
弹幕
按类型屏蔽
diff --git a/src/DownKyi/Models/DownloadBaseItem.cs b/src/DownKyi/Models/DownloadBaseItem.cs
index 6c6c102..488f572 100644
--- a/src/DownKyi/Models/DownloadBaseItem.cs
+++ b/src/DownKyi/Models/DownloadBaseItem.cs
@@ -1,4 +1,5 @@
-using Prism.Mvvm;
+using DownKyi.Core.BiliApi.BiliUtils;
+using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Windows.Media;
@@ -38,6 +39,9 @@ namespace DownKyi.Models
// 视频封面的url
public string CoverUrl { get; set; }
+ // 视频page的封面的url
+ public string PageCoverUrl { get; set; }
+
private DrawingImage zoneImage;
public DrawingImage ZoneImage
{
@@ -77,15 +81,6 @@ namespace DownKyi.Models
set => SetProperty(ref duration, value);
}
- // 音频编码
- public int AudioCodecId { get; set; }
- private string audioCodecName;
- public string AudioCodecName
- {
- get => audioCodecName;
- set => SetProperty(ref audioCodecName, value);
- }
-
// 视频编码
// "hev1.2.4.L156.90"
// "avc1.640034"
@@ -100,13 +95,21 @@ namespace DownKyi.Models
}
// 视频画质
- private Resolution resolution;
- public Resolution Resolution
+ private Quality resolution;
+ public Quality Resolution
{
get => resolution;
set => SetProperty(ref resolution, value);
}
+ // 音频编码
+ private Quality audioCodec;
+ public Quality AudioCodec
+ {
+ get => audioCodec;
+ set => SetProperty(ref audioCodec, value);
+ }
+
// 文件路径,不包含扩展名,所有内容均以此路径下载
public string FilePath { get; set; }
diff --git a/src/DownKyi/Services/Download/AriaDownloadService.cs b/src/DownKyi/Services/Download/AriaDownloadService.cs
index abcf28a..d972c38 100644
--- a/src/DownKyi/Services/Download/AriaDownloadService.cs
+++ b/src/DownKyi/Services/Download/AriaDownloadService.cs
@@ -59,7 +59,7 @@ namespace DownKyi.Services.Download
PlayUrlDashVideo downloadAudio = null;
foreach (PlayUrlDashVideo audio in downloading.PlayUrl.Dash.Audio)
{
- if (audio.Id == downloading.AudioCodecId)
+ if (audio.Id == downloading.AudioCodec.Id)
{
downloadAudio = audio;
break;
@@ -148,7 +148,7 @@ namespace DownKyi.Services.Download
/// 下载封面
///
///
- public string DownloadCover(DownloadingItem downloading)
+ public string DownloadCover(DownloadingItem downloading, string coverUrl, string fileName)
{
// 更新状态显示
downloading.DownloadStatusTitle = DictionaryResource.GetString("WhileDownloading");
@@ -160,24 +160,16 @@ namespace DownKyi.Services.Download
// 查询、保存封面
StorageCover storageCover = new StorageCover();
- string cover = storageCover.GetCover(downloading.Avid, downloading.Bvid, downloading.Cid, downloading.CoverUrl);
+ string cover = storageCover.GetCover(downloading.Avid, downloading.Bvid, downloading.Cid, coverUrl);
if (cover == null)
{
return null;
}
- // 图片的扩展名
- string[] temp = downloading.CoverUrl.Split('.');
- string fileExtension = temp[temp.Length - 1];
-
- // 图片的地址
- string coverPath = $"{StorageManager.GetCover()}/{cover}";
-
// 复制图片到指定位置
try
{
- string fileName = $"{downloading.FilePath}.{fileExtension}";
- File.Copy(coverPath, fileName);
+ File.Copy(cover, fileName, true);
// 记录本次下载的文件
downloading.DownloadFiles.Add(fileName);
@@ -448,6 +440,15 @@ namespace DownKyi.Services.Download
///
private async void SingleDownload(DownloadingItem downloading)
{
+ // 路径
+ string[] temp = downloading.FilePath.Split('/');
+ string path = downloading.FilePath.Replace(temp[temp.Length - 1], "");
+ // 路径不存在则创建
+ if (!Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+
await Task.Run(new Action(() =>
{
downloading.DownloadStatus = DownloadStatus.DOWNLOADING;
@@ -507,14 +508,24 @@ namespace DownKyi.Services.Download
// 如果需要下载封面
if (downloading.NeedDownloadContent["downloadCover"])
{
- outputCover = DownloadCover(downloading);
+
+ string fileName = $"{downloading.FilePath}.{GetImageExtension(downloading.PageCoverUrl)}";
+
+ // page的封面
+ outputCover = DownloadCover(downloading, downloading.PageCoverUrl, fileName);
+ // 封面
+ DownloadCover(downloading, downloading.CoverUrl, $"{path}/Cover.{GetImageExtension(downloading.CoverUrl)}");
}
// 暂停
Pause(downloading);
// 混流
- string outputMedia = MixedFlow(downloading, audioUid, videoUid);
+ string outputMedia = string.Empty;
+ if (downloading.NeedDownloadContent["downloadAudio"] || downloading.NeedDownloadContent["downloadVideo"])
+ {
+ outputMedia = MixedFlow(downloading, audioUid, videoUid);
+ }
// 暂停
Pause(downloading);
@@ -570,6 +581,24 @@ namespace DownKyi.Services.Download
}));
}
+ ///
+ /// 获取图片的扩展名
+ ///
+ ///
+ ///
+ private string GetImageExtension(string coverUrl)
+ {
+ if (coverUrl == null)
+ {
+ return string.Empty;
+ }
+
+ // 图片的扩展名
+ string[] temp = coverUrl.Split('.');
+ string fileExtension = temp[temp.Length - 1];
+ return fileExtension;
+ }
+
///
/// 强制暂停
///
diff --git a/src/DownKyi/Services/Download/IDownloadService.cs b/src/DownKyi/Services/Download/IDownloadService.cs
index 8facfb4..3621dad 100644
--- a/src/DownKyi/Services/Download/IDownloadService.cs
+++ b/src/DownKyi/Services/Download/IDownloadService.cs
@@ -10,7 +10,7 @@ namespace DownKyi.Services.Download
string DownloadVideo(DownloadingItem downloading);
string DownloadDanmaku(DownloadingItem downloading);
List DownloadSubtitle(DownloadingItem downloading);
- string DownloadCover(DownloadingItem downloading);
+ string DownloadCover(DownloadingItem downloading, string coverUrl, string fileName);
string MixedFlow(DownloadingItem downloading, string audioUid, string videoUid);
void Start();
diff --git a/src/DownKyi/Services/Utils.cs b/src/DownKyi/Services/Utils.cs
index c16cf98..ed54eb9 100644
--- a/src/DownKyi/Services/Utils.cs
+++ b/src/DownKyi/Services/Utils.cs
@@ -1,4 +1,5 @@
-using DownKyi.Core.BiliApi.VideoStream.Models;
+using DownKyi.Core.BiliApi.BiliUtils;
+using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Core.Settings;
using DownKyi.Core.Settings.Models;
using DownKyi.Core.Utils;
@@ -101,9 +102,10 @@ namespace DownKyi.Services
// 音质id大于设置画质时,跳过
if (audio.Id > defaultAudioQuality) { continue; }
- if (Core.BiliApi.BiliUtils.Constant.AudioQuality.ContainsKey(audio.Id))
+ Quality audioQuality = Constant.GetAudioQualities().FirstOrDefault(t => { return t.Id == audio.Id; });
+ if (audioQuality != null)
{
- ListHelper.AddUnique(audioQualityFormatList, Core.BiliApi.BiliUtils.Constant.AudioQuality[audio.Id]);
+ ListHelper.AddUnique(audioQualityFormatList, audioQuality.Name);
}
}
diff --git a/src/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs b/src/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs
index 5f47ece..d100b8c 100644
--- a/src/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs
+++ b/src/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs
@@ -1,8 +1,8 @@
-using DownKyi.Core.FileName;
+using DownKyi.Core.BiliApi.BiliUtils;
+using DownKyi.Core.FileName;
using DownKyi.Core.Settings;
using DownKyi.Events;
using DownKyi.Models;
-using DownKyi.Services;
using DownKyi.Utils;
using Prism.Commands;
using Prism.Events;
@@ -36,20 +36,34 @@ namespace DownKyi.ViewModels.Settings
set => SetProperty(ref selectedVideoCodec, value);
}
- private List videoQualityList;
- public List VideoQualityList
+ private List videoQualityList;
+ public List VideoQualityList
{
get => videoQualityList;
set => SetProperty(ref videoQualityList, value);
}
- private Resolution selectedVideoQuality;
- public Resolution SelectedVideoQuality
+ private Quality selectedVideoQuality;
+ public Quality SelectedVideoQuality
{
get => selectedVideoQuality;
set => SetProperty(ref selectedVideoQuality, value);
}
+ private List audioQualityList;
+ public List AudioQualityList
+ {
+ get => audioQualityList;
+ set => SetProperty(ref audioQualityList, value);
+ }
+
+ private Quality selectedAudioQuality;
+ public Quality SelectedAudioQuality
+ {
+ get => selectedAudioQuality;
+ set => SetProperty(ref selectedAudioQuality, value);
+ }
+
private bool isTranscodingFlvToMp4;
public bool IsTranscodingFlvToMp4
{
@@ -104,11 +118,14 @@ namespace DownKyi.ViewModels.Settings
VideoCodecs = new List
{
"H.264/AVC",
- "H.265/HEVC"
+ "H.265/HEVC",
};
// 优先下载画质
- VideoQualityList = new ResolutionService().GetResolution();
+ VideoQualityList = Constant.GetResolutions();
+
+ // 优先下载音质
+ AudioQualityList = Constant.GetAudioQualities();
// 文件命名格式
SelectedFileName = new ObservableCollection();
@@ -143,6 +160,10 @@ namespace DownKyi.ViewModels.Settings
int quality = SettingsManager.GetInstance().GetQuality();
SelectedVideoQuality = VideoQualityList.FirstOrDefault(t => { return t.Id == quality; });
+ // 优先下载音质
+ int audioQuality = SettingsManager.GetInstance().GetAudioQuality();
+ SelectedAudioQuality = AudioQualityList.FirstOrDefault(t => { return t.Id == audioQuality; });
+
// 是否下载flv视频后转码为mp4
AllowStatus isTranscodingFlvToMp4 = SettingsManager.GetInstance().IsTranscodingFlvToMp4();
IsTranscodingFlvToMp4 = isTranscodingFlvToMp4 == AllowStatus.YES;
@@ -194,12 +215,28 @@ namespace DownKyi.ViewModels.Settings
///
private void ExecuteVideoQualityCommand(object parameter)
{
- if (!(parameter is Resolution resolution)) { return; }
+ if (!(parameter is Quality resolution)) { return; }
bool isSucceed = SettingsManager.GetInstance().SetQuality(resolution.Id);
PublishTip(isSucceed);
}
+ // 优先下载音质事件
+ private DelegateCommand