Skip to content

Commit

Permalink
支持Hi-Res无损音频格式,支持AV1编码视频格式
Browse files Browse the repository at this point in the history
  • Loading branch information
leiurayer committed Oct 16, 2022
1 parent 6a511ca commit e09b4bc
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 96 deletions.
20 changes: 20 additions & 0 deletions src/DownKyi.Core/BiliApi/BiliUtils/Constant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,20 @@ public static class Constant
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>
{
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 },
new Quality { Name = "Hi-Res无损", Id = 30251 },
};

/// <summary>
Expand All @@ -39,6 +47,18 @@ public static List<Quality> GetResolutions()
return new List<Quality>(resolutions);
}

/// <summary>
/// 获取视频编码代码
/// </summary>
/// <returns></returns>
public static List<Quality> GetCodecIds()
{
// 使用深复制,
// 保证外部修改list后,
// 不会影响其他调用处
return new List<Quality>(codecIds);
}

/// <summary>
/// 获取支持的视频音质
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions src/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ public class PlayUrlDash : BaseModel
public List<PlayUrlDashVideo> Audio { get; set; }
[JsonProperty("dolby")]
public PlayUrlDashDolby Dolby { get; set; }
[JsonProperty("flac")]
public PlayUrlDashFlac Flac { get; set; }
}
}
12 changes: 12 additions & 0 deletions src/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashFlac.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using DownKyi.Core.BiliApi.Models;
using Newtonsoft.Json;

