mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
Added ffprobe stream input
This commit is contained in:
parent
5af9aeb926
commit
cfda0fc9ae
5 changed files with 106 additions and 8 deletions
|
@ -31,5 +31,30 @@ public void Probe_Success()
|
|||
|
||||
Assert.AreEqual(13, info.Duration.Seconds);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Probe_Success_FromStream()
|
||||
{
|
||||
var output = new FFProbe();
|
||||
|
||||
using (var stream = File.OpenRead(VideoLibrary.LocalVideo.FullName))
|
||||
{
|
||||
var info = output.ParseVideoInfo(stream);
|
||||
Assert.AreEqual(13, info.Duration.Seconds);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Probe_Success_FromStream_Async()
|
||||
{
|
||||
var output = new FFProbe();
|
||||
|
||||
using (var stream = File.OpenRead(VideoLibrary.LocalVideo.FullName))
|
||||
{
|
||||
var info = output.ParseVideoInfoAsync(stream).WaitForResult();
|
||||
|
||||
Assert.AreEqual(13, info.Duration.Seconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
FFMpegCore.Test/TasksExtensions.cs
Normal file
16
FFMpegCore.Test/TasksExtensions.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFMpegCore.Test
|
||||
{
|
||||
static class TasksExtensions
|
||||
{
|
||||
public static T WaitForResult<T>(this Task<T> task)
|
||||
{
|
||||
task.Wait();
|
||||
return task.Result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ namespace FFMpegCore.FFMPEG.Argument
|
|||
public class InputPipeArgument : Argument
|
||||
{
|
||||
public string PipeName { get; private set; }
|
||||
public string PipePath => $@"\\.\pipe\{PipeName}";
|
||||
public IPipeSource Source { get; private set; }
|
||||
|
||||
private NamedPipeServerStream pipe;
|
||||
|
@ -42,7 +43,7 @@ public void ClosePipe()
|
|||
|
||||
public override string GetStringValue()
|
||||
{
|
||||
return $"-y {Source.GetFormat()} -i \\\\.\\pipe\\{PipeName}";
|
||||
return $"-y {Source.GetFormat()} -i {PipePath}";
|
||||
}
|
||||
|
||||
public void FlushPipe()
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Instances;
|
||||
using FFMpegCore.FFMPEG.Argument;
|
||||
using FFMpegCore.FFMPEG.Pipes;
|
||||
|
||||
namespace FFMpegCore.FFMPEG
|
||||
{
|
||||
|
@ -65,6 +67,56 @@ public async Task<VideoInfo> ParseVideoInfoAsync(VideoInfo info)
|
|||
return ParseVideoInfoInternal(info, output);
|
||||
}
|
||||
|
||||
public VideoInfo ParseVideoInfo(System.IO.Stream stream)
|
||||
{
|
||||
var info = new VideoInfo();
|
||||
var streamPipeSource = new StreamPipeSource(stream);
|
||||
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
||||
|
||||
var instance = new Instance(_ffprobePath, BuildFFProbeArguments(pipeArgument.PipePath)) { DataBufferCapacity = _outputCapacity };
|
||||
pipeArgument.OpenPipe();
|
||||
|
||||
try
|
||||
{
|
||||
var task = instance.FinishedRunning();
|
||||
pipeArgument.FlushPipe();
|
||||
pipeArgument.ClosePipe();
|
||||
task.Wait();
|
||||
}
|
||||
finally
|
||||
{
|
||||
pipeArgument.ClosePipe();
|
||||
}
|
||||
|
||||
var output = string.Join("", instance.OutputData);
|
||||
return ParseVideoInfoInternal(info, output);
|
||||
}
|
||||
|
||||
public async Task<VideoInfo> ParseVideoInfoAsync(System.IO.Stream stream)
|
||||
{
|
||||
var info = new VideoInfo();
|
||||
var streamPipeSource = new StreamPipeSource(stream);
|
||||
var pipeArgument = new InputPipeArgument(streamPipeSource);
|
||||
|
||||
var instance = new Instance(_ffprobePath, BuildFFProbeArguments(pipeArgument.PipePath)) { DataBufferCapacity = _outputCapacity };
|
||||
pipeArgument.OpenPipe();
|
||||
|
||||
try
|
||||
{
|
||||
var task = instance.FinishedRunning();
|
||||
await pipeArgument.FlushPipeAsync();
|
||||
pipeArgument.ClosePipe();
|
||||
await task;
|
||||
}
|
||||
finally
|
||||
{
|
||||
pipeArgument.ClosePipe();
|
||||
}
|
||||
|
||||
var output = string.Join("", instance.OutputData);
|
||||
return ParseVideoInfoInternal(info, output);
|
||||
}
|
||||
|
||||
private static string BuildFFProbeArguments(string fullPath) =>
|
||||
$"-v quiet -print_format json -show_streams \"{fullPath}\"";
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ public class VideoInfo
|
|||
{
|
||||
private FileInfo _file;
|
||||
|
||||
internal VideoInfo()
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Create a video information object from a file information object.
|
||||
/// </summary>
|
||||
|
@ -76,37 +80,37 @@ public VideoInfo(string path, int outputCapacity = int.MaxValue) : this(new File
|
|||
/// <summary>
|
||||
/// Gets the name of the file.
|
||||
/// </summary>
|
||||
public string Name => _file.Name;
|
||||
public string Name => _file != null ? _file.Name : throw new FileNotFoundException();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path of the file.
|
||||
/// </summary>
|
||||
public string FullName => _file.FullName;
|
||||
public string FullName => _file != null ? _file.FullName : throw new FileNotFoundException();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file extension.
|
||||
/// </summary>
|
||||
public string Extension => _file.Extension;
|
||||
public string Extension => _file != null ? _file.Extension : throw new FileNotFoundException();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating if the file is read-only.
|
||||
/// </summary>
|
||||
public bool IsReadOnly => _file.IsReadOnly;
|
||||
public bool IsReadOnly => _file != null ? _file.IsReadOnly : throw new FileNotFoundException();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating if the file exists (no cache, per call verification).
|
||||
/// </summary>
|
||||
public bool Exists => File.Exists(FullName);
|
||||
public bool Exists => _file != null ? File.Exists(FullName) : false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation date.
|
||||
/// </summary>
|
||||
public DateTime CreationTime => _file.CreationTime;
|
||||
public DateTime CreationTime => _file != null ? _file.CreationTime : throw new FileNotFoundException();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent directory information.
|
||||
/// </summary>
|
||||
public DirectoryInfo Directory => _file.Directory;
|
||||
public DirectoryInfo Directory => _file != null ? _file.Directory : throw new FileNotFoundException();
|
||||
|
||||
/// <summary>
|
||||
/// Create a video information object from a file information object.
|
||||
|
|
Loading…
Reference in a new issue