支持AV1编码视频

croire 2 years ago
parent a35d8a0334
commit 0dde0bceb5

@ -19,6 +19,13 @@ namespace DownKyi.Core.BiliApi.BiliUtils
new Quality { Name = "360P 流畅", Id = 16 }, new Quality { Name = "360P 流畅", Id = 16 },
}; };
private static readonly List<Quality> codecIds = new List<Quality>
{
new Quality { Name = "H.264/AVC", Id = 7 },
new Quality { Name = "H.265/HEVC", Id = 12 },
new Quality { Name = "AV1", Id = 13 },
};
private static readonly List<Quality> qualities = new List<Quality> private static readonly List<Quality> qualities = new List<Quality>
{ {
new Quality { Name = "64K", Id = 30216 }, new Quality { Name = "64K", Id = 30216 },
@ -40,6 +47,18 @@ namespace DownKyi.Core.BiliApi.BiliUtils
return new List<Quality>(resolutions); return new List<Quality>(resolutions);
} }
/// <summary>
/// 获取视频编码代码
/// </summary>
/// <returns></returns>
public static List<Quality> GetCodecIds()
{
// 使用深复制,
// 保证外部修改list后
// 不会影响其他调用处
return new List<Quality>(codecIds);
}
/// <summary> /// <summary>
/// 获取支持的视频音质 /// 获取支持的视频音质
/// </summary> /// </summary>

@ -30,6 +30,7 @@ namespace DownKyi.Core.BiliApi.VideoStream.Models
// start_with_sap // start_with_sap
// SegmentBase // SegmentBase
// segment_base // segment_base
// codecid [JsonProperty("codecid")]
public int CodecId { get; set; }
} }
} }

