Added ffprobe stream input

This commit is contained in:
Максим Багрянцев 2020-04-28 15:21:48 +03:00
parent 5af9aeb926
commit cfda0fc9ae
5 changed files with 106 additions and 8 deletions

View file

@ -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);
}
}
}
}

View 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;
}
}
}

View file

@ -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()

View file

@ -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}\"";

View file

@ -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.