From b83e7a4fff787ab0f9b83ceb5ceb327364217406 Mon Sep 17 00:00:00 2001 From: tqk2811 Date: Sat, 18 Oct 2025 17:13:31 +0700 Subject: [PATCH 1/3] make MediaAnalysis public #589 --- FFMpegCore/FFProbe/MediaAnalysis.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FFMpegCore/FFProbe/MediaAnalysis.cs b/FFMpegCore/FFProbe/MediaAnalysis.cs index 4129e63..afac8fd 100644 --- a/FFMpegCore/FFProbe/MediaAnalysis.cs +++ b/FFMpegCore/FFProbe/MediaAnalysis.cs @@ -4,9 +4,9 @@ using FFMpegCore.Builders.MetaData; namespace FFMpegCore; -internal class MediaAnalysis : IMediaAnalysis +public class MediaAnalysis : IMediaAnalysis { - internal MediaAnalysis(FFProbeAnalysis analysis) + public MediaAnalysis(FFProbeAnalysis analysis) { Format = ParseFormat(analysis.Format); Chapters = analysis.Chapters.Select(c => ParseChapter(c)).ToList(); From 07bfc4617883812edab061805684015d07da036a Mon Sep 17 00:00:00 2001 From: tqk2811 Date: Sat, 18 Oct 2025 17:15:57 +0700 Subject: [PATCH 2/3] remove JsonIgnore from FFProbeAnalysis.ErrorData #589 --- FFMpegCore/FFProbe/FFProbeAnalysis.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFMpegCore/FFProbe/FFProbeAnalysis.cs b/FFMpegCore/FFProbe/FFProbeAnalysis.cs index 7176ce1..6bea6e7 100644 --- a/FFMpegCore/FFProbe/FFProbeAnalysis.cs +++ b/FFMpegCore/FFProbe/FFProbeAnalysis.cs @@ -11,7 +11,7 @@ public class FFProbeAnalysis [JsonPropertyName("chapters")] public List Chapters { get; set; } = null!; - [JsonIgnore] public IReadOnlyList ErrorData { get; set; } = new List(); + public IReadOnlyList ErrorData { get; set; } = new List(); } public class FFProbeStream : ITagsContainer, IDispositionContainer From 89d4235f7a0ffe5f3f81021b6ad59d7c1f8a9d1c Mon Sep 17 00:00:00 2001 From: tqk2811 Date: Sat, 18 Oct 2025 17:36:53 +0700 Subject: [PATCH 3/3] FFProbe: add GetAnalysis and GetAnalysisAsync #589 --- FFMpegCore/FFProbe/FFProbe.cs | 47 +++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/FFMpegCore/FFProbe/FFProbe.cs b/FFMpegCore/FFProbe/FFProbe.cs index e199376..8647685 100644 --- a/FFMpegCore/FFProbe/FFProbe.cs +++ b/FFMpegCore/FFProbe/FFProbe.cs @@ -12,6 +12,11 @@ namespace FFMpegCore; public static class FFProbe { public static IMediaAnalysis Analyse(string filePath, FFOptions? ffOptions = null, string? customArguments = null) + { + return new MediaAnalysis(GetAnalysis(filePath, ffOptions, customArguments)); + } + + public static FFProbeAnalysis GetAnalysis(string filePath, FFOptions? ffOptions = null, string? customArguments = null) { ThrowIfInputFileDoesNotExist(filePath); @@ -19,7 +24,7 @@ public static class FFProbe var result = processArguments.StartAndWaitForExit(); ThrowIfExitCodeNotZero(result); - return ParseOutput(result); + return DeserializeOutput(result); } public static FFProbeFrames GetFrames(string filePath, FFOptions? ffOptions = null, string? customArguments = null) @@ -45,15 +50,25 @@ public static class FFProbe } public static IMediaAnalysis Analyse(Uri uri, FFOptions? ffOptions = null, string? customArguments = null) + { + return new MediaAnalysis(GetAnalysis(uri, ffOptions, customArguments)); + } + + public static FFProbeAnalysis GetAnalysis(Uri uri, FFOptions? ffOptions = null, string? customArguments = null) { var instance = PrepareStreamAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current, customArguments); var result = instance.StartAndWaitForExit(); ThrowIfExitCodeNotZero(result); - return ParseOutput(result); + return DeserializeOutput(result); } public static IMediaAnalysis Analyse(Stream stream, FFOptions? ffOptions = null, string? customArguments = null) + { + return new MediaAnalysis(GetAnalysis(stream, ffOptions, customArguments)); + } + + public static FFProbeAnalysis GetAnalysis(Stream stream, FFOptions? ffOptions = null, string? customArguments = null) { var streamPipeSource = new StreamPipeSource(stream); var pipeArgument = new InputPipeArgument(streamPipeSource); @@ -74,11 +89,17 @@ public static class FFProbe var result = task.ConfigureAwait(false).GetAwaiter().GetResult(); ThrowIfExitCodeNotZero(result); - return ParseOutput(result); + return DeserializeOutput(result); } public static async Task AnalyseAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null) + { + return new MediaAnalysis(await GetAnalysisAsync(filePath, ffOptions, cancellationToken, customArguments)); + } + + public static async Task GetAnalysisAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, + string? customArguments = null) { ThrowIfInputFileDoesNotExist(filePath); @@ -86,7 +107,7 @@ public static class FFProbe var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false); ThrowIfExitCodeNotZero(result); - return ParseOutput(result); + return DeserializeOutput(result); } public static FFProbeFrames GetFrames(Uri uri, FFOptions? ffOptions = null, string? customArguments = null) @@ -120,16 +141,26 @@ public static class FFProbe public static async Task AnalyseAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null) + { + return new MediaAnalysis(await GetAnalysisAsync(uri, ffOptions, cancellationToken, customArguments)); + } + public static async Task GetAnalysisAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, + string? customArguments = null) { var instance = PrepareStreamAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current, customArguments); var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false); ThrowIfExitCodeNotZero(result); - return ParseOutput(result); + return DeserializeOutput(result); } public static async Task AnalyseAsync(Stream stream, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null) + { + return new MediaAnalysis(await GetAnalysisAsync(stream, ffOptions, cancellationToken, customArguments)); + } + public static async Task GetAnalysisAsync(Stream stream, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, + string? customArguments = null) { var streamPipeSource = new StreamPipeSource(stream); var pipeArgument = new InputPipeArgument(streamPipeSource); @@ -153,7 +184,7 @@ public static class FFProbe ThrowIfExitCodeNotZero(result); pipeArgument.Post(); - return ParseOutput(result); + return DeserializeOutput(result); } public static async Task GetFramesAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, @@ -164,7 +195,7 @@ public static class FFProbe return ParseFramesOutput(result); } - private static IMediaAnalysis ParseOutput(IProcessResult instance) + private static FFProbeAnalysis DeserializeOutput(IProcessResult instance) { var json = string.Join(string.Empty, instance.OutputData); var ffprobeAnalysis = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); @@ -175,7 +206,7 @@ public static class FFProbe } ffprobeAnalysis.ErrorData = instance.ErrorData; - return new MediaAnalysis(ffprobeAnalysis); + return ffprobeAnalysis; } private static FFProbeFrames ParseFramesOutput(IProcessResult instance)