From 0a37220fe9330dc07b2d284a7b9137819a9ee199 Mon Sep 17 00:00:00 2001 From: croire <1432593898@qq.com> Date: Mon, 31 Jan 2022 02:09:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9D=9C=E6=AF=94=E5=85=A8?= =?UTF-8?q?=E6=99=AF=E5=A3=B0=E3=80=81=E6=9D=9C=E6=AF=94=E8=A7=86=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DownKyi.Core/BiliApi/BiliUtils/Constant.cs | 3 ++ .../BiliApi/VideoStream/Models/PlayUrlDash.cs | 2 + .../VideoStream/Models/PlayUrlDashDolby.cs | 13 ++++++ .../VideoStream/Models/PlayUrlDashVideo.cs | 4 +- .../BiliApi/VideoStream/VideoStream.cs | 6 +-- DownKyi.Core/BiliApi/WebClient.cs | 8 +++- DownKyi.Core/DownKyi.Core.csproj | 1 + DownKyi.Core/Utils/ListHelper.cs | 16 +++++++ .../Services/Download/AddToDownloadService.cs | 14 ++++++- .../Services/Download/AriaDownloadService.cs | 13 +++++- DownKyi/Services/Utils.cs | 9 ++-- .../ViewModels/PageViewModels/VideoPage.cs | 42 +++++++++++++++++-- .../ViewModels/Settings/ViewVideoViewModel.cs | 1 + DownKyi/Views/ViewVideoDetail.xaml | 12 ++++-- 14 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashDolby.cs diff --git a/DownKyi.Core/BiliApi/BiliUtils/Constant.cs b/DownKyi.Core/BiliApi/BiliUtils/Constant.cs index 5e82b9c..070adfb 100644 --- a/DownKyi.Core/BiliApi/BiliUtils/Constant.cs +++ b/DownKyi.Core/BiliApi/BiliUtils/Constant.cs @@ -6,6 +6,8 @@ namespace DownKyi.Core.BiliApi.BiliUtils { private static readonly List resolutions = new List { + new Quality { Name = "超高清 8K", Id = 127 }, + new Quality { Name = "杜比视界", Id = 126 }, new Quality { Name = "HDR 真彩", Id = 125 }, new Quality { Name = "4K 超清", Id = 120 }, new Quality { Name = "1080P 60帧", Id = 116 }, @@ -22,6 +24,7 @@ namespace DownKyi.Core.BiliApi.BiliUtils new Quality { Name = "64K", Id = 30216 }, new Quality { Name = "132K", Id = 30232 }, new Quality { Name = "192K", Id = 30280 }, + new Quality { Name = "Dolby Atmos", Id = 30250 }, }; /// diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs index 7b65a05..ff545d1 100644 --- a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs @@ -16,5 +16,7 @@ namespace DownKyi.Core.BiliApi.VideoStream.Models public List Video { get; set; } [JsonProperty("audio")] public List Audio { get; set; } + [JsonProperty("dolby")] + public PlayUrlDashDolby Dolby { get; set; } } } diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashDolby.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashDolby.cs new file mode 100644 index 0000000..9629c8d --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashDolby.cs @@ -0,0 +1,13 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.VideoStream.Models +{ + public class PlayUrlDashDolby : BaseModel + { + // type + [JsonProperty("audio")] + public List Audio { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs index 9c5cf20..098f9bc 100644 --- a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs @@ -8,9 +8,9 @@ namespace DownKyi.Core.BiliApi.VideoStream.Models { [JsonProperty("id")] public int Id { get; set; } - [JsonProperty("baseUrl")] + [JsonProperty("base_url")] public string BaseUrl { get; set; } - [JsonProperty("backupUrl")] + [JsonProperty("backup_url")] public List BackupUrl { get; set; } // bandwidth [JsonProperty("mimeType")] diff --git a/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs b/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs index 8490aea..5764fcd 100644 --- a/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs +++ b/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs @@ -93,7 +93,7 @@ namespace DownKyi.Core.BiliApi.VideoStream /// public static PlayUrl GetVideoPlayUrl(long avid, string bvid, long cid, int quality = 125) { - string baseUrl = $"https://api.bilibili.com/x/player/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=80"; + string baseUrl = $"https://api.bilibili.com/x/player/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=4048"; string url; if (bvid != null) { url = $"{baseUrl}&bvid={bvid}"; } else if (avid > -1) { url = $"{baseUrl}&aid={avid}"; } @@ -112,7 +112,7 @@ namespace DownKyi.Core.BiliApi.VideoStream /// public static PlayUrl GetBangumiPlayUrl(long avid, string bvid, long cid, int quality = 125) { - string baseUrl = $"https://api.bilibili.com/pgc/player/web/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=80"; + string baseUrl = $"https://api.bilibili.com/pgc/player/web/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=4048"; string url; if (bvid != null) { url = $"{baseUrl}&bvid={bvid}"; } else if (avid > -1) { url = $"{baseUrl}&aid={avid}"; } @@ -131,7 +131,7 @@ namespace DownKyi.Core.BiliApi.VideoStream /// public static PlayUrl GetCheesePlayUrl(long avid, string bvid, long cid, long episodeId, int quality = 125) { - string baseUrl = $"https://api.bilibili.com/pugv/player/web/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=80"; + string baseUrl = $"https://api.bilibili.com/pugv/player/web/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=4048"; string url; if (bvid != null) { url = $"{baseUrl}&bvid={bvid}"; } else if (avid > -1) { url = $"{baseUrl}&aid={avid}"; } diff --git a/DownKyi.Core/BiliApi/WebClient.cs b/DownKyi.Core/BiliApi/WebClient.cs index 9a514e0..7d3a676 100644 --- a/DownKyi.Core/BiliApi/WebClient.cs +++ b/DownKyi.Core/BiliApi/WebClient.cs @@ -49,7 +49,13 @@ namespace DownKyi.Core.BiliApi HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = method; request.Timeout = 30 * 1000; - request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"; + + // MacOS Safari + string safari = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15"; + // Windows 10 Chrome + string chrome = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"; + request.UserAgent = chrome; + //request.ContentType = "application/json,text/html,application/xhtml+xml,application/xml;charset=UTF-8"; request.Headers["accept-language"] = "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"; request.Headers["accept-encoding"] = "gzip, deflate, br"; diff --git a/DownKyi.Core/DownKyi.Core.csproj b/DownKyi.Core/DownKyi.Core.csproj index a5cb204..4fda17f 100644 --- a/DownKyi.Core/DownKyi.Core.csproj +++ b/DownKyi.Core/DownKyi.Core.csproj @@ -211,6 +211,7 @@ + diff --git a/DownKyi.Core/Utils/ListHelper.cs b/DownKyi.Core/Utils/ListHelper.cs index bee195d..b7f8a28 100644 --- a/DownKyi.Core/Utils/ListHelper.cs +++ b/DownKyi.Core/Utils/ListHelper.cs @@ -1,15 +1,31 @@ using System.Collections.Generic; +using System.Collections.ObjectModel; namespace DownKyi.Core.Utils { public static class ListHelper { + /// + /// 判断ObservableCollection中是否存在,不存在则添加 + /// + /// + /// + /// + public static void AddUnique(ObservableCollection list, T item) + { + if (!list.Contains(item)) + { + list.Add(item); + } + } + /// /// 判断List中是否存在,不存在则添加 /// /// /// + /// public static void AddUnique(List list, T item) { if (!list.Exists(t => t.Equals(item))) diff --git a/DownKyi/Services/Download/AddToDownloadService.cs b/DownKyi/Services/Download/AddToDownloadService.cs index d9ce014..939dcf6 100644 --- a/DownKyi/Services/Download/AddToDownloadService.cs +++ b/DownKyi/Services/Download/AddToDownloadService.cs @@ -119,6 +119,15 @@ namespace DownKyi.Services.Download } }; } + + // 将所有视频设置为选中 + foreach (VideoSection section in videoSections) + { + foreach (var item in section.VideoPages) + { + item.IsSelected = true; + } + } } /// @@ -200,6 +209,9 @@ namespace DownKyi.Services.Download { foreach (VideoPage page in section.VideoPages) { + // 只下载选中项,跳过未选中项 + if (!page.IsSelected) { continue; } + // 没有解析的也跳过 if (page.PlayUrl == null) { continue; } @@ -282,7 +294,7 @@ namespace DownKyi.Services.Download .SetVideoZone(videoInfoView.VideoZone.Split('>')[0]) .SetAudioQuality(page.AudioQualityFormat) .SetVideoQuality(page.VideoQuality == null ? "" : page.VideoQuality.QualityFormat) - .SetVideoCodec(page.VideoQuality == null ? "" : page.VideoQuality.SelectedVideoCodec.Contains("AVC") ? "AVC" : page.VideoQuality.SelectedVideoCodec.Contains("HEVC") ? "HEVC" : ""); + .SetVideoCodec(page.VideoQuality == null ? "" : page.VideoQuality.SelectedVideoCodec.Contains("AVC") ? "AVC" : page.VideoQuality.SelectedVideoCodec.Contains("HEVC") ? "HEVC" : page.VideoQuality.SelectedVideoCodec.Contains("Dolby") ? "Dolby Vision" : ""); string filePath = Path.Combine(directory, fileName.RelativePath()); // 视频类别 diff --git a/DownKyi/Services/Download/AriaDownloadService.cs b/DownKyi/Services/Download/AriaDownloadService.cs index c563825..fa9cea8 100644 --- a/DownKyi/Services/Download/AriaDownloadService.cs +++ b/DownKyi/Services/Download/AriaDownloadService.cs @@ -71,6 +71,17 @@ namespace DownKyi.Services.Download } } + // 避免Dolby==null及其它未知情况,直接使用异常捕获 + try + { + // Dolby Atmos + if (downloading.AudioCodec.Id == 30250) + { + downloadAudio = downloading.PlayUrl.Dash.Dolby.Audio[0]; + } + } + catch (Exception) { } + return DownloadVideo(downloading, downloadAudio); } @@ -892,7 +903,7 @@ namespace DownKyi.Services.Download $"Cookie: {LoginHelper.GetLoginInfoCookiesString()}", $"Origin: https://www.bilibili.com", $"Referer: https://www.bilibili.com", - $"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 91.0.4472.77 Safari / 537.36" + $"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36" }; AriaConfig config = new AriaConfig() diff --git a/DownKyi/Services/Utils.cs b/DownKyi/Services/Utils.cs index 7489c1c..25f9725 100644 --- a/DownKyi/Services/Utils.cs +++ b/DownKyi/Services/Utils.cs @@ -5,6 +5,7 @@ using DownKyi.Core.Settings.Models; using DownKyi.Core.Utils; using DownKyi.ViewModels.PageViewModels; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; namespace DownKyi.Services @@ -94,13 +95,13 @@ namespace DownKyi.Services /// /// /// - private static List GetAudioQualityFormatList(PlayUrl playUrl, int defaultAudioQuality) + private static ObservableCollection GetAudioQualityFormatList(PlayUrl playUrl, int defaultAudioQuality) { List audioQualityFormatList = new List(); if (playUrl.Dash.Audio == null) { - return audioQualityFormatList; + return new ObservableCollection(); } foreach (PlayUrlDashVideo audio in playUrl.Dash.Audio) @@ -118,7 +119,7 @@ namespace DownKyi.Services audioQualityFormatList.Sort(new StringLogicalComparer()); audioQualityFormatList.Reverse(); - return audioQualityFormatList; + return new ObservableCollection(audioQualityFormatList); } /// @@ -221,7 +222,7 @@ namespace DownKyi.Services /// internal static string GetVideoCodecName(string origin) { - return origin.Contains("avc") ? "H.264/AVC" : origin.Contains("hev") ? "H.265/HEVC" : origin.Contains("dvh") ? "dolby" : ""; + return origin.Contains("avc") ? "H.264/AVC" : origin.Contains("hev") ? "H.265/HEVC" : origin.Contains("dvh") || origin.Contains("hvc") ? "Dolby Vision" : ""; } } diff --git a/DownKyi/ViewModels/PageViewModels/VideoPage.cs b/DownKyi/ViewModels/PageViewModels/VideoPage.cs index 6d7704e..08b9373 100644 --- a/DownKyi/ViewModels/PageViewModels/VideoPage.cs +++ b/DownKyi/ViewModels/PageViewModels/VideoPage.cs @@ -1,6 +1,10 @@ -using DownKyi.Core.BiliApi.VideoStream.Models; +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.VideoStream.Models; +using DownKyi.Core.Utils; +using Prism.Commands; using Prism.Mvvm; using System.Collections.Generic; +using System.Collections.ObjectModel; namespace DownKyi.ViewModels.PageViewModels { @@ -43,8 +47,8 @@ namespace DownKyi.ViewModels.PageViewModels set => SetProperty(ref duration, value); } - private List audioQualityFormatList; - public List AudioQualityFormatList + private ObservableCollection audioQualityFormatList; + public ObservableCollection AudioQualityFormatList { get => audioQualityFormatList; set => SetProperty(ref audioQualityFormatList, value); @@ -71,5 +75,37 @@ namespace DownKyi.ViewModels.PageViewModels set => SetProperty(ref videoQuality, value); } + + #region + + // 视频画质选择事件 + private DelegateCommand videoQualitySelectedCommand; + public DelegateCommand VideoQualitySelectedCommand => videoQualitySelectedCommand ?? (videoQualitySelectedCommand = new DelegateCommand(ExecuteVideoQualitySelectedCommand)); + + /// + /// 视频画质选择事件 + /// + private void ExecuteVideoQualitySelectedCommand() + { + // 杜比视界 + string dolby = Constant.GetAudioQualities()[3].Name; + if (VideoQuality.Quality == 126) + { + ListHelper.AddUnique(AudioQualityFormatList, dolby); + AudioQualityFormat = dolby; + } + else + { + if (AudioQualityFormatList.Contains(dolby)) + { + AudioQualityFormatList.Remove(dolby); + AudioQualityFormat = AudioQualityFormatList[0]; + } + } + + } + + #endregion + } } diff --git a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs index f2cd1f0..a36ac6d 100644 --- a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs +++ b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs @@ -125,6 +125,7 @@ namespace DownKyi.ViewModels.Settings // 优先下载音质 AudioQualityList = Constant.GetAudioQualities(); + AudioQualityList.RemoveAt(3); // 文件命名格式 SelectedFileName = new ObservableCollection(); diff --git a/DownKyi/Views/ViewVideoDetail.xaml b/DownKyi/Views/ViewVideoDetail.xaml index 08d0042..0c62303 100644 --- a/DownKyi/Views/ViewVideoDetail.xaml +++ b/DownKyi/Views/ViewVideoDetail.xaml @@ -619,14 +619,14 @@ DisplayMemberBinding="{Binding Order}" Header="{DynamicResource Order}" /> - + @@ -644,7 +644,13 @@ IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding VideoQualityList, Mode=TwoWay, IsAsync=True}" SelectedItem="{Binding VideoQuality, Mode=TwoWay}" - SelectedValuePath="Quality" /> + SelectedValuePath="Quality"> + + + + + +