mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 00:24:14 +01:00
Merge pull request #431 from vfrz/feature/custom-ffprob-arguments
Feature: custom ffprob arguments
This commit is contained in:
commit
ed2b95038c
2 changed files with 39 additions and 32 deletions
|
@ -236,5 +236,12 @@ public async Task Probe_Success_32BitWavBitDepth_Async()
|
||||||
Assert.IsNotNull(info.PrimaryAudioStream);
|
Assert.IsNotNull(info.PrimaryAudioStream);
|
||||||
Assert.AreEqual(32, info.PrimaryAudioStream.BitDepth);
|
Assert.AreEqual(32, info.PrimaryAudioStream.BitDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Probe_Success_Custom_Arguments()
|
||||||
|
{
|
||||||
|
var info = FFProbe.Analyse(TestResources.Mp4Video, customArguments: "-headers \"Hello: World\"");
|
||||||
|
Assert.AreEqual(3, info.Duration.Seconds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,52 +10,52 @@ namespace FFMpegCore
|
||||||
{
|
{
|
||||||
public static class FFProbe
|
public static class FFProbe
|
||||||
{
|
{
|
||||||
public static IMediaAnalysis Analyse(string filePath, FFOptions? ffOptions = null)
|
public static IMediaAnalysis Analyse(string filePath, FFOptions? ffOptions = null, string? customArguments = null)
|
||||||
{
|
{
|
||||||
ThrowIfInputFileDoesNotExist(filePath);
|
ThrowIfInputFileDoesNotExist(filePath);
|
||||||
|
|
||||||
var processArguments = PrepareStreamAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current);
|
var processArguments = PrepareStreamAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = processArguments.StartAndWaitForExit();
|
var result = processArguments.StartAndWaitForExit();
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParseOutput(result);
|
return ParseOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FFProbeFrames GetFrames(string filePath, FFOptions? ffOptions = null)
|
public static FFProbeFrames GetFrames(string filePath, FFOptions? ffOptions = null, string? customArguments = null)
|
||||||
{
|
{
|
||||||
ThrowIfInputFileDoesNotExist(filePath);
|
ThrowIfInputFileDoesNotExist(filePath);
|
||||||
|
|
||||||
var instance = PrepareFrameAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareFrameAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = instance.StartAndWaitForExit();
|
var result = instance.StartAndWaitForExit();
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParseFramesOutput(result);
|
return ParseFramesOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FFProbePackets GetPackets(string filePath, FFOptions? ffOptions = null)
|
public static FFProbePackets GetPackets(string filePath, FFOptions? ffOptions = null, string? customArguments = null)
|
||||||
{
|
{
|
||||||
ThrowIfInputFileDoesNotExist(filePath);
|
ThrowIfInputFileDoesNotExist(filePath);
|
||||||
|
|
||||||
var instance = PreparePacketAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PreparePacketAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = instance.StartAndWaitForExit();
|
var result = instance.StartAndWaitForExit();
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParsePacketsOutput(result);
|
return ParsePacketsOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMediaAnalysis Analyse(Uri uri, FFOptions? ffOptions = null)
|
public static IMediaAnalysis Analyse(Uri uri, FFOptions? ffOptions = null, string? customArguments = null)
|
||||||
{
|
{
|
||||||
var instance = PrepareStreamAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareStreamAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = instance.StartAndWaitForExit();
|
var result = instance.StartAndWaitForExit();
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParseOutput(result);
|
return ParseOutput(result);
|
||||||
}
|
}
|
||||||
public static IMediaAnalysis Analyse(Stream stream, FFOptions? ffOptions = null)
|
public static IMediaAnalysis Analyse(Stream stream, FFOptions? ffOptions = null, string? customArguments = null)
|
||||||
{
|
{
|
||||||
var streamPipeSource = new StreamPipeSource(stream);
|
var streamPipeSource = new StreamPipeSource(stream);
|
||||||
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
||||||
var instance = PrepareStreamAnalysisInstance(pipeArgument.PipePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareStreamAnalysisInstance(pipeArgument.PipePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
pipeArgument.Pre();
|
pipeArgument.Pre();
|
||||||
|
|
||||||
var task = instance.StartAndWaitForExitAsync();
|
var task = instance.StartAndWaitForExitAsync();
|
||||||
|
@ -75,57 +75,57 @@ public static IMediaAnalysis Analyse(Stream stream, FFOptions? ffOptions = null)
|
||||||
return ParseOutput(result);
|
return ParseOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IMediaAnalysis> AnalyseAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default)
|
public static async Task<IMediaAnalysis> AnalyseAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null)
|
||||||
{
|
{
|
||||||
ThrowIfInputFileDoesNotExist(filePath);
|
ThrowIfInputFileDoesNotExist(filePath);
|
||||||
|
|
||||||
var instance = PrepareStreamAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareStreamAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParseOutput(result);
|
return ParseOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FFProbeFrames GetFrames(Uri uri, FFOptions? ffOptions = null)
|
public static FFProbeFrames GetFrames(Uri uri, FFOptions? ffOptions = null, string? customArguments = null)
|
||||||
{
|
{
|
||||||
var instance = PrepareFrameAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareFrameAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = instance.StartAndWaitForExit();
|
var result = instance.StartAndWaitForExit();
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParseFramesOutput(result);
|
return ParseFramesOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<FFProbeFrames> GetFramesAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default)
|
public static async Task<FFProbeFrames> GetFramesAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null)
|
||||||
{
|
{
|
||||||
ThrowIfInputFileDoesNotExist(filePath);
|
ThrowIfInputFileDoesNotExist(filePath);
|
||||||
|
|
||||||
var instance = PrepareFrameAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareFrameAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
return ParseFramesOutput(result);
|
return ParseFramesOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<FFProbePackets> GetPacketsAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default)
|
public static async Task<FFProbePackets> GetPacketsAsync(string filePath, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null)
|
||||||
{
|
{
|
||||||
ThrowIfInputFileDoesNotExist(filePath);
|
ThrowIfInputFileDoesNotExist(filePath);
|
||||||
|
|
||||||
var instance = PreparePacketAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PreparePacketAnalysisInstance(filePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
return ParsePacketsOutput(result);
|
return ParsePacketsOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IMediaAnalysis> AnalyseAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default)
|
public static async Task<IMediaAnalysis> AnalyseAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null)
|
||||||
{
|
{
|
||||||
var instance = PrepareStreamAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareStreamAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
ThrowIfExitCodeNotZero(result);
|
ThrowIfExitCodeNotZero(result);
|
||||||
|
|
||||||
return ParseOutput(result);
|
return ParseOutput(result);
|
||||||
}
|
}
|
||||||
public static async Task<IMediaAnalysis> AnalyseAsync(Stream stream, FFOptions? ffOptions = null, CancellationToken cancellationToken = default)
|
public static async Task<IMediaAnalysis> AnalyseAsync(Stream stream, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null)
|
||||||
{
|
{
|
||||||
var streamPipeSource = new StreamPipeSource(stream);
|
var streamPipeSource = new StreamPipeSource(stream);
|
||||||
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
||||||
var instance = PrepareStreamAnalysisInstance(pipeArgument.PipePath, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareStreamAnalysisInstance(pipeArgument.PipePath, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
pipeArgument.Pre();
|
pipeArgument.Pre();
|
||||||
|
|
||||||
var task = instance.StartAndWaitForExitAsync(cancellationToken);
|
var task = instance.StartAndWaitForExitAsync(cancellationToken);
|
||||||
|
@ -148,9 +148,9 @@ public static async Task<IMediaAnalysis> AnalyseAsync(Stream stream, FFOptions?
|
||||||
return ParseOutput(result);
|
return ParseOutput(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<FFProbeFrames> GetFramesAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default)
|
public static async Task<FFProbeFrames> GetFramesAsync(Uri uri, FFOptions? ffOptions = null, CancellationToken cancellationToken = default, string? customArguments = null)
|
||||||
{
|
{
|
||||||
var instance = PrepareFrameAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current);
|
var instance = PrepareFrameAnalysisInstance(uri.AbsoluteUri, ffOptions ?? GlobalFFOptions.Current, customArguments);
|
||||||
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
var result = await instance.StartAndWaitForExitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
return ParseFramesOutput(result);
|
return ParseFramesOutput(result);
|
||||||
}
|
}
|
||||||
|
@ -212,18 +212,18 @@ private static void ThrowIfExitCodeNotZero(IProcessResult result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ProcessArguments PrepareStreamAnalysisInstance(string filePath, FFOptions ffOptions)
|
private static ProcessArguments PrepareStreamAnalysisInstance(string filePath, FFOptions ffOptions, string? customArguments)
|
||||||
=> PrepareInstance($"-loglevel error -print_format json -show_format -sexagesimal -show_streams -show_chapters \"{filePath}\"", ffOptions);
|
=> PrepareInstance($"-loglevel error -print_format json -show_format -sexagesimal -show_streams -show_chapters \"{filePath}\"", ffOptions, customArguments);
|
||||||
private static ProcessArguments PrepareFrameAnalysisInstance(string filePath, FFOptions ffOptions)
|
private static ProcessArguments PrepareFrameAnalysisInstance(string filePath, FFOptions ffOptions, string? customArguments)
|
||||||
=> PrepareInstance($"-loglevel error -print_format json -show_frames -v quiet -sexagesimal \"{filePath}\"", ffOptions);
|
=> PrepareInstance($"-loglevel error -print_format json -show_frames -v quiet -sexagesimal \"{filePath}\"", ffOptions, customArguments);
|
||||||
private static ProcessArguments PreparePacketAnalysisInstance(string filePath, FFOptions ffOptions)
|
private static ProcessArguments PreparePacketAnalysisInstance(string filePath, FFOptions ffOptions, string? customArguments)
|
||||||
=> PrepareInstance($"-loglevel error -print_format json -show_packets -v quiet -sexagesimal \"{filePath}\"", ffOptions);
|
=> PrepareInstance($"-loglevel error -print_format json -show_packets -v quiet -sexagesimal \"{filePath}\"", ffOptions, customArguments);
|
||||||
|
|
||||||
private static ProcessArguments PrepareInstance(string arguments, FFOptions ffOptions)
|
private static ProcessArguments PrepareInstance(string arguments, FFOptions ffOptions, string? customArguments)
|
||||||
{
|
{
|
||||||
FFProbeHelper.RootExceptionCheck();
|
FFProbeHelper.RootExceptionCheck();
|
||||||
FFProbeHelper.VerifyFFProbeExists(ffOptions);
|
FFProbeHelper.VerifyFFProbeExists(ffOptions);
|
||||||
var startInfo = new ProcessStartInfo(GlobalFFOptions.GetFFProbeBinaryPath(ffOptions), arguments)
|
var startInfo = new ProcessStartInfo(GlobalFFOptions.GetFFProbeBinaryPath(ffOptions), $"{arguments} {customArguments}")
|
||||||
{
|
{
|
||||||
StandardOutputEncoding = ffOptions.Encoding,
|
StandardOutputEncoding = ffOptions.Encoding,
|
||||||
StandardErrorEncoding = ffOptions.Encoding,
|
StandardErrorEncoding = ffOptions.Encoding,
|
||||||
|
|
Loading…
Reference in a new issue