Adds overloads to FFProbe.GetFrames methods that take streams

This commit is contained in:
Emem Adegbola 2025-12-19 10:52:09 +00:00
parent cc75e03ec9
commit c9d7b663ae
2 changed files with 56 additions and 0 deletions

View file

@ -30,6 +30,19 @@ public class FFProbeTests
Assert.IsTrue(frameAnalysis.Frames.All(f => f.MediaType == "video")); Assert.IsTrue(frameAnalysis.Frames.All(f => f.MediaType == "video"));
} }
[TestMethod]
public void FrameAnalysis_FromStream_Sync()
{
using var stream = File.OpenRead(TestResources.WebmVideo);
var frameAnalysis = FFProbe.GetFrames(stream);
Assert.HasCount(90, frameAnalysis.Frames);
Assert.IsTrue(frameAnalysis.Frames.All(f => f.PixelFormat == "yuv420p"));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.Height == 360));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.Width == 640));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.MediaType == "video"));
}
[TestMethod] [TestMethod]
public async Task FrameAnalysis_Async() public async Task FrameAnalysis_Async()
{ {
@ -42,6 +55,19 @@ public class FFProbeTests
Assert.IsTrue(frameAnalysis.Frames.All(f => f.MediaType == "video")); Assert.IsTrue(frameAnalysis.Frames.All(f => f.MediaType == "video"));
} }
[TestMethod]
public async Task FrameAnalysis_FromStream_Async()
{
using var stream = File.OpenRead(TestResources.WebmVideo);
var frameAnalysis = await FFProbe.GetFramesAsync(stream, cancellationToken: TestContext.CancellationToken);
Assert.HasCount(90, frameAnalysis.Frames);
Assert.IsTrue(frameAnalysis.Frames.All(f => f.PixelFormat == "yuv420p"));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.Height == 360));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.Width == 640));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.MediaType == "video"));
}
[TestMethod] [TestMethod]
public async Task PacketAnalysis_Async() public async Task PacketAnalysis_Async()
{ {

View file

@ -22,6 +22,11 @@ public static class FFProbe
return ParseOutput(result); return ParseOutput(result);
} }
public static FFProbeFrames GetFrames(Stream stream, FFOptions? ffOptions = null, string? customArguments = null)
{
return GetFramesAsync(stream, ffOptions, CancellationToken.None, customArguments).ConfigureAwait(false).GetAwaiter().GetResult();
}
public static FFProbeFrames GetFrames(string filePath, FFOptions? ffOptions = null, string? customArguments = null) public static FFProbeFrames GetFrames(string filePath, FFOptions? ffOptions = null, string? customArguments = null)
{ {
ThrowIfInputFileDoesNotExist(filePath); ThrowIfInputFileDoesNotExist(filePath);
@ -167,6 +172,31 @@ public static class FFProbe
return ParseFramesOutput(result); return ParseFramesOutput(result);
} }
public static async Task<FFProbeFrames> GetFramesAsync(Stream stream, FFOptions? ffOptions = null, CancellationToken cancellationToken = default,
string? customArguments = null)
{
var streamPipeSource = new StreamPipeSource(stream);
var pipeArgument = new InputPipeArgument(streamPipeSource);
var instance = PrepareFrameAnalysisInstance(pipeArgument.PipePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
pipeArgument.Pre();
var task = instance.Start().WaitForExitAsync(cancellationToken);
try
{
await pipeArgument.During(cancellationToken).ConfigureAwait(false);
}
catch (IOException) { }
finally
{
pipeArgument.Post();
}
var result = task.ConfigureAwait(false).GetAwaiter().GetResult();
ThrowIfExitCodeNotZero(result);
return ParseFramesOutput(result);
}
private static IMediaAnalysis ParseOutput(IProcessResult instance) private static IMediaAnalysis ParseOutput(IProcessResult instance)
{ {
var json = string.Join(string.Empty, instance.OutputData); var json = string.Join(string.Empty, instance.OutputData);