diff --git a/src/Ytdlp.NET/Parsing/RegexPatterns.cs b/src/Ytdlp.NET/Parsing/RegexPatterns.cs index 5692c81..72d4bf6 100644 --- a/src/Ytdlp.NET/Parsing/RegexPatterns.cs +++ b/src/Ytdlp.NET/Parsing/RegexPatterns.cs @@ -1,4 +1,6 @@ -namespace ManuHub.Ytdlp.NET; +using System.Text.Json.Serialization; + +namespace ManuHub.Ytdlp.NET; internal static class RegexPatterns { @@ -34,4 +36,4 @@ internal static class RegexPatterns // Generic fallback for any unknown post-processor public const string PostProcessorGeneric = @"\[(?Merger|ModifyChapters|SplitChapters|ExtractAudio|VideoRemuxer|VideoConvertor|Metadata|EmbedSubtitle|EmbedThumbnail|SubtitlesConvertor|ThumbnailsConvertor|FixupStretched|FixupM4a|FixupM3u8|FixupTimestamp|FixupDuration|MoveFiles|ffmpeg|ConvertSubs|SponsorBlock)\]\s*(?.+)"; -} \ No newline at end of file +} diff --git a/src/Ytdlp.NET/Parsing/YtdlpJsonContext.cs b/src/Ytdlp.NET/Parsing/YtdlpJsonContext.cs new file mode 100644 index 0000000..dda6fa4 --- /dev/null +++ b/src/Ytdlp.NET/Parsing/YtdlpJsonContext.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Serialization; + +namespace ManuHub.Ytdlp.NET; + +/// +/// Defines the source-generated JSON serialization context for . +/// +/// +/// This class enables high-performance, reflection-free JSON serialization/deserialization. +/// It is essential for: +/// +/// Reducing CPU overhead and memory allocations during metadata probing. +/// Supporting Native AOT compilation by providing compile-time type metadata. +/// +/// +[JsonSerializable(typeof(Metadata))] +public partial class YtdlpJsonContext : JsonSerializerContext { } \ No newline at end of file diff --git a/src/Ytdlp.NET/Ytdlp.Probe.cs b/src/Ytdlp.NET/Ytdlp.Probe.cs index fae0268..ae99361 100644 --- a/src/Ytdlp.NET/Ytdlp.Probe.cs +++ b/src/Ytdlp.NET/Ytdlp.Probe.cs @@ -15,7 +15,8 @@ public sealed partial class Ytdlp { PropertyNameCaseInsensitive = true, NumberHandling = JsonNumberHandling.AllowReadingFromString, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + TypeInfoResolver = YtdlpJsonContext.Default }; #endregion @@ -147,7 +148,7 @@ public async Task> GetAdobePassListAsync(CancellationToken ct = def try { - return JsonSerializer.Deserialize(json, JsonOptions); + return JsonSerializer.Deserialize(json, YtdlpJsonContext.Default.Metadata); } catch (Exception ex) { @@ -187,7 +188,7 @@ public async Task> GetAdobePassListAsync(CancellationToken ct = def try { - return JsonSerializer.Deserialize(json, JsonOptions); + return JsonSerializer.Deserialize(json, YtdlpJsonContext.Default.Metadata); } catch (Exception ex) { @@ -209,24 +210,6 @@ public async Task> GetAdobePassListAsync(CancellationToken ct = def public async Task GetDeepMetadataRawAsync(string url, CancellationToken ct = default, bool tuneProcess = true) => await GetMetadataInternalAsync(url, flat: false, ct, tuneProcess); - private async Task GetMetadataInternalAsync(string url, bool flat, CancellationToken ct, bool tuneProcess) - { - if (string.IsNullOrWhiteSpace(url)) - throw new ArgumentException("URL cannot be empty.", nameof(url)); - - var arguments = - "--dump-single-json " + - "--simulate " + - "--skip-download " + - (flat ? "--flat-playlist " : "") + - "--lazy-playlist " + - "--quiet " + - "--no-warnings " + - $"{Quote(url)}"; - - return await RunProbeAsync(arguments, ct, tuneProcess); - } - /// /// Retrieves a list of all available stream formats for a given URL. /// @@ -477,6 +460,25 @@ public async Task> GetSubtitlesAsync(string url, Cancellatio } } + + private async Task GetMetadataInternalAsync(string url, bool flat, CancellationToken ct, bool tuneProcess) + { + if (string.IsNullOrWhiteSpace(url)) + throw new ArgumentException("URL cannot be empty.", nameof(url)); + + var arguments = + "--dump-single-json " + + "--simulate " + + "--skip-download " + + (flat ? "--flat-playlist " : "") + + "--lazy-playlist " + + "--quiet " + + "--no-warnings " + + $"{Quote(url)}"; + + return await RunProbeAsync(arguments, ct, tuneProcess); + } + private List ParseFormats(string result) { var formats = new List();