namespace DownKyi.Core.BiliApi.VideoStream.Models
{
public class PlayUrlDashFlac : BaseModel
{
[JsonProperty("audio")]
public PlayUrlDashVideo Audio { get; set; }
//bool display { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class PlayUrlDashVideo : BaseModel
// start_with_sap
// SegmentBase
// segment_base
// codecid
[JsonProperty("codecid")]
public int CodecId { get; set; }
}
}
1 change: 1 addition & 0 deletions src/DownKyi.Core/DownKyi.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
<Compile Include="BiliApi\VideoStream\Models\PlayUrl.cs" />
<Compile Include="BiliApi\VideoStream\Models\PlayUrlDash.cs" />
<Compile Include="BiliApi\VideoStream\Models\PlayUrlDashDolby.cs" />
<Compile Include="BiliApi\VideoStream\Models\PlayUrlDashFlac.cs" />
<Compile Include="BiliApi\VideoStream\Models\PlayUrlDashVideo.cs" />
<Compile Include="BiliApi\VideoStream\Models\PlayUrlDurl.cs" />
<Compile Include="BiliApi\VideoStream\Models\PlayUrlSupportFormat.cs" />
Expand Down
10 changes: 7 additions & 3 deletions src/DownKyi.Core/FFmpeg/FFmpegHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,19 @@ static FFmpegHelper()
/// <param name="destVideo"></param>
public static bool MergeVideo(string video1, string video2, string destVideo)
{
string param = $"-y -i \"{video1}\" -i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\"";
string param = $"-y -i \"{video1}\" -i \"{video2}\" -strict -2 -acodec copy -vcodec copy -f mp4 \"{destVideo}\"";
if (video1 == null || !File.Exists(video1))
{
param = $"-y -i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\"";
param = $"-y -i \"{video2}\" -strict -2 -acodec copy -vcodec copy -f mp4 \"{destVideo}\"";
}
if (video2 == null || !File.Exists(video2))
{
param = $"-y -i \"{video1}\" -acodec copy \"{destVideo}\"";
param = $"-y -i \"{video1}\" -strict -2 -acodec copy \"{destVideo}\"";
}

// 支持flac格式音频
//param += " -strict -2";

if (!File.Exists(video1) && !File.Exists(video2)) { return false; }

// 如果存在
Expand Down
2 changes: 1 addition & 1 deletion src/DownKyi.Core/Settings/Models/VideoSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace DownKyi.Core.Settings.Models
/// </summary>
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 AudioQuality { get; set; } = -1; // 音质
public AllowStatus IsTranscodingFlvToMp4 { get; set; } = AllowStatus.NONE; // 是否将flv转为mp4
Expand Down
8 changes: 4 additions & 4 deletions src/DownKyi.Core/Settings/SettingsManager.Video.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace DownKyi.Core.Settings
public partial class SettingsManager
{
// 设置优先下载的视频编码
private readonly VideoCodecs videoCodecs = VideoCodecs.AVC;
private readonly int videoCodecs = 7;

// 设置优先下载画质
private readonly int quality = 120;
Expand Down Expand Up @@ -58,10 +58,10 @@ public partial class SettingsManager
/// 获取优先下载的视频编码
/// </summary>
/// <returns></returns>
public VideoCodecs GetVideoCodecs()
public int GetVideoCodecs()
{
appSettings = GetSettings();
if (appSettings.Video.VideoCodecs == VideoCodecs.NONE)
if (appSettings.Video.VideoCodecs == -1)
{
// 第一次获取,先设置默认值
SetVideoCodecs(videoCodecs);
Expand All @@ -75,7 +75,7 @@ public VideoCodecs GetVideoCodecs()
/// </summary>
/// <param name="videoCodecs"></param>
/// <returns></returns>
public bool SetVideoCodecs(VideoCodecs videoCodecs)
public bool SetVideoCodecs(int videoCodecs)
{
appSettings.Video.VideoCodecs = videoCodecs;
return SetSettings();
Expand Down
12 changes: 10 additions & 2 deletions src/DownKyi/Services/Download/DownloadService.cs
Original file line number Diff line number Diff line change
@@ -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.Danmaku2Ass;
using DownKyi.Core.FFmpeg;
Expand All @@ -14,6 +15,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -82,6 +84,11 @@ protected PlayUrlDashVideo BaseDownloadAudio(DownloadingItem downloading)
{
downloadAudio = downloading.PlayUrl.Dash.Dolby.Audio[0];
}
// Hi-Res无损
if (downloading.AudioCodec.Id == 30251)
{
downloadAudio = downloading.PlayUrl.Dash.Flac.Audio;
}
}
catch (Exception) { }

Expand Down Expand Up @@ -110,7 +117,8 @@ protected PlayUrlDashVideo BaseDownloadVideo(DownloadingItem downloading)
PlayUrlDashVideo downloadVideo = null;
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;
break;
Expand Down
75 changes: 47 additions & 28 deletions src/DownKyi/Services/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal static void VideoPageInfo(PlayUrl playUrl, VideoPage page)
// 获取设置
UserInfoSettings userInfo = SettingsManager.GetInstance().GetUserInfo();
int defaultQuality = SettingsManager.GetInstance().GetQuality();
VideoCodecs videoCodecs = SettingsManager.GetInstance().GetVideoCodecs();
int videoCodecs = SettingsManager.GetInstance().GetVideoCodecs();
int defaultAudioQuality = SettingsManager.GetInstance().GetAudioQuality();

// 未登录时,最高仅720P
Expand Down Expand Up @@ -132,25 +132,37 @@ private static ObservableCollection<string> GetAudioQualityFormatList_old(PlayUr
private static ObservableCollection<string> GetAudioQualityFormatList(PlayUrl playUrl, int defaultAudioQuality)
{
List<string> audioQualityFormatList = new List<string>();
List<Quality> audioQualities = Constant.GetAudioQualities();

if (playUrl.Dash.Audio != null && playUrl.Dash.Audio.Count > 0)
{
foreach (PlayUrlDashVideo audio in playUrl.Dash.Audio)
{
// 音质id大于设置画质时,跳过
// 音质id大于设置音质时,跳过
if (audio.Id > defaultAudioQuality) { continue; }

Quality audioQuality = Constant.GetAudioQualities().FirstOrDefault(t => { return t.Id == audio.Id; });
Quality audioQuality = audioQualities.FirstOrDefault(t => { return t.Id == audio.Id; });
if (audioQuality != null)
{
ListHelper.AddUnique(audioQualityFormatList, audioQuality.Name);
}
}
}

if (playUrl.Dash.Dolby.Audio != null && playUrl.Dash.Dolby.Audio.Count > 0)
if (audioQualities[3].Id <= defaultAudioQuality - 1000 && playUrl.Dash.Dolby != null)
{
ListHelper.AddUnique(audioQualityFormatList, Constant.GetAudioQualities().Last().Name);
if (playUrl.Dash.Dolby.Audio != null && playUrl.Dash.Dolby.Audio.Count > 0)
{
ListHelper.AddUnique(audioQualityFormatList, audioQualities[3].Name);
}
}

if (audioQualities[4].Id <= defaultAudioQuality - 1000 && playUrl.Dash.Flac != null)
{
if (playUrl.Dash.Flac.Audio != null)
{
ListHelper.AddUnique(audioQualityFormatList, audioQualities[4].Name);
}
}

audioQualityFormatList.Sort(new StringLogicalComparer<string>());
Expand All @@ -167,9 +179,10 @@ private static ObservableCollection<string> GetAudioQualityFormatList(PlayUrl pl
/// <param name="userInfo"></param>
/// <param name="videoCodecs"></param>
/// <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<Quality> codeIds = Constant.GetCodecIds();

if (playUrl.Dash.Video == null)
{
Expand Down Expand Up @@ -197,7 +210,8 @@ private static List<VideoQuality> GetVideoQualityList(PlayUrl playUrl, UserInfoS

// 寻找是否已存在这个画质
// 不存在则添加,存在则修改
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);
if (videoQualityExist == null)
{
Expand Down Expand Up @@ -237,24 +251,29 @@ private static List<VideoQuality> GetVideoQualityList(PlayUrl playUrl, UserInfoS
}

// 设置选中的视频编码
switch (videoCodecs)
//switch (videoCodecs)
//{
// case VideoCodecs.AVC:
// if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.264/AVC"))
// {
// videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.264/AVC";
// }
// break;
// case VideoCodecs.HEVC:
// if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.265/HEVC"))
// {
// videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.265/HEVC";
// }
// break;
// case VideoCodecs.NONE:
// break;
// default:
// break;
//}
string videoCodecsName = codeIds.FirstOrDefault(t => t.Id == videoCodecs).Name;
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains(videoCodecsName))
{
case VideoCodecs.AVC:
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.264/AVC"))
{
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.264/AVC";
}
break;
case VideoCodecs.HEVC:
if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.265/HEVC"))
{
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.265/HEVC";
}
break;
case VideoCodecs.NONE:
break;
default:
break;
videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = videoCodecsName;
}

}
Expand All @@ -267,10 +286,10 @@ private static List<VideoQuality> GetVideoQualityList(PlayUrl playUrl, UserInfoS
/// </summary>
/// <param name="origin"></param>
/// <returns></returns>
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" : "";
}
//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" : "";
//}

}
}
Loading

0 comments on commit e09b4bc

Please sign in to comment.