@ -8,7 +8,7 @@ namespace DownKyi.Core.Settings.Models
/// </summary> /// </summary>
public class VideoSettings public class VideoSettings
{ {
public VideoCodecs VideoCodecs { get; set; } = VideoCodecs.NONE; // AVC or HEVC public int VideoCodecs { get; set; } = -1; // AVC or HEVC
public int Quality { get; set; } = -1; // 画质 public int Quality { get; set; } = -1; // 画质
public int AudioQuality { get; set; } = -1; // 音质 public int AudioQuality { get; set; } = -1; // 音质
public AllowStatus IsTranscodingFlvToMp4 { get; set; } = AllowStatus.NONE; // 是否将flv转为mp4 public AllowStatus IsTranscodingFlvToMp4 { get; set; } = AllowStatus.NONE; // 是否将flv转为mp4

@ -9,7 +9,7 @@ namespace DownKyi.Core.Settings
public partial class SettingsManager public partial class SettingsManager
{ {
// 设置优先下载的视频编码 // 设置优先下载的视频编码
private readonly VideoCodecs videoCodecs = VideoCodecs.AVC; private readonly int videoCodecs = 7;
// 设置优先下载画质 // 设置优先下载画质
private readonly int quality = 120; private readonly int quality = 120;
@ -58,10 +58,10 @@ namespace DownKyi.Core.Settings
/// 获取优先下载的视频编码 /// 获取优先下载的视频编码
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public VideoCodecs GetVideoCodecs() public int GetVideoCodecs()
{ {
appSettings = GetSettings(); appSettings = GetSettings();
if (appSettings.Video.VideoCodecs == VideoCodecs.NONE) if (appSettings.Video.VideoCodecs == -1)
{ {
// 第一次获取,先设置默认值 // 第一次获取,先设置默认值
SetVideoCodecs(videoCodecs); SetVideoCodecs(videoCodecs);
@ -75,7 +75,7 @@ namespace DownKyi.Core.Settings
/// </summary> /// </summary>
/// <param name="videoCodecs"></param> /// <param name="videoCodecs"></param>
/// <returns></returns> /// <returns></returns>
public bool SetVideoCodecs(VideoCodecs videoCodecs) public bool SetVideoCodecs(int videoCodecs)
{ {
appSettings.Video.VideoCodecs = videoCodecs; appSettings.Video.VideoCodecs = videoCodecs;
return SetSettings(); return SetSettings();

@ -1,4 +1,5 @@
using DownKyi.Core.BiliApi.VideoStream; using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.BiliApi.VideoStream.Models; using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Core.Danmaku2Ass; using DownKyi.Core.Danmaku2Ass;
using DownKyi.Core.FFmpeg; using DownKyi.Core.FFmpeg;
@ -14,6 +15,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -115,7 +117,8 @@ namespace DownKyi.Services.Download
PlayUrlDashVideo downloadVideo = null; PlayUrlDashVideo downloadVideo = null;
foreach (PlayUrlDashVideo video in downloading.PlayUrl.Dash.Video) foreach (PlayUrlDashVideo video in downloading.PlayUrl.Dash.Video)
{ {
if (video.Id == downloading.Resolution.Id && Utils.GetVideoCodecName(video.Codecs) == downloading.VideoCodecName) Quality codecs = Constant.GetCodecIds().FirstOrDefault(t => t.Id == video.CodecId);
if (video.Id == downloading.Resolution.Id && codecs.Name == downloading.VideoCodecName)
{ {
downloadVideo = video; downloadVideo = video;
break; break;

@ -30,7 +30,7 @@ namespace DownKyi.Services
// 获取设置 // 获取设置
UserInfoSettings userInfo = SettingsManager.GetInstance().GetUserInfo(); UserInfoSettings userInfo = SettingsManager.GetInstance().GetUserInfo();
int defaultQuality = SettingsManager.GetInstance().GetQuality(); int defaultQuality = SettingsManager.GetInstance().GetQuality();
VideoCodecs videoCodecs = SettingsManager.GetInstance().GetVideoCodecs(); int videoCodecs = SettingsManager.GetInstance().GetVideoCodecs();
int defaultAudioQuality = SettingsManager.GetInstance().GetAudioQuality(); int defaultAudioQuality = SettingsManager.GetInstance().GetAudioQuality();
// 未登录时最高仅720P // 未登录时最高仅720P
@ -179,9 +179,10 @@ namespace DownKyi.Services
/// <param name="userInfo"></param> /// <param name="userInfo"></param>
/// <param name="videoCodecs"></param> /// <param name="videoCodecs"></param>
/// <returns></returns> /// <returns></returns>
private static List<VideoQuality> GetVideoQualityList(PlayUrl playUrl, UserInfoSettings userInfo, int defaultQuality, VideoCodecs videoCodecs) private static List<VideoQuality> GetVideoQualityList(PlayUrl playUrl, UserInfoSettings userInfo, int defaultQuality, int videoCodecs)
{ {
List<VideoQuality> videoQualityList = new List<VideoQuality>(); List<VideoQuality> videoQualityList = new List<VideoQuality>();
List<Quality> codeIds = Constant.GetCodecIds();
if (playUrl.Dash.Video == null) if (playUrl.Dash.Video == null)
{ {
@ -209,7 +210,8 @@ namespace DownKyi.Services
// 寻找是否已存在这个画质 // 寻找是否已存在这个画质
// 不存在则添加,存在则修改 // 不存在则添加,存在则修改
string codecName = GetVideoCodecName(video.Codecs); //string codecName = GetVideoCodecName(video.Codecs);
string codecName = codeIds.FirstOrDefault(t => t.Id == video.CodecId).Name;
VideoQuality videoQualityExist = videoQualityList.FirstOrDefault(t => t.Quality == video.Id); VideoQuality videoQualityExist = videoQualityList.FirstOrDefault(t => t.Quality == video.Id);
if (videoQualityExist == null) if (videoQualityExist == null)
{ {
@ -249,24 +251,29 @@ namespace DownKyi.Services
} }
// 设置选中的视频编码 // 设置选中的视频编码
switch (videoCodecs) //switch (videoCodecs)
{ //{
case VideoCodecs.AVC: // case VideoCodecs.AVC:
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.264/AVC")) // if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.264/AVC"))
{ // {
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.264/AVC"; // videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.264/AVC";
} // }
break; // break;
case VideoCodecs.HEVC: // case VideoCodecs.HEVC:
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.265/HEVC")) // if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.265/HEVC"))
{ // {
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.265/HEVC"; // videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.265/HEVC";
} // }
break; // break;
case VideoCodecs.NONE: // case VideoCodecs.NONE:
break; // break;
default: // default:
break; // break;
//}
string videoCodecsName = codeIds.FirstOrDefault(t => t.Id == videoCodecs).Name;
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains(videoCodecsName))
{
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = videoCodecsName;
} }
} }
@ -279,10 +286,10 @@ namespace DownKyi.Services
/// </summary> /// </summary>
/// <param name="origin"></param> /// <param name="origin"></param>
/// <returns></returns> /// <returns></returns>
internal static string GetVideoCodecName(string origin) //internal static string GetVideoCodecName(string origin)
{ //{
return origin.Contains("avc") ? "H.264/AVC" : origin.Contains("hev") ? "H.265/HEVC" : origin.Contains("dvh") || origin.Contains("hvc") ? "Dolby Vision" : ""; // return origin.Contains("avc") ? "H.264/AVC" : origin.Contains("hev") ? "H.265/HEVC" : origin.Contains("dvh") || origin.Contains("hvc") ? "Dolby Vision" : "";
} //}
} }
} }

@ -24,15 +24,15 @@ namespace DownKyi.ViewModels.Settings
#region 页面属性申明 #region 页面属性申明
private List<string> videoCodecs; private List<Quality> videoCodecs;
public List<string> VideoCodecs public List<Quality> VideoCodecs
{ {
get => videoCodecs; get => videoCodecs;
set => SetProperty(ref videoCodecs, value); set => SetProperty(ref videoCodecs, value);
} }
private string selectedVideoCodec; private Quality selectedVideoCodec;
public string SelectedVideoCodec public Quality SelectedVideoCodec
{ {
get => selectedVideoCodec; get => selectedVideoCodec;
set => SetProperty(ref selectedVideoCodec, value); set => SetProperty(ref selectedVideoCodec, value);
@ -186,11 +186,12 @@ namespace DownKyi.ViewModels.Settings
#region 属性初始化 #region 属性初始化
// 优先下载的视频编码 // 优先下载的视频编码
VideoCodecs = new List<string> VideoCodecs = Constant.GetCodecIds();
{ //VideoCodecs = new List<string>
"H.264/AVC", //{
"H.265/HEVC", // "H.264/AVC",
}; // "H.265/HEVC",
//};
// 优先下载画质 // 优先下载画质
VideoQualityList = Constant.GetResolutions(); VideoQualityList = Constant.GetResolutions();
@ -255,8 +256,9 @@ namespace DownKyi.ViewModels.Settings
isOnNavigatedTo = true; isOnNavigatedTo = true;
// 优先下载的视频编码 // 优先下载的视频编码
VideoCodecs videoCodecs = SettingsManager.GetInstance().GetVideoCodecs(); int videoCodecs = SettingsManager.GetInstance().GetVideoCodecs();
SelectedVideoCodec = GetVideoCodecsString(videoCodecs); //SelectedVideoCodec = GetVideoCodecsString(videoCodecs);
SelectedVideoCodec = VideoCodecs.FirstOrDefault(t => { return t.Id == videoCodecs; });
// 优先下载画质 // 优先下载画质
int quality = SettingsManager.GetInstance().GetQuality(); int quality = SettingsManager.GetInstance().GetQuality();
@ -317,18 +319,20 @@ namespace DownKyi.ViewModels.Settings
#region 命令申明 #region 命令申明
// 优先下载的视频编码事件 // 优先下载的视频编码事件
private DelegateCommand<string> videoCodecsCommand; private DelegateCommand<object> videoCodecsCommand;
public DelegateCommand<string> VideoCodecsCommand => videoCodecsCommand ?? (videoCodecsCommand = new DelegateCommand<string>(ExecuteVideoCodecsCommand)); public DelegateCommand<object> VideoCodecsCommand => videoCodecsCommand ?? (videoCodecsCommand = new DelegateCommand<object>(ExecuteVideoCodecsCommand));
/// <summary> /// <summary>
/// 优先下载的视频编码事件 /// 优先下载的视频编码事件
/// </summary> /// </summary>
/// <param name="parameter"></param> /// <param name="parameter"></param>
private void ExecuteVideoCodecsCommand(string parameter) private void ExecuteVideoCodecsCommand(object parameter)
{ {
VideoCodecs videoCodecs = GetVideoCodecs(parameter); //VideoCodecs videoCodecs = GetVideoCodecs(parameter);
bool isSucceed = SettingsManager.GetInstance().SetVideoCodecs(videoCodecs); if (!(parameter is Quality videoCodecs)) { return; }
bool isSucceed = SettingsManager.GetInstance().SetVideoCodecs(videoCodecs.Id);
PublishTip(isSucceed); PublishTip(isSucceed);
} }
@ -676,49 +680,49 @@ namespace DownKyi.ViewModels.Settings
/// </summary> /// </summary>
/// <param name="videoCodecs"></param> /// <param name="videoCodecs"></param>
/// <returns></returns> /// <returns></returns>
private string GetVideoCodecsString(VideoCodecs videoCodecs) //private string GetVideoCodecsString(VideoCodecs videoCodecs)
{ //{
string codec; // string codec;
switch (videoCodecs) // switch (videoCodecs)
{ // {
case Core.Settings.VideoCodecs.NONE: // case Core.Settings.VideoCodecs.NONE:
codec = ""; // codec = "";
break; // break;
case Core.Settings.VideoCodecs.AVC: // case Core.Settings.VideoCodecs.AVC:
codec = "H.264/AVC"; // codec = "H.264/AVC";
break; // break;
case Core.Settings.VideoCodecs.HEVC: // case Core.Settings.VideoCodecs.HEVC:
codec = "H.265/HEVC"; // codec = "H.265/HEVC";
break; // break;
default: // default:
codec = ""; // codec = "";
break; // break;
} // }
return codec; // return codec;
} //}
/// <summary> /// <summary>
/// 返回VideoCodecs /// 返回VideoCodecs
/// </summary> /// </summary>
/// <param name="str"></param> /// <param name="str"></param>
/// <returns></returns> /// <returns></returns>
private VideoCodecs GetVideoCodecs(string str) //private VideoCodecs GetVideoCodecs(string str)
{ //{
VideoCodecs videoCodecs; // VideoCodecs videoCodecs;
switch (str) // switch (str)
{ // {
case "H.264/AVC": // case "H.264/AVC":
videoCodecs = Core.Settings.VideoCodecs.AVC; // videoCodecs = Core.Settings.VideoCodecs.AVC;
break; // break;
case "H.265/HEVC": // case "H.265/HEVC":
videoCodecs = Core.Settings.VideoCodecs.HEVC; // videoCodecs = Core.Settings.VideoCodecs.HEVC;
break; // break;
default: // default:
videoCodecs = Core.Settings.VideoCodecs.NONE; // videoCodecs = Core.Settings.VideoCodecs.NONE;
break; // break;
} // }
return videoCodecs; // return videoCodecs;
} //}
/// <summary> /// <summary>
/// 保存下载视频内容到设置 /// 保存下载视频内容到设置

@ -23,6 +23,7 @@
Name="nameVideoCodecs" Name="nameVideoCodecs"
Width="120" Width="120"
VerticalContentAlignment="Center" VerticalContentAlignment="Center"
DisplayMemberPath="Name"
ItemsSource="{Binding VideoCodecs}" ItemsSource="{Binding VideoCodecs}"
SelectedValue="{Binding SelectedVideoCodec}"> SelectedValue="{Binding SelectedVideoCodec}">
<i:Interaction.Triggers> <i:Interaction.Triggers>

Loading…
Cancel
Save