diff --git a/FFMpegCore.Test/FFProbeTests.cs b/FFMpegCore.Test/FFProbeTests.cs index c931e9d..5e877ff 100644 --- a/FFMpegCore.Test/FFProbeTests.cs +++ b/FFMpegCore.Test/FFProbeTests.cs @@ -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); } } diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index 53024ed..0f4fc7f 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -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); diff --git a/FFMpegCore/FFMPEG/Argument/Atoms/InputPipeArgument.cs b/FFMpegCore/FFMPEG/Argument/Atoms/InputPipeArgument.cs index 4bd2357..6197a23 100644 --- a/FFMpegCore/FFMPEG/Argument/Atoms/InputPipeArgument.cs +++ b/FFMpegCore/FFMPEG/Argument/Atoms/InputPipeArgument.cs @@ -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); } } } diff --git a/FFMpegCore/FFMPEG/Argument/Atoms/OutputPipeArgument.cs b/FFMpegCore/FFMPEG/Argument/Atoms/OutputPipeArgument.cs index 389e204..fd02df2 100644 --- a/FFMpegCore/FFMPEG/Argument/Atoms/OutputPipeArgument.cs +++ b/FFMpegCore/FFMPEG/Argument/Atoms/OutputPipeArgument.cs @@ -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); } } } diff --git a/FFMpegCore/FFMPEG/Argument/Atoms/PipeArgument.cs b/FFMpegCore/FFMPEG/Argument/Atoms/PipeArgument.cs index 3ca3efe..81fb872 100644 --- a/FFMpegCore/FFMPEG/Argument/Atoms/PipeArgument.cs +++ b/FFMpegCore/FFMPEG/Argument/Atoms/PipeArgument.cs @@ -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() { diff --git a/FFMpegCore/FFMPEG/Argument/Atoms/UnixNamedPipe.cs b/FFMpegCore/FFMPEG/Argument/Atoms/UnixNamedPipe.cs deleted file mode 100644 index d862b26..0000000 --- a/FFMpegCore/FFMPEG/Argument/Atoms/UnixNamedPipe.cs +++ /dev/null @@ -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}"; - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMPEG/Pipes/PipeHelpers.cs b/FFMpegCore/FFMPEG/Pipes/PipeHelpers.cs new file mode 100644 index 0000000..6717dac --- /dev/null +++ b/FFMpegCore/FFMPEG/Pipes/PipeHelpers.cs @@ -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}"; + } + } +} diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index 7308d0e..f400dc0 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -32,7 +32,6 @@ Thanks to max619 and WeihanLi -