mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
parent
5d8dfc8f7d
commit
364406fa2a
8 changed files with 48 additions and 125 deletions
|
@ -52,6 +52,7 @@ public void Probe_Success_FromStream_Async()
|
|||
using (var stream = File.OpenRead(VideoLibrary.LocalVideo.FullName))
|
||||
{
|
||||
var info = output.ParseVideoInfoAsync(stream).WaitForResult();
|
||||
|
||||
Assert.AreEqual(13, info.Duration.Seconds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,6 +219,13 @@ public void Convert(VideoType type, ArgumentContainer container)
|
|||
}
|
||||
}
|
||||
|
||||
public void ConvertFromPipe(VideoType type, ArgumentContainer container)
|
||||
{
|
||||
ConvertFromPipe(type, container, PixelFormat.Format24bppRgb);
|
||||
ConvertFromPipe(type, container, PixelFormat.Format32bppArgb);
|
||||
ConvertFromPipe(type, container, PixelFormat.Format48bppRgb);
|
||||
}
|
||||
|
||||
public void ConvertFromPipe(VideoType type, ArgumentContainer container, PixelFormat fmt)
|
||||
{
|
||||
var output = Input.OutputLocation(type);
|
||||
|
@ -287,7 +294,7 @@ public void Video_ToMP4_Args()
|
|||
public void Video_ToMP4_Args_Pipe()
|
||||
{
|
||||
var container = new ArgumentContainer { new VideoCodecArgument(VideoCodec.LibX264) };
|
||||
ConvertFromPipe(VideoType.Mp4, container, PixelFormat.Format24bppRgb);
|
||||
ConvertFromPipe(VideoType.Mp4, container);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -388,7 +395,7 @@ public void Video_ToTS_Args_Pipe()
|
|||
{
|
||||
new ForceFormatArgument(VideoCodec.MpegTs)
|
||||
};
|
||||
ConvertFromPipe(VideoType.Ts, container, PixelFormat.Format32bppArgb);
|
||||
ConvertFromPipe(VideoType.Ts, container);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -416,7 +423,7 @@ public void Video_ToOGV_Resize_Args_Pipe()
|
|||
new ScaleArgument(VideoSize.Ed),
|
||||
new VideoCodecArgument(VideoCodec.LibTheora)
|
||||
};
|
||||
ConvertFromPipe(VideoType.Ogv, container, PixelFormat.Format48bppRgb);
|
||||
ConvertFromPipe(VideoType.Ogv, container);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -441,12 +448,13 @@ public void Video_ToMP4_Resize_Args_Pipe()
|
|||
{
|
||||
var container = new ArgumentContainer
|
||||
{
|
||||
new ScaleArgument(VideoSize.Ld),
|
||||
new VideoCodecArgument(VideoCodec.LibX264)
|
||||
};
|
||||
ConvertFromPipe(VideoType.Mp4, container, PixelFormat.Format24bppRgb);
|
||||
ConvertFromPipe(VideoType.Mp4, container);
|
||||
}
|
||||
|
||||
[TestMethod, Timeout(30000)]
|
||||
[TestMethod]
|
||||
public void Video_ToOGV()
|
||||
{
|
||||
Convert(VideoType.Ogv);
|
||||
|
|
|
@ -30,8 +30,10 @@ public override string GetStringValue()
|
|||
|
||||
public override async Task ProcessDataAsync(CancellationToken token)
|
||||
{
|
||||
await Pipe.During(token).ConfigureAwait(false);
|
||||
await Writer.WriteDataAsync(Pipe.GetStream()).ConfigureAwait(false);
|
||||
await Pipe.WaitForConnectionAsync(token).ConfigureAwait(false);
|
||||
if (!Pipe.IsConnected)
|
||||
throw new TaskCanceledException();
|
||||
await Writer.WriteDataAsync(Pipe).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,10 @@ public override string GetStringValue()
|
|||
|
||||
public override async Task ProcessDataAsync(CancellationToken token)
|
||||
{
|
||||
await Pipe.During(token).ConfigureAwait(false);
|
||||
await Reader.ReadDataAsync(Pipe.GetStream()).ConfigureAwait(false);
|
||||
await Pipe.WaitForConnectionAsync(token).ConfigureAwait(false);
|
||||
if (!Pipe.IsConnected)
|
||||
throw new TaskCanceledException();
|
||||
await Reader.ReadDataAsync(Pipe).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,40 +2,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Pipes;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Mono.Unix;
|
||||
|
||||
namespace FFMpegCore.FFMPEG.Argument
|
||||
{
|
||||
public abstract class PipeArgument : Argument
|
||||
{
|
||||
public string PipePath => Pipe.PipePath;
|
||||
public string PipeName { get; private set; }
|
||||
public string PipePath => PipeHelpers.GetPipePath(PipeName);
|
||||
|
||||
protected INamedPipe Pipe { get; private set; }
|
||||
protected NamedPipeServerStream Pipe { get; private set; }
|
||||
private PipeDirection direction;
|
||||
|
||||
protected PipeArgument(PipeDirection direction)
|
||||
{
|
||||
var pipeName = "FFMpegCore_Pipe_" + Guid.NewGuid();
|
||||
Pipe = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) switch
|
||||
{
|
||||
true => new WindowsNamedPipe(pipeName),
|
||||
false => new UnixNamedPipe(pipeName)
|
||||
};
|
||||
PipeName = PipeHelpers.GetUnqiuePipeName();
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public void OpenPipe()
|
||||
{
|
||||
Pipe.Open(direction);
|
||||
if (Pipe != null)
|
||||
throw new InvalidOperationException("Pipe already has been opened");
|
||||
|
||||
Pipe = new NamedPipeServerStream(PipeName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||
}
|
||||
|
||||
public void ClosePipe()
|
||||
{
|
||||
Pipe.Close();
|
||||
Pipe?.Dispose();
|
||||
Pipe = null;
|
||||
}
|
||||
public Task ProcessDataAsync()
|
||||
{
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Instances;
|
||||
|
||||
namespace FFMpegCore.FFMPEG.Argument
|
||||
{
|
||||
|
||||
public interface INamedPipe
|
||||
{
|
||||
public void Open(PipeDirection direction);
|
||||
public Task During(CancellationToken cancellationToken);
|
||||
public void Close();
|
||||
System.IO.Stream GetStream();
|
||||
string PipePath { get; }
|
||||
}
|
||||
|
||||
public class WindowsNamedPipe : INamedPipe
|
||||
{
|
||||
private readonly string _pipeName;
|
||||
|
||||
public WindowsNamedPipe(string pipeName)
|
||||
{
|
||||
_pipeName = pipeName;
|
||||
}
|
||||
public void Open(PipeDirection direction)
|
||||
{
|
||||
if (Pipe != null)
|
||||
throw new InvalidOperationException("Pipe already has been opened");
|
||||
|
||||
Pipe = new NamedPipeServerStream(_pipeName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||
}
|
||||
|
||||
public async Task During(CancellationToken cancellationToken)
|
||||
{
|
||||
await Pipe.WaitForConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (!Pipe.IsConnected)
|
||||
throw new TaskCanceledException();
|
||||
}
|
||||
|
||||
public System.IO.Stream GetStream()
|
||||
{
|
||||
return Pipe;
|
||||
}
|
||||
|
||||
public NamedPipeServerStream Pipe { get; set; }
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Pipe?.Dispose();
|
||||
Pipe = null;
|
||||
}
|
||||
public string PipePath => $@"\\.\pipe\{_pipeName}";
|
||||
}
|
||||
public class UnixNamedPipe : INamedPipe
|
||||
{
|
||||
private readonly string _pipeName;
|
||||
private PipeDirection _direction;
|
||||
|
||||
public UnixNamedPipe(string pipeName)
|
||||
{
|
||||
_pipeName = pipeName;
|
||||
}
|
||||
|
||||
public void Open(PipeDirection direction)
|
||||
{
|
||||
if (direction == PipeDirection.InOut)
|
||||
throw new NotImplementedException();
|
||||
_direction = direction;
|
||||
|
||||
if (File.Exists(PipePath))
|
||||
throw new IOException($"Pipe name is already in use ({PipePath})");
|
||||
|
||||
var (exitCode, _) = Instance.Finish("mkfifo", PipePath);
|
||||
if (exitCode != 0)
|
||||
throw new IOException($"Could not create FIFO file. (mkfifo failed with argument '{PipePath}')");
|
||||
}
|
||||
public Task During(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (File.Exists(PipePath))
|
||||
File.Delete(PipePath);
|
||||
}
|
||||
|
||||
public System.IO.Stream GetStream()
|
||||
{
|
||||
return _direction switch
|
||||
{
|
||||
PipeDirection.In => File.OpenRead(PipePath),
|
||||
PipeDirection.Out => File.OpenWrite(PipePath),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
public string PipePath => $"/tmp/CoreFxPipe_FIFO_{_pipeName}";
|
||||
}
|
||||
}
|
16
FFMpegCore/FFMPEG/Pipes/PipeHelpers.cs
Normal file
16
FFMpegCore/FFMPEG/Pipes/PipeHelpers.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FFMpegCore.FFMPEG.Pipes
|
||||
{
|
||||
static class PipeHelpers
|
||||
{
|
||||
public static string GetUnqiuePipeName() => "FFMpegCore_Pipe_" + Guid.NewGuid();
|
||||
|
||||
public static string GetPipePath(string pipeName)
|
||||
{
|
||||
return $@"\\.\pipe\{pipeName}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ Thanks to max619 and WeihanLi
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Instances" Version="1.5.0" />
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.5.1" />
|
||||
</ItemGroup>
|
||||
|
|
Loading…
Reference in a new issue