mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-13 01:34:14 +01:00
76a977bcd6
Former-commit-id: f648a4b234
114 lines
4.7 KiB
C#
114 lines
4.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using FFMpegCore.Arguments;
|
|
using FFMpegCore.Exceptions;
|
|
using FFMpegCore.Helpers;
|
|
using FFMpegCore.Pipes;
|
|
using Instances;
|
|
|
|
namespace FFMpegCore
|
|
{
|
|
public static class FFProbe
|
|
{
|
|
public static IMediaAnalysis Analyse(string filePath, int outputCapacity = int.MaxValue)
|
|
{
|
|
if (!File.Exists(filePath))
|
|
throw new FFMpegException(FFMpegExceptionType.File, $"No file found at '{filePath}'");
|
|
|
|
using var instance = PrepareInstance(filePath, outputCapacity);
|
|
instance.BlockUntilFinished();
|
|
return ParseOutput(filePath, instance);
|
|
}
|
|
public static IMediaAnalysis Analyse(Uri uri, int outputCapacity = int.MaxValue)
|
|
{
|
|
using var instance = PrepareInstance(uri.AbsoluteUri, outputCapacity);
|
|
instance.BlockUntilFinished();
|
|
return ParseOutput(uri.AbsoluteUri, instance);
|
|
}
|
|
public static IMediaAnalysis Analyse(Stream stream, int outputCapacity = int.MaxValue)
|
|
{
|
|
var streamPipeSource = new StreamPipeSource(stream);
|
|
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
|
using var instance = PrepareInstance(pipeArgument.PipePath, outputCapacity);
|
|
pipeArgument.Pre();
|
|
|
|
var task = instance.FinishedRunning();
|
|
try
|
|
{
|
|
pipeArgument.During().ConfigureAwait(false).GetAwaiter().GetResult();
|
|
}
|
|
catch (IOException) { }
|
|
finally
|
|
{
|
|
pipeArgument.Post();
|
|
}
|
|
var exitCode = task.ConfigureAwait(false).GetAwaiter().GetResult();
|
|
if (exitCode != 0)
|
|
throw new FFMpegException(FFMpegExceptionType.Process, $"FFProbe process returned exit status {exitCode}", null, string.Join("\n", instance.ErrorData), string.Join("\n", instance.OutputData));
|
|
|
|
return ParseOutput(pipeArgument.PipePath, instance);
|
|
}
|
|
public static async Task<IMediaAnalysis> AnalyseAsync(string filePath, int outputCapacity = int.MaxValue)
|
|
{
|
|
if (!File.Exists(filePath))
|
|
throw new FFMpegException(FFMpegExceptionType.File, $"No file found at '{filePath}'");
|
|
|
|
using var instance = PrepareInstance(filePath, outputCapacity);
|
|
await instance.FinishedRunning();
|
|
return ParseOutput(filePath, instance);
|
|
}
|
|
public static async Task<IMediaAnalysis> AnalyseAsync(Uri uri, int outputCapacity = int.MaxValue)
|
|
{
|
|
using var instance = PrepareInstance(uri.AbsoluteUri, outputCapacity);
|
|
await instance.FinishedRunning();
|
|
return ParseOutput(uri.AbsoluteUri, instance);
|
|
}
|
|
public static async Task<IMediaAnalysis> AnalyseAsync(Stream stream, int outputCapacity = int.MaxValue)
|
|
{
|
|
var streamPipeSource = new StreamPipeSource(stream);
|
|
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
|
using var instance = PrepareInstance(pipeArgument.PipePath, outputCapacity);
|
|
pipeArgument.Pre();
|
|
|
|
var task = instance.FinishedRunning();
|
|
try
|
|
{
|
|
await pipeArgument.During();
|
|
}
|
|
catch(IOException)
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
pipeArgument.Post();
|
|
}
|
|
var exitCode = await task;
|
|
if (exitCode != 0)
|
|
throw new FFMpegException(FFMpegExceptionType.Process, $"FFProbe process returned exit status {exitCode}", null, string.Join("\n", instance.ErrorData), string.Join("\n", instance.OutputData));
|
|
|
|
pipeArgument.Post();
|
|
return ParseOutput(pipeArgument.PipePath, instance);
|
|
}
|
|
|
|
private static IMediaAnalysis ParseOutput(string filePath, Instance instance)
|
|
{
|
|
var json = string.Join(string.Empty, instance.OutputData);
|
|
var ffprobeAnalysis = JsonSerializer.Deserialize<FFProbeAnalysis>(json, new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
})!;
|
|
return new MediaAnalysis(filePath, ffprobeAnalysis);
|
|
}
|
|
|
|
private static Instance PrepareInstance(string filePath, int outputCapacity)
|
|
{
|
|
FFProbeHelper.RootExceptionCheck();
|
|
FFProbeHelper.VerifyFFProbeExists();
|
|
var arguments = $"-loglevel error -print_format json -show_format -sexagesimal -show_streams \"{filePath}\"";
|
|
var instance = new Instance(FFMpegOptions.Options.FFProbeBinary(), arguments) {DataBufferCapacity = outputCapacity};
|
|
return instance;
|
|
}
|
|
}
|
|
}
|