From 0fedce61a7032880ad0712bd1de199fdffcc87d8 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 13 Jul 2022 22:48:49 +0900 Subject: [PATCH] net7.0, aot and code fixes --- .github/workflows/build_latest.yml | 2 +- BBDown.Core/AppHelper.cs | 255 ++++----- BBDown.Core/BBDown.Core.csproj | 18 +- BBDown.Core/Config.cs | 10 +- BBDown.Core/DanmakuUtil.cs | 73 ++- BBDown.Core/Entity/Entity.cs | 85 +-- BBDown.Core/Entity/VInfo.cs | 42 +- BBDown.Core/Fetcher/BangumiInfoFetcher.cs | 36 +- BBDown.Core/Fetcher/CheeseInfoFetcher.cs | 33 +- BBDown.Core/Fetcher/FavListFetcher.cs | 43 +- BBDown.Core/Fetcher/IntlBangumiInfoFetcher.cs | 44 +- BBDown.Core/Fetcher/MediaListFetcher.cs | 37 +- BBDown.Core/Fetcher/NormalInfoFetcher.cs | 32 +- BBDown.Core/Fetcher/SeriesListFetcher.cs | 36 +- BBDown.Core/Fetcher/SpaceVideoFetcher.cs | 13 +- BBDown.Core/IFetcher.cs | 7 +- BBDown.Core/Logger.cs | 8 +- BBDown.Core/Parser.cs | 151 ++--- BBDown.Core/Util/HTTPUtil.cs | 24 +- BBDown.Core/Util/SubUtil.cs | 85 +-- BBDown/BBDown.csproj | 8 +- BBDown/BBDownAria2c.cs | 2 +- BBDown/BBDownMuxer.cs | 34 +- BBDown/BBDownUtil.cs | 335 +++++------ BBDown/ConsoleQRCode.cs | 6 +- BBDown/Directory.Build.props | 4 +- BBDown/Program.cs | 537 ++++++++---------- BBDown/ProgressBar.cs | 21 +- BBDown/rd.xml | 7 - 29 files changed, 920 insertions(+), 1068 deletions(-) diff --git a/.github/workflows/build_latest.yml b/.github/workflows/build_latest.yml index 56ea8b257..1a8c7062c 100644 --- a/.github/workflows/build_latest.yml +++ b/.github/workflows/build_latest.yml @@ -3,7 +3,7 @@ name: Build Latest on: [push] env: - DOTNET_SDK_VERSION: '6.0.x' + DOTNET_SDK_VERSION: '7.0.x' jobs: diff --git a/BBDown.Core/AppHelper.cs b/BBDown.Core/AppHelper.cs index dd5f7b2da..e598b0a29 100644 --- a/BBDown.Core/AppHelper.cs +++ b/BBDown.Core/AppHelper.cs @@ -1,41 +1,35 @@ using ProtoBuf; -using System; -using System.Collections.Generic; -using System.IO; using System.IO.Compression; -using System.Linq; -using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; using System.Text.Json.Serialization; -using System.Threading.Tasks; using static BBDown.Core.Logger; namespace BBDown.Core { class AppHelper { - private static string API = "https://grpc.biliapi.net/bilibili.app.playurl.v1.PlayURL/PlayView"; - private static string API2 = "https://app.bilibili.com/bilibili.pgc.gateway.player.v1.PlayURL/PlayView"; - private static string dalvikVer = "2.1.0"; - private static string osVer = "11"; - private static string brand = "M2012K11AC"; - private static string model = "Build/RKQ1.200826.002"; - private static string appVer = "6.32.0"; - private static int build = 6320200; - private static string channel = "xiaomi_cn_tv.danmaku.bili_zm20200902"; - private static Network.Type networkType = Network.Type.Wifi; - private static string networkOid = "46007"; - private static string cronet = "1.36.1"; - private static string buvid = ""; - private static string mobiApp = "android"; - private static string appKey = "android64"; - private static string sessionId = "dedf8669"; - private static string platform = "android"; - private static string env = "prod"; - private static int appId = 1; - private static string region = "CN"; - private static string language = "zh"; + private static readonly string API = "https://grpc.biliapi.net/bilibili.app.playurl.v1.PlayURL/PlayView"; + private static readonly string API2 = "https://app.bilibili.com/bilibili.pgc.gateway.player.v1.PlayURL/PlayView"; + private static readonly string dalvikVer = "2.1.0"; + private static readonly string osVer = "11"; + private static readonly string brand = "M2012K11AC"; + private static readonly string model = "Build/RKQ1.200826.002"; + private static readonly string appVer = "6.32.0"; + private static readonly int build = 6320200; + private static readonly string channel = "xiaomi_cn_tv.danmaku.bili_zm20200902"; + private static readonly Network.Type networkType = Network.Type.Wifi; + private static readonly string networkOid = "46007"; + private static readonly string cronet = "1.36.1"; + private static readonly string buvid = ""; + private static readonly string mobiApp = "android"; + private static readonly string appKey = "android64"; + private static readonly string sessionId = "dedf8669"; + private static readonly string platform = "android"; + private static readonly string env = "prod"; + private static readonly int appId = 1; + private static readonly string region = "CN"; + private static readonly string language = "zh"; /// /// 发起请求并返回响应报文(protobuf -> json) @@ -48,11 +42,11 @@ class AppHelper public static async Task DoReqAsync(string aid, string cid, string epId, string qn, bool bangumi, bool onlyAvc, string appkey = "") { var headers = GetHeader(appkey); - LogDebug("App-Req-Headers: {0}", ConvertToString(headers)); + LogDebug("App-Req-Headers: {0}", JsonSerializer.Serialize(headers, JsonContext.Default.DictionaryStringString)); var body = GetPayload(Convert.ToInt64(aid), Convert.ToInt64(cid), Convert.ToInt64(qn), onlyAvc ? PlayViewReq.CodeType.Code264 : PlayViewReq.CodeType.Code265); //Console.WriteLine(ReadMessage(body)); var data = await GetPostResponseAsync(API, body, headers); - PlayViewReply resp = null; + PlayViewReply? resp; try { resp = ReadMessage(data); @@ -75,7 +69,7 @@ public static async Task DoReqAsync(string aid, string cid, string epId, throw; } } - LogDebug("PlayViewReplyPlain: {0}", ConvertToString(resp)); + LogDebug("PlayViewReplyPlain: {0}", JsonSerializer.Serialize(resp, JsonContext.Default.PlayViewReply)); return ConvertToDashJson(resp); } @@ -144,23 +138,25 @@ private static string ConvertToDashJson(object data) ) ); - return ConvertToString(json); + return JsonSerializer.Serialize(json, JsonContext.Default.DashJson); } private static byte[] GetPayload(long aid, long cid, long qn, PlayViewReq.CodeType codec) { - var obj = new PlayViewReq(); - obj.epId = aid; - obj.Cid = cid; - //obj.Qn = qn; - obj.Qn = 126; - obj.Fnval = 976; - obj.Spmid = "main.ugc-video-detail.0.0"; - obj.fromSpmid = "main.my-history.0.0"; - obj.preferCodecType = codec; - obj.Download = 0; //0:播放 1:flv下载 2:dash下载 - obj.forceHost = 2; //0:允许使用ip 1:使用http 2:使用https - LogDebug("PayLoadPlain: {0}", ConvertToString(obj)); + var obj = new PlayViewReq + { + epId = aid, + Cid = cid, + //obj.Qn = qn; + Qn = 126, + Fnval = 976, + Spmid = "main.ugc-video-detail.0.0", + fromSpmid = "main.my-history.0.0", + preferCodecType = codec, + Download = 0, //0:播放 1:flv下载 2:dash下载 + forceHost = 2 //0:允许使用ip 1:使用http 2:使用https + }; + LogDebug("PayLoadPlain: {0}", JsonSerializer.Serialize(obj, JsonContext.Default.PlayViewReq)); return PackMessage(ObjectToBytes(obj)); } @@ -190,54 +186,66 @@ private static Dictionary GetHeader(string appkey) private static string GenerateLocaleBin() { - var obj = new Locale(); - obj.cLocale = new Locale.LocaleIds(); - obj.cLocale.Language = language; - obj.cLocale.Region = region; + var obj = new Locale + { + cLocale = new Locale.LocaleIds + { + Language = language, + Region = region + } + }; return SerializeToBase64(obj); } private static string GenerateNetworkBin() { - var obj = new Network(); - obj.type = networkType; - obj.Oid = networkOid; + var obj = new Network + { + type = networkType, + Oid = networkOid + }; return SerializeToBase64(obj); } private static string GenerateDeviceBin() { - var obj = new Device(); - obj.appId = appId; - obj.Build = build; - obj.Buvid = buvid; - obj.mobiApp = mobiApp; - obj.Platform = platform; - obj.Channel = channel; - obj.Brand = brand; - obj.Model = model; - obj.Osver = osVer; + var obj = new Device + { + appId = appId, + Build = build, + Buvid = buvid, + mobiApp = mobiApp, + Platform = platform, + Channel = channel, + Brand = brand, + Model = model, + Osver = osVer + }; return SerializeToBase64(obj); } private static string GenerateMetadataBin(string appkey) { - var obj = new Metadata(); - obj.accessKey = appkey; - obj.mobiApp = mobiApp; - obj.Build = build; - obj.Channel = channel; - obj.Buvid = buvid; - obj.Platform = platform; + var obj = new Metadata + { + accessKey = appkey, + mobiApp = mobiApp, + Build = build, + Channel = channel, + Buvid = buvid, + Platform = platform + }; return SerializeToBase64(obj); } private static string GenerateFawkesReqBin() { - var obj = new FawkesReq(); - obj.Appkey = appKey; - obj.Env = env; - obj.sessionId = sessionId; + var obj = new FawkesReq + { + Appkey = appKey, + Env = env, + sessionId = sessionId + }; return SerializeToBase64(obj); } @@ -246,13 +254,11 @@ private static string GenerateFawkesReqBin() /// /// /// - private static byte[] ObjectToBytes(object obj) + private static byte[] ObjectToBytes(T obj) { - using (var stream = new MemoryStream()) - { - Serializer.Serialize(stream, obj); - return stream.ToArray(); - } + using var stream = new MemoryStream(); + Serializer.Serialize(stream, obj); + return stream.ToArray(); } /// @@ -260,23 +266,13 @@ private static byte[] ObjectToBytes(object obj) /// /// /// - private static string SerializeToBase64(object obj) + private static string SerializeToBase64(T obj) { return Convert.ToBase64String(ObjectToBytes(obj)).TrimEnd('='); } #endregion - /// - /// 对象转字符串(json) - /// - /// - /// - private static string ConvertToString(object obj) - { - return JsonSerializer.Serialize(obj); - } - /// /// 读取gRPC响应流 通过前5字节信息 解析/解压后面的报文体 /// @@ -287,11 +283,7 @@ private static byte[] ReadMessage(byte[] data) byte first; int size; (first, size) = ReadInfo(data); - if (first == 1) - { - return GzipDecompress(data.Skip(5).ToArray()); - } - return data.Skip(5).Take(size).ToArray(); + return first == 1 ? GzipDecompress(data.Skip(5).ToArray()) : data.Skip(5).Take(size).ToArray(); } /// @@ -314,16 +306,12 @@ private static T ReadMessage(byte[] data) /// private static (byte first, int size) ReadInfo(byte[] data) { - using (var stream = new MemoryStream(data.Take(5).ToArray())) - { - using (var reader = new BinaryReader(stream)) - { - var value1 = reader.ReadByte(); - var value2 = reader.ReadBytes(4); + using var stream = new MemoryStream(data.Take(5).ToArray()); + using var reader = new BinaryReader(stream); + var value1 = reader.ReadByte(); + var value2 = reader.ReadBytes(4); - return (value1, BitConverter.ToInt32(value2.Reverse().ToArray())); - } - } + return (value1, BitConverter.ToInt32(value2.Reverse().ToArray())); } /// @@ -333,18 +321,16 @@ private static (byte first, int size) ReadInfo(byte[] data) /// private static byte[] PackMessage(byte[] input) { - using (var stream = new MemoryStream()) + using var stream = new MemoryStream(); + using (var writer = new BinaryWriter(stream)) { - using (var writer = new BinaryWriter(stream)) - { - var comp = GzipCompress(input); - var reverse = BitConverter.GetBytes(comp.Length).Reverse().ToArray(); - writer.Write((byte)1); - writer.Write(reverse); - writer.Write(comp); - } - return stream.ToArray(); + var comp = GzipCompress(input); + var reverse = BitConverter.GetBytes(comp.Length).Reverse().ToArray(); + writer.Write((byte)1); + writer.Write(reverse); + writer.Write(comp); } + return stream.ToArray(); } /// @@ -354,14 +340,12 @@ private static byte[] PackMessage(byte[] input) /// private static byte[] GzipCompress(byte[] data) { - using (var output = new MemoryStream()) + using var output = new MemoryStream(); + using (var comp = new GZipStream(output, CompressionMode.Compress)) { - using (var comp = new GZipStream(output, CompressionMode.Compress)) - { - comp.Write(data, 0, data.Length); - } - return output.ToArray(); + comp.Write(data, 0, data.Length); } + return output.ToArray(); } /// @@ -371,27 +355,23 @@ private static byte[] GzipCompress(byte[] data) /// private static byte[] GzipDecompress(byte[] data) { - using (var output = new MemoryStream()) + using var output = new MemoryStream(); + using (var input = new MemoryStream(data)) { - using (var input = new MemoryStream(data)) - { - using (var decomp = new GZipStream(input, CompressionMode.Decompress)) - { - decomp.CopyTo(output); - } - } - return output.ToArray(); + using var decomp = new GZipStream(input, CompressionMode.Decompress); + decomp.CopyTo(output); } + return output.ToArray(); } public static async Task GetPostResponseAsync(string Url, byte[] postData, Dictionary headers) { LogDebug("Post to: {0}, data: {1}", Url, Convert.ToBase64String(postData)); - ByteArrayContent content = new ByteArrayContent(postData); + ByteArrayContent content = new(postData); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/grpc"); - HttpRequestMessage request = new HttpRequestMessage() + HttpRequestMessage request = new() { RequestUri = new Uri(Url), Method = HttpMethod.Post, @@ -410,6 +390,13 @@ public static async Task GetPostResponseAsync(string Url, byte[] postDat } } + + [JsonSerializable(typeof(DashJson))] + [JsonSerializable(typeof(PlayViewReq))] + [JsonSerializable(typeof(PlayViewReply))] + [JsonSerializable(typeof(Dictionary))] + internal partial class JsonContext : JsonSerializerContext { } + internal class AudioInfoWithCodecName { [JsonPropertyName("id")] @@ -432,7 +419,7 @@ public AudioInfoWithCodecName(uint id, string base_url,List backup_url, Codecs = codecs; } - public override bool Equals(object obj) => obj is AudioInfoWithCodecName other && Id == other.Id && BaseUrl == other.BaseUrl && BackupUrl.SequenceEqual(other.BackupUrl) && Bandwidth == other.Bandwidth && Codecs == other.Codecs; + public override bool Equals(object? obj) => obj is AudioInfoWithCodecName other && Id == other.Id && BaseUrl == other.BaseUrl && BackupUrl.SequenceEqual(other.BackupUrl) && Bandwidth == other.Bandwidth && Codecs == other.Codecs; public override int GetHashCode() => HashCode.Combine(Id, BaseUrl, BackupUrl, Bandwidth, Codecs); } @@ -455,7 +442,7 @@ public AudioInfoWitCodecId(uint id, string base_url, uint bandwidth, uint codeci Codecid = codecid; } - public override bool Equals(object obj) => obj is AudioInfoWitCodecId other && Id == other.Id && BaseUrl == other.BaseUrl && Bandwidth == other.Bandwidth && Codecid == other.Codecid; + public override bool Equals(object? obj) => obj is AudioInfoWitCodecId other && Id == other.Id && BaseUrl == other.BaseUrl && Bandwidth == other.Bandwidth && Codecid == other.Codecid; public override int GetHashCode() => HashCode.Combine(Id, BaseUrl, Bandwidth, Codecid); } @@ -472,7 +459,7 @@ public DashInfo(List video, List audio) Audio = audio; } - public override bool Equals(object obj) => obj is DashInfo other && EqualityComparer>.Default.Equals(Video, other.Video) && EqualityComparer>.Default.Equals(Audio, other.Audio); + public override bool Equals(object? obj) => obj is DashInfo other && EqualityComparer>.Default.Equals(Video, other.Video) && EqualityComparer>.Default.Equals(Audio, other.Audio); public override int GetHashCode() => HashCode.Combine(Video, Audio); } @@ -489,7 +476,7 @@ public DashData(ulong timelength, DashInfo dash) Dash = dash; } - public override bool Equals(object obj) => obj is DashData other && TimeLength == other.TimeLength && EqualityComparer.Default.Equals(Dash, other.Dash); + public override bool Equals(object? obj) => obj is DashData other && TimeLength == other.TimeLength && EqualityComparer.Default.Equals(Dash, other.Dash); public override int GetHashCode() => HashCode.Combine(TimeLength, Dash); } @@ -512,7 +499,7 @@ public DashJson(int code, string message, int ttl, DashData data) Data = data; } - public override bool Equals(object obj) => obj is DashJson other && Code == other.Code && Message == other.Message && Ttl == other.Ttl && EqualityComparer.Default.Equals(Data, other.Data); + public override bool Equals(object? obj) => obj is DashJson other && Code == other.Code && Message == other.Message && Ttl == other.Ttl && EqualityComparer.Default.Equals(Data, other.Data); public override int GetHashCode() => HashCode.Combine(Code, Message, Ttl, Data); } } diff --git a/BBDown.Core/BBDown.Core.csproj b/BBDown.Core/BBDown.Core.csproj index 3434f45aa..cac4ea8b5 100644 --- a/BBDown.Core/BBDown.Core.csproj +++ b/BBDown.Core/BBDown.Core.csproj @@ -1,13 +1,21 @@ - + library - net6.0 + net7.0 enable enable + preview - - - + + + + + + + + + + diff --git a/BBDown.Core/Config.cs b/BBDown.Core/Config.cs index 1ad38b02d..967c6034f 100644 --- a/BBDown.Core/Config.cs +++ b/BBDown.Core/Config.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BBDown.Core +namespace BBDown.Core { public class Config { @@ -15,7 +9,7 @@ public class Config //日志级别 public static bool DEBUG_LOG { get; set; } = false; - public static Dictionary qualitys = new Dictionary() { + public static readonly Dictionary qualitys = new() { {"127","8K 超高清" }, {"126","杜比视界" }, {"125","HDR 真彩" }, {"120","4K 超清" }, {"116","1080P 高帧率" }, {"112","1080P 高码率" }, {"80","1080P 高清" }, {"74","720P 高帧率" }, {"64","720P 高清" }, {"48","720P 高清" }, {"32","480P 清晰" }, {"16","360P 流畅" } diff --git a/BBDown.Core/DanmakuUtil.cs b/BBDown.Core/DanmakuUtil.cs index 801c22744..8b23a36aa 100644 --- a/BBDown.Core/DanmakuUtil.cs +++ b/BBDown.Core/DanmakuUtil.cs @@ -12,7 +12,7 @@ public class DanmakuUtil private const double MOVE_SPEND_TIME = 8.00; //单条条滚动弹幕存在时间(控制速度) private const double TOP_SPEND_TIME = 4.00; //单条顶部或底部弹幕存在时间 private const int PROTECT_LENGTH = 50; //滚动弹幕屏占百分比 - public static readonly DanmakuComparer comparer = new DanmakuComparer(); + public static readonly DanmakuComparer comparer = new(); /*public static async Task DownloadAsync(Page p, string xmlPath, bool aria2c, string aria2cProxy) { @@ -20,12 +20,14 @@ public class DanmakuUtil await DownloadFile(danmakuUrl, xmlPath, aria2c, aria2cProxy); }*/ - public static DanmakuItem[] ParseXml(string xmlPath) + public static DanmakuItem[]? ParseXml(string xmlPath) { // 解析xml文件 - XmlDocument xmlFile = new XmlDocument(); - XmlReaderSettings settings = new XmlReaderSettings(); - settings.IgnoreComments = true;//忽略文档里面的注释 + XmlDocument xmlFile = new(); + XmlReaderSettings settings = new() + { + IgnoreComments = true//忽略文档里面的注释 + }; var danmakus = new List(); using (var reader = XmlReader.Create(xmlPath, settings)) { @@ -92,25 +94,19 @@ public static async Task SaveAsAssAsync(DanmakuItem[] danmakus, string outputPat sb.AppendLine("[Events]"); sb.AppendLine("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"); - PositionController controller = new PositionController(); // 弹幕位置控制器 + PositionController controller = new(); // 弹幕位置控制器 Array.Sort(danmakus, comparer); foreach (DanmakuItem danmaku in danmakus) { - int height = controller.updatePosition(danmaku.DanmakuMode, danmaku.Second, danmaku.Content.Length); + int height = controller.UpdatePosition(danmaku.DanmakuMode, danmaku.Second, danmaku.Content.Length); if (height == -1) continue; string effect = ""; - switch (danmaku.DanmakuMode) + effect += danmaku.DanmakuMode switch { - case 3: - effect += $"\\an8\\pos({MONITOR_WIDTH / 2}, {MONITOR_HEIGHT - FONT_SIZE - height})"; - break; - case 2: - effect += $"\\an8\\pos({MONITOR_WIDTH / 2}, {height})"; - break; - default: - effect += $"\\move({MONITOR_WIDTH}, {height}, {-danmaku.Content.Length * FONT_SIZE}, {height})"; - break; - } + 3 => $"\\an8\\pos({MONITOR_WIDTH / 2}, {MONITOR_HEIGHT - FONT_SIZE - height})", + 2 => $"\\an8\\pos({MONITOR_WIDTH / 2}, {height})", + _ => $"\\move({MONITOR_WIDTH}, {height}, {-danmaku.Content.Length * FONT_SIZE}, {height})", + }; if (danmaku.Color != "FFFFFF") { effect += $"\\c&{danmaku.Color}&"; @@ -123,11 +119,12 @@ public static async Task SaveAsAssAsync(DanmakuItem[] danmakus, string outputPat protected class PositionController { - int maxLine = MONITOR_HEIGHT * PROTECT_LENGTH / FONT_SIZE / 100; //总行数 - // 三个位置的弹幕队列,记录弹幕结束时间 - List moveQueue = new List(); - List topQueue = new List(); - List bottomQueue = new List(); + readonly int maxLine = MONITOR_HEIGHT * PROTECT_LENGTH / FONT_SIZE / 100; //总行数 + // 三个位置的弹幕队列,记录弹幕结束时间 + + readonly List moveQueue = new(); + readonly List topQueue = new(); + readonly List bottomQueue = new(); public PositionController() { @@ -139,7 +136,7 @@ public PositionController() } } - public int updatePosition(int type, double time, int length) + public int UpdatePosition(int type, double time, int length) { // 获取可用位置 List vs; @@ -155,7 +152,7 @@ public int updatePosition(int type, double time, int length) else { vs = moveQueue; - displayTime = MOVE_SPEND_TIME * (length + 5) * FONT_SIZE / (MONITOR_WIDTH + length * MOVE_SPEND_TIME); + displayTime = MOVE_SPEND_TIME * (length + 5) * FONT_SIZE / (MONITOR_WIDTH + (length * MOVE_SPEND_TIME)); } for (int i = 0; i < maxLine; i++) { @@ -173,24 +170,18 @@ public class DanmakuItem { public DanmakuItem(string[] attrs, string content) { - switch (attrs[1]) + DanmakuMode = attrs[1] switch { - case "4": - DanmakuMode = POS_BOTTOM; - break; - case "5": - DanmakuMode = POS_TOP; - break; - default: - DanmakuMode = POS_MOVE; - break; - } + "4" => POS_BOTTOM, + "5" => POS_TOP, + _ => POS_MOVE, + }; try { double second = double.Parse(attrs[0]); Second = second; - StartTime = computeTime(second); - EndTime = computeTime(second + (DanmakuMode == 1 ? MOVE_SPEND_TIME : TOP_SPEND_TIME)); + StartTime = ComputeTime(second); + EndTime = ComputeTime(second + (DanmakuMode == 1 ? MOVE_SPEND_TIME : TOP_SPEND_TIME)); } catch (Exception e) { @@ -209,11 +200,11 @@ public DanmakuItem(string[] attrs, string content) Timestamp = attrs[4]; Content = content; } - private string computeTime(double second) + private static string ComputeTime(double second) { int hour = (int)second / 3600; - int minute = (int)(second - hour * 3600) / 60; - second -= hour * 3600 + minute * 60; + int minute = (int)(second - (hour * 3600)) / 60; + second -= (hour * 3600) + (minute * 60); return hour.ToString() + string.Format(":{0:D2}:", minute) + string.Format("{0:00.00}", second); } public string Content { get; set; } = ""; diff --git a/BBDown.Core/Entity/Entity.cs b/BBDown.Core/Entity/Entity.cs index 8fe6f115e..1718fd2ec 100644 --- a/BBDown.Core/Entity/Entity.cs +++ b/BBDown.Core/Entity/Entity.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Diagnostics.CodeAnalysis; namespace BBDown.Core.Entity { @@ -8,19 +6,20 @@ public class Entity { public class Page { - public int index; - public string aid; - public string cid; - public string epid; - public string title; - public int dur; - public string res; - public string cover; - public string desc; - public string ownerName; - public string ownerMid; - public List points = new List(); - + public required int index; + public required string aid; + public required string cid; + public required string epid; + public required string title; + public required int dur; + public required string res; + public string? cover; + public string? desc; + public string? ownerName; + public string? ownerMid; + public List points = new(); + + [SetsRequiredMembers] public Page(int index, string aid, string cid, string epid, string title, int dur, string res) { this.aid = aid; @@ -32,6 +31,7 @@ public Page(int index, string aid, string cid, string epid, string title, int du this.res = res; } + [SetsRequiredMembers] public Page(int index, string aid, string cid, string epid, string title, int dur, string res, string cover) { this.aid = aid; @@ -44,6 +44,7 @@ public Page(int index, string aid, string cid, string epid, string title, int du this.cover = cover; } + [SetsRequiredMembers] public Page(int index, string aid, string cid, string epid, string title, int dur, string res, string cover, string desc) { this.aid = aid; @@ -57,6 +58,7 @@ public Page(int index, string aid, string cid, string epid, string title, int du this.desc = desc; } + [SetsRequiredMembers] public Page(int index, string aid, string cid, string epid, string title, int dur, string res, string cover, string desc, string ownerName, string ownerMid) { this.aid = aid; @@ -72,6 +74,7 @@ public Page(int index, string aid, string cid, string epid, string title, int du this.ownerMid = ownerMid; } + [SetsRequiredMembers] public Page(int index, Page page) { this.index = index; @@ -86,7 +89,7 @@ public Page(int index, Page page) this.ownerMid = page.ownerMid; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is Page page && aid == page.aid && @@ -102,24 +105,24 @@ public override int GetHashCode() public class ViewPoint { - public string title; - public int start; - public int end; + public required string title; + public required int start; + public required int end; } public class Video { - public string id; - public string dfn; - public string baseUrl; - public string res; - public string fps; - public string codecs; + public required string id; + public required string dfn; + public required string baseUrl; + public string? res; + public string? fps; + public required string codecs; public long bandwith; public int dur; public double size; - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is Video video && id == video.id && @@ -139,14 +142,14 @@ public override int GetHashCode() public class Audio { - public string id; - public string dfn; - public string baseUrl; - public string codecs; - public long bandwith; - public int dur; - - public override bool Equals(object obj) + public required string id; + public required string dfn; + public required string baseUrl; + public required string codecs; + public required long bandwith; + public required int dur; + + public override bool Equals(object? obj) { return obj is Audio audio && id == audio.id && @@ -164,16 +167,16 @@ public override int GetHashCode() public class Subtitle { - public string lan; - public string url; - public string path; + public required string lan; + public required string url; + public required string path; } public class Clip { - public int index; - public long from; - public long to; + public required int index; + public required long from; + public required long to; } } } diff --git a/BBDown.Core/Entity/VInfo.cs b/BBDown.Core/Entity/VInfo.cs index ff2108bf5..63602b779 100644 --- a/BBDown.Core/Entity/VInfo.cs +++ b/BBDown.Core/Entity/VInfo.cs @@ -1,58 +1,44 @@ -using System; -using System.Collections.Generic; -using System.Text; -using static BBDown.Core.Entity.Entity; +using static BBDown.Core.Entity.Entity; namespace BBDown.Core.Entity { public class VInfo { - /// - /// 视频index 用于番剧或课程判断当前选择的是第几集 - /// - private string index; - /// /// 视频标题 /// - private string title; + public required string Title { get; set; } /// /// 视频描述 /// - private string desc; + public required string Desc { get; set; } /// /// 视频封面 /// - private string pic; + public required string Pic { get; set; } /// /// 视频发布时间 /// - private string pubTime; - - private bool isBangumi; - private bool isCheese; + public required string PubTime { get; set; } + public bool IsBangumi { get; set; } + public bool IsCheese { get; set; } /// /// 番剧是否完结 /// - private bool isBangumiEnd; + public bool IsBangumiEnd { get; set; } /// - /// 视频分P信息 + /// 视频index 用于番剧或课程判断当前选择的是第几集 /// - private List pagesInfo; + public string? Index { get; set; } - public string Title { get => title; set => title = value; } - public string Desc { get => desc; set => desc = value; } - public string Pic { get => pic; set => pic = value; } - public string PubTime { get => pubTime; set => pubTime = value; } - public bool IsBangumi { get => isBangumi; set => isBangumi = value; } - public bool IsCheese { get => isCheese; set => isCheese = value; } - public bool IsBangumiEnd { get => isBangumiEnd; set => isBangumiEnd = value; } - public string Index { get => index; set => index = value; } - public List PagesInfo { get => pagesInfo; set => pagesInfo = value; } + /// + /// 视频分P信息 + /// + public required List PagesInfo { get; set; } } } diff --git a/BBDown.Core/Fetcher/BangumiInfoFetcher.cs b/BBDown.Core/Fetcher/BangumiInfoFetcher.cs index 386ada67f..d5b03d161 100644 --- a/BBDown.Core/Fetcher/BangumiInfoFetcher.cs +++ b/BBDown.Core/Fetcher/BangumiInfoFetcher.cs @@ -1,9 +1,5 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.Linq; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; using static BBDown.Core.Util.HTTPUtil; @@ -13,7 +9,7 @@ public class BangumiInfoFetcher : IFetcher { public async Task FetchAsync(string id) { - id = id.Substring(3); + id = id[3..]; string index = ""; string api = $"https://api.bilibili.com/pgc/view/web/season?ep_id={id}"; string json = await GetWebSourceAsync(api); @@ -24,14 +20,13 @@ public async Task FetchAsync(string id) string desc = result.GetProperty("evaluate").ToString(); string pubTime = result.GetProperty("publish").GetProperty("pub_time").ToString(); var pages = result.GetProperty("episodes").EnumerateArray().ToList(); - List pagesInfo = new List(); + List pagesInfo = new(); int i = 1; //episodes为空; 或者未包含对应epid,番外/花絮什么的 if (pages.Count == 0 || !result.GetProperty("episodes").ToString().Contains($"/ep{id}")) { - JsonElement sections; - if (result.TryGetProperty("section", out sections)) + if (result.TryGetProperty("section", out JsonElement sections)) { foreach (var section in sections.EnumerateArray()) { @@ -48,8 +43,7 @@ public async Task FetchAsync(string id) foreach (var page in pages) { //跳过预告 - JsonElement badge; - if (page.TryGetProperty("badge", out badge) && badge.ToString() == "预告") continue; + if (page.TryGetProperty("badge", out JsonElement badge) && badge.ToString() == "预告") continue; string res = ""; try { @@ -58,7 +52,7 @@ public async Task FetchAsync(string id) catch (Exception) { } string _title = page.GetProperty("title").ToString() + " " + page.GetProperty("long_title").ToString(); _title = _title.Trim(); - Page p = new Page(i++, + Page p = new(i++, page.GetProperty("aid").ToString(), page.GetProperty("cid").ToString(), page.GetProperty("id").ToString(), @@ -69,15 +63,17 @@ public async Task FetchAsync(string id) } - var info = new VInfo(); - info.Title = title.Trim(); - info.Desc = desc.Trim(); - info.Pic = cover; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = true; - info.IsCheese = true; - info.Index = index; + var info = new VInfo + { + Title = title.Trim(), + Desc = desc.Trim(), + Pic = cover, + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = true, + IsCheese = true, + Index = index + }; return info; } diff --git a/BBDown.Core/Fetcher/CheeseInfoFetcher.cs b/BBDown.Core/Fetcher/CheeseInfoFetcher.cs index ab21026f9..f3114f272 100644 --- a/BBDown.Core/Fetcher/CheeseInfoFetcher.cs +++ b/BBDown.Core/Fetcher/CheeseInfoFetcher.cs @@ -1,10 +1,5 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; using static BBDown.Core.Util.HTTPUtil; @@ -14,7 +9,7 @@ public class CheeseInfoFetcher : IFetcher { public async Task FetchAsync(string id) { - id = id.Substring(7); + id = id[7..]; string index = ""; string api = $"https://api.bilibili.com/pugv/view/web/season?ep_id={id}"; string json = await GetWebSourceAsync(api); @@ -26,10 +21,10 @@ public async Task FetchAsync(string id) string ownerName = data.GetProperty("up_info").GetProperty("uname").ToString(); string ownerMid = data.GetProperty("up_info").GetProperty("mid").ToString(); var pages = data.GetProperty("episodes").EnumerateArray().ToList(); - List pagesInfo = new List(); + List pagesInfo = new(); foreach (var page in pages) { - Page p = new Page(page.GetProperty("index").GetInt32(), + Page p = new(page.GetProperty("index").GetInt32(), page.GetProperty("aid").ToString(), page.GetProperty("cid").ToString(), page.GetProperty("id").ToString(), @@ -44,17 +39,19 @@ public async Task FetchAsync(string id) pagesInfo.Add(p); } string pubTime = pagesInfo.Count > 0 ? pages[0].GetProperty("release_date").ToString() : ""; - pubTime = pubTime != "" ? (new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString()) : ""; + pubTime = pubTime != "" ? new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString() : ""; - var info = new VInfo(); - info.Title = title.Trim(); - info.Desc = desc.Trim(); - info.Pic = cover; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = true; - info.IsCheese = true; - info.Index = index; + var info = new VInfo + { + Title = title.Trim(), + Desc = desc.Trim(), + Pic = cover, + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = true, + IsCheese = true, + Index = index + }; return info; } diff --git a/BBDown.Core/Fetcher/FavListFetcher.cs b/BBDown.Core/Fetcher/FavListFetcher.cs index 24077df7f..23dd67ebb 100644 --- a/BBDown.Core/Fetcher/FavListFetcher.cs +++ b/BBDown.Core/Fetcher/FavListFetcher.cs @@ -1,13 +1,6 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; -using static BBDown.Core.Logger; using static BBDown.Core.Util.HTTPUtil; @@ -22,7 +15,7 @@ public class FavListFetcher : IFetcher { public async Task FetchAsync(string id) { - id = id.Substring(6); + id = id[6..]; var favId = id.Split(':')[0]; var mid = id.Split(':')[1]; //查找默认收藏夹 @@ -34,7 +27,7 @@ public async Task FetchAsync(string id) int pageSize = 20; int index = 1; - List pagesInfo = new List(); + List pagesInfo = new(); var api = $"https://api.bilibili.com/x/v3/fav/resource/list?media_id={favId}&pn=1&ps={pageSize}&keyword=&order=mtime&type=0&tid=0&platform=web&jsonp=jsonp"; var json = await GetWebSourceAsync(api); @@ -42,8 +35,8 @@ public async Task FetchAsync(string id) var data = infoJson.RootElement.GetProperty("data"); int totalCount = data.GetProperty("info").GetProperty("media_count").GetInt32(); int totalPage = (int)Math.Ceiling((double)totalCount / pageSize); - var title = data.GetProperty("info").GetProperty("title").ToString(); - var intro = data.GetProperty("info").GetProperty("intro").GetString(); + var title = data.GetProperty("info").GetProperty("title").GetString()!; + var intro = data.GetProperty("info").GetProperty("intro").GetString()!; string pubTime = data.GetProperty("info").GetProperty("ctime").ToString(); pubTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString(); var userName = data.GetProperty("info").GetProperty("upper").GetProperty("name").ToString(); @@ -66,16 +59,18 @@ public async Task FetchAsync(string id) var tmpInfo = await new NormalInfoFetcher().FetchAsync(m.GetProperty("id").ToString()); foreach (var item in tmpInfo.PagesInfo) { - Page p = new Page(index++, item); - p.title = m.GetProperty("title").ToString() + $"_P{item.index}_{item.title}"; - p.cover = tmpInfo.Pic; - p.desc = m.GetProperty("intro").ToString(); + Page p = new(index++, item) + { + title = m.GetProperty("title").ToString() + $"_P{item.index}_{item.title}", + cover = tmpInfo.Pic, + desc = m.GetProperty("intro").ToString() + }; if (!pagesInfo.Contains(p)) pagesInfo.Add(p); } } else { - Page p = new Page(index++, + Page p = new(index++, m.GetProperty("id").ToString(), m.GetProperty("ugc").GetProperty("first_cid").ToString(), "", //epid @@ -90,13 +85,15 @@ public async Task FetchAsync(string id) } } - var info = new VInfo(); - info.Title = title.Trim(); - info.Desc = intro.Trim(); - info.Pic = ""; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = false; + var info = new VInfo + { + Title = title.Trim(), + Desc = intro.Trim(), + Pic = "", + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = false + }; return info; } diff --git a/BBDown.Core/Fetcher/IntlBangumiInfoFetcher.cs b/BBDown.Core/Fetcher/IntlBangumiInfoFetcher.cs index aece56e2d..102c80416 100644 --- a/BBDown.Core/Fetcher/IntlBangumiInfoFetcher.cs +++ b/BBDown.Core/Fetcher/IntlBangumiInfoFetcher.cs @@ -1,21 +1,16 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.Json; using System.Text.RegularExpressions; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; using static BBDown.Core.Util.HTTPUtil; namespace BBDown.Core.Fetcher { - public class IntlBangumiInfoFetcher : IFetcher + public partial class IntlBangumiInfoFetcher : IFetcher { public async Task FetchAsync(string id) { - id = id.Substring(3); + id = id[3..]; string index = ""; //string api = $"https://api.global.bilibili.com/intl/gateway/ogv/m/view?ep_id={id}&s_locale=ja_JP"; string api = $"https://api.bilibili.tv/intl/gateway/v2/ogv/view/app/season?ep_id={id}&platform=android&s_locale=zh_SG&mobi_app=bstar_a" + (Config.TOKEN != "" ? $"&access_key={Config.TOKEN}" : ""); @@ -34,7 +29,7 @@ public async Task FetchAsync(string id) var web = await GetWebSourceAsync(animeUrl); if (web != "") { - Regex regex = new Regex("window.__INITIAL_STATE__=([\\s\\S].*?);\\(function\\(\\)"); + Regex regex = StateRegex(); string _json = regex.Match(web).Groups[1].Value; using var _tempJson = JsonDocument.Parse(_json); cover = _tempJson.RootElement.GetProperty("mediaInfo").GetProperty("cover").ToString(); @@ -49,11 +44,10 @@ public async Task FetchAsync(string id) { pages = result.GetProperty("episodes").EnumerateArray().ToList(); } - List pagesInfo = new List(); + List pagesInfo = new(); int i = 1; - JsonElement modules; - if (result.TryGetProperty("modules", out modules)) + if (result.TryGetProperty("modules", out JsonElement modules)) { foreach (var section in modules.EnumerateArray()) { @@ -89,8 +83,7 @@ public async Task FetchAsync(string id) foreach (var page in pages) { //跳过预告 - JsonElement badge; - if (page.TryGetProperty("badge", out badge) && badge.ToString() == "预告") continue; + if (page.TryGetProperty("badge", out JsonElement badge) && badge.ToString() == "预告") continue; string res = ""; try { @@ -99,7 +92,7 @@ public async Task FetchAsync(string id) catch (Exception) { } string _title = page.GetProperty("title").ToString() + " " + page.GetProperty("long_title").ToString(); _title = _title.Trim(); - Page p = new Page(i++, + Page p = new(i++, page.GetProperty("aid").ToString(), page.GetProperty("cid").ToString(), page.GetProperty("id").ToString(), @@ -110,17 +103,22 @@ public async Task FetchAsync(string id) } - var info = new VInfo(); - info.Title = title.Trim(); - info.Desc = desc.Trim(); - info.Pic = cover; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = true; - info.IsCheese = true; - info.Index = index; + var info = new VInfo + { + Title = title.Trim(), + Desc = desc.Trim(), + Pic = cover, + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = true, + IsCheese = true, + Index = index + }; return info; } + + [RegexGenerator("window.__INITIAL_STATE__=([\\s\\S].*?);\\(function\\(\\)")] + private static partial Regex StateRegex(); } } diff --git a/BBDown.Core/Fetcher/MediaListFetcher.cs b/BBDown.Core/Fetcher/MediaListFetcher.cs index 6639beb60..6da3714f0 100644 --- a/BBDown.Core/Fetcher/MediaListFetcher.cs +++ b/BBDown.Core/Fetcher/MediaListFetcher.cs @@ -1,10 +1,5 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; using static BBDown.Core.Util.HTTPUtil; @@ -19,17 +14,17 @@ public class MediaListFetcher : IFetcher { public async Task FetchAsync(string id) { - id = id.Substring(10); + id = id[10..]; var api = $"https://api.bilibili.com/x/v1/medialist/info?type=8&biz_id={id}&tid=0"; var json = await GetWebSourceAsync(api); using var infoJson = JsonDocument.Parse(json); var data = infoJson.RootElement.GetProperty("data"); - var listTitle = data.GetProperty("title").GetString(); - var intro = data.GetProperty("intro").GetString(); - string pubTime = data.GetProperty("ctime").ToString(); + var listTitle = data.GetProperty("title").GetString()!; + var intro = data.GetProperty("intro").GetString()!; + string pubTime = data.GetProperty("ctime").ToString()!; pubTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString(); - List pagesInfo = new List(); + List pagesInfo = new(); bool hasMore = true; var oid = ""; int index = 1; @@ -43,16 +38,16 @@ public async Task FetchAsync(string id) foreach (var m in data.GetProperty("media_list").EnumerateArray()) { var pageCount = m.GetProperty("page").GetInt32(); - var desc = m.GetProperty("intro").GetString(); + var desc = m.GetProperty("intro").GetString()!; var ownerName = m.GetProperty("upper").GetProperty("name").ToString(); var ownerMid = m.GetProperty("upper").GetProperty("mid").ToString(); foreach (var page in m.GetProperty("pages").EnumerateArray()) { - Page p = new Page(index++, + Page p = new(index++, m.GetProperty("id").ToString(), page.GetProperty("id").ToString(), "", //epid - pageCount == 1 ? m.GetProperty("title").ToString() : $"{m.GetProperty("title").ToString()}_P{page.GetProperty("page").ToString()}_{page.GetProperty("title")}", //单P使用外层标题 多P则拼接内层子标题 + pageCount == 1 ? m.GetProperty("title").ToString() : $"{m.GetProperty("title")}_P{page.GetProperty("page")}_{page.GetProperty("title")}", //单P使用外层标题 多P则拼接内层子标题 page.GetProperty("duration").GetInt32(), page.GetProperty("dimension").GetProperty("width").ToString() + "x" + page.GetProperty("dimension").GetProperty("height").ToString(), m.GetProperty("cover").ToString(), @@ -66,13 +61,15 @@ public async Task FetchAsync(string id) } } - var info = new VInfo(); - info.Title = listTitle.Trim(); - info.Desc = intro.Trim(); - info.Pic = ""; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = false; + var info = new VInfo + { + Title = listTitle.Trim(), + Desc = intro.Trim(), + Pic = "", + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = false + }; return info; } diff --git a/BBDown.Core/Fetcher/NormalInfoFetcher.cs b/BBDown.Core/Fetcher/NormalInfoFetcher.cs index 14fc64cd2..353aaace2 100644 --- a/BBDown.Core/Fetcher/NormalInfoFetcher.cs +++ b/BBDown.Core/Fetcher/NormalInfoFetcher.cs @@ -1,17 +1,12 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.Json; using System.Text.RegularExpressions; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; using static BBDown.Core.Util.HTTPUtil; namespace BBDown.Core.Fetcher { - public class NormalInfoFetcher : IFetcher + public partial class NormalInfoFetcher : IFetcher { public async Task FetchAsync(string id) { @@ -30,10 +25,10 @@ public async Task FetchAsync(string id) bool bangumi = false; var pages = data.GetProperty("pages").EnumerateArray().ToList(); - List pagesInfo = new List(); + List pagesInfo = new(); foreach (var page in pages) { - Page p = new Page(page.GetProperty("page").GetInt32(), + Page p = new(page.GetProperty("page").GetInt32(), id, page.GetProperty("cid").ToString(), "", //epid @@ -53,7 +48,7 @@ public async Task FetchAsync(string id) if (data.GetProperty("redirect_url").ToString().Contains("bangumi")) { bangumi = true; - string epId = Regex.Match(data.GetProperty("redirect_url").ToString(), "ep(\\d+)").Groups[1].Value; + string epId = EpIdRegex().Match(data.GetProperty("redirect_url").ToString()).Groups[1].Value; //番剧内容通常不会有分P,如果有分P则不需要epId参数 if (pages.Count == 1) { @@ -63,15 +58,20 @@ public async Task FetchAsync(string id) } catch { } - var info = new VInfo(); - info.Title = title.Trim(); - info.Desc = desc.Trim(); - info.Pic = pic; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = bangumi; + var info = new VInfo + { + Title = title.Trim(), + Desc = desc.Trim(), + Pic = pic, + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = bangumi + }; return info; } + + [RegexGenerator("ep(\\d+)")] + private static partial Regex EpIdRegex(); } } diff --git a/BBDown.Core/Fetcher/SeriesListFetcher.cs b/BBDown.Core/Fetcher/SeriesListFetcher.cs index c3e97abfc..b1d61bf24 100644 --- a/BBDown.Core/Fetcher/SeriesListFetcher.cs +++ b/BBDown.Core/Fetcher/SeriesListFetcher.cs @@ -1,11 +1,5 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Entity.Entity; using static BBDown.Core.Util.HTTPUtil; @@ -21,17 +15,17 @@ public async Task FetchAsync(string id) { //套用BBDownMediaListFetcher.cs的代码 //只修改id = id.Substring(12);以及api地址的type=5 - id = id.Substring(12); + id = id[12..]; var api = $"https://api.bilibili.com/x/v1/medialist/info?type=5&biz_id={id}&tid=0"; var json = await GetWebSourceAsync(api); using var infoJson = JsonDocument.Parse(json); var data = infoJson.RootElement.GetProperty("data"); - var listTitle = data.GetProperty("title").GetString(); - var intro = data.GetProperty("intro").GetString(); + var listTitle = data.GetProperty("title").GetString()!; + var intro = data.GetProperty("intro").GetString()!; string pubTime = data.GetProperty("ctime").ToString(); pubTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString(); - List pagesInfo = new List(); + List pagesInfo = new(); bool hasMore = true; var oid = ""; int index = 1; @@ -45,16 +39,16 @@ public async Task FetchAsync(string id) foreach (var m in data.GetProperty("media_list").EnumerateArray()) { var pageCount = m.GetProperty("page").GetInt32(); - var desc = m.GetProperty("intro").GetString(); + var desc = m.GetProperty("intro").GetString()!; var ownerName = m.GetProperty("upper").GetProperty("name").ToString(); var ownerMid = m.GetProperty("upper").GetProperty("mid").ToString(); foreach (var page in m.GetProperty("pages").EnumerateArray()) { - Page p = new Page(index++, + Page p = new(index++, m.GetProperty("id").ToString(), page.GetProperty("id").ToString(), "", //epid - pageCount == 1 ? m.GetProperty("title").ToString() : $"{m.GetProperty("title").ToString()}_P{page.GetProperty("page").ToString()}_{page.GetProperty("title")}", //单P使用外层标题 多P则拼接内层子标题 + pageCount == 1 ? m.GetProperty("title").ToString() : $"{m.GetProperty("title")}_P{page.GetProperty("page")}_{page.GetProperty("title")}", //单P使用外层标题 多P则拼接内层子标题 page.GetProperty("duration").GetInt32(), page.GetProperty("dimension").GetProperty("width").ToString() + "x" + page.GetProperty("dimension").GetProperty("height").ToString(), m.GetProperty("cover").ToString(), @@ -68,13 +62,15 @@ public async Task FetchAsync(string id) } } - var info = new VInfo(); - info.Title = listTitle.Trim(); - info.Desc = intro.Trim(); - info.Pic = ""; - info.PubTime = pubTime; - info.PagesInfo = pagesInfo; - info.IsBangumi = false; + var info = new VInfo + { + Title = listTitle.Trim(), + Desc = intro.Trim(), + Pic = "", + PubTime = pubTime, + PagesInfo = pagesInfo, + IsBangumi = false + }; return info; } diff --git a/BBDown.Core/Fetcher/SpaceVideoFetcher.cs b/BBDown.Core/Fetcher/SpaceVideoFetcher.cs index 0f94435fa..622baa4fa 100644 --- a/BBDown.Core/Fetcher/SpaceVideoFetcher.cs +++ b/BBDown.Core/Fetcher/SpaceVideoFetcher.cs @@ -1,10 +1,5 @@ using BBDown.Core.Entity; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Util.HTTPUtil; using static BBDown.Core.Logger; @@ -14,10 +9,10 @@ public class SpaceVideoFetcher : IFetcher { public async Task FetchAsync(string id) { - id = id.Substring(4); + id = id[4..]; string userInfoApi = $"https://api.bilibili.com/x/space/acc/info?mid={id}&jsonp=jsonp"; string userName = GetValidFileName(JsonDocument.Parse(await GetWebSourceAsync(userInfoApi)).RootElement.GetProperty("data").GetProperty("name").ToString(), ".", true); - List urls = new List(); + List urls = new(); int pageSize = 50; int pageNumber = 1; string api = $"https://api.bilibili.com/x/space/arc/search?mid={id}&ps={pageSize}&tid=0&pn={pageNumber}&keyword=&order=pubdate&jsonp=jsonp"; @@ -45,9 +40,9 @@ public async Task FetchAsync(string id) throw new Exception("暂不支持该功能"); } - async Task> GetVideosByPageAsync(int pageNumber, int pageSize, string mid) + static async Task> GetVideosByPageAsync(int pageNumber, int pageSize, string mid) { - List urls = new List(); + List urls = new(); string api = $"https://api.bilibili.com/x/space/arc/search?mid={mid}&ps={pageSize}&tid=0&pn={pageNumber}&keyword=&order=pubdate&jsonp=jsonp"; string json = await GetWebSourceAsync(api); var infoJson = JsonDocument.Parse(json); diff --git a/BBDown.Core/IFetcher.cs b/BBDown.Core/IFetcher.cs index 5d8663f59..8fa406a3d 100644 --- a/BBDown.Core/IFetcher.cs +++ b/BBDown.Core/IFetcher.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace BBDown.Core +namespace BBDown.Core { public interface IFetcher { diff --git a/BBDown.Core/Logger.cs b/BBDown.Core/Logger.cs index b5ab21a83..1569b392c 100644 --- a/BBDown.Core/Logger.cs +++ b/BBDown.Core/Logger.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BBDown.Core +namespace BBDown.Core { public class Logger { diff --git a/BBDown.Core/Parser.cs b/BBDown.Core/Parser.cs index 5ad88337a..4ce7ff306 100644 --- a/BBDown.Core/Parser.cs +++ b/BBDown.Core/Parser.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Text; using System.Text.RegularExpressions; -using System.Linq; using System.Text.Json; -using System.Threading.Tasks; using static BBDown.Core.Logger; using static BBDown.Core.Util.HTTPUtil; using static BBDown.Core.Entity.Entity; @@ -12,7 +8,7 @@ namespace BBDown.Core { - public class Parser + public partial class Parser { private static async Task GetPlayJsonAsync(bool onlyAvc, string aidOri, string aid, string cid, string epId, bool tvApi, bool intl, bool appApi, string qn = "0") { @@ -27,8 +23,8 @@ private static async Task GetPlayJsonAsync(bool onlyAvc, string aidOri, if (appApi) return await AppHelper.DoReqAsync(aid, cid, epId, qn, bangumi, onlyAvc, Config.TOKEN); - string prefix = tvApi ? (bangumi ? "api.snm0516.aisee.tv/pgc/player/api/playurltv" : "api.snm0516.aisee.tv/x/tv/ugc/playurl") - : (bangumi ? "api.bilibili.com/pgc/player/web/playurl" : "api.bilibili.com/x/player/playurl"); + string prefix = tvApi ? bangumi ? "api.snm0516.aisee.tv/pgc/player/api/playurltv" : "api.snm0516.aisee.tv/x/tv/ugc/playurl" + : bangumi ? "api.bilibili.com/pgc/player/web/playurl" : "api.bilibili.com/x/player/playurl"; string api = $"https://{prefix}?avid={aid}&cid={cid}&qn={qn}&type=&otype=json" + (tvApi ? "" : "&fourk=1") + $"&fnver=0&fnval=4048" + (tvApi ? "&device=android&platform=android" + "&mobi_app=android_tv_yst&npcybs=0&force_host=2&build=102801" + @@ -57,7 +53,7 @@ private static async Task GetPlayJsonAsync(bool onlyAvc, string aidOri, Log("此视频需要大会员,您大概率需要登录一个有大会员的账号才可以下载,尝试从网页源码解析"); string webUrl = "https://www.bilibili.com/bangumi/play/ep" + epId; string webSource = await GetWebSourceAsync(webUrl); - webJson = Regex.Match(webSource, @"window.__playinfo__=([\s\S]*?)<\/script>").Groups[1].Value; + webJson = PlayerJsonRegex().Match(webSource).Groups[1].Value; } return webJson; } @@ -72,10 +68,10 @@ private static async Task GetPlayJsonAsync(string aid, string cid, strin public static async Task<(string, List