From e10657169ea002cee05e7cd3d809ec936d678cfb Mon Sep 17 00:00:00 2001 From: Julien Loir Date: Mon, 12 Apr 2021 13:48:55 +0200 Subject: [PATCH 1/9] Move `System.IO` in `using`s on some classes --- FFMpegCore/Extend/BitmapVideoFrameWrapper.cs | 9 +++++---- FFMpegCore/FFMpeg/Pipes/IPipeSink.cs | 5 +++-- FFMpegCore/FFMpeg/Pipes/IPipeSource.cs | 5 +++-- FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs | 7 ++++--- FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs | 3 ++- FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs | 2 +- FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs | 5 +++-- 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs index e2f0737..36790d4 100644 --- a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs +++ b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs @@ -1,10 +1,11 @@ -using System; +using FFMpegCore.Pipes; +using System; using System.Drawing; using System.Drawing.Imaging; +using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using FFMpegCore.Pipes; namespace FFMpegCore.Extend { @@ -24,7 +25,7 @@ public BitmapVideoFrameWrapper(Bitmap bitmap) Format = ConvertStreamFormat(bitmap.PixelFormat); } - public void Serialize(System.IO.Stream stream) + public void Serialize(Stream stream) { var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat); @@ -40,7 +41,7 @@ public void Serialize(System.IO.Stream stream) } } - public async Task SerializeAsync(System.IO.Stream stream, CancellationToken token) + public async Task SerializeAsync(Stream stream, CancellationToken token) { var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat); diff --git a/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs b/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs index 875407e..e5f2bf4 100644 --- a/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs +++ b/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs @@ -1,11 +1,12 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes { public interface IPipeSink { - Task ReadAsync(System.IO.Stream inputStream, CancellationToken cancellationToken); + Task ReadAsync(Stream inputStream, CancellationToken cancellationToken); string GetFormat(); } } diff --git a/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs index cdd5139..c250421 100644 --- a/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes @@ -9,6 +10,6 @@ namespace FFMpegCore.Pipes public interface IPipeSource { string GetStreamArguments(); - Task WriteAsync(System.IO.Stream outputStream, CancellationToken cancellationToken); + Task WriteAsync(Stream outputStream, CancellationToken cancellationToken); } } diff --git a/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs b/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs index 094040b..dd583d9 100644 --- a/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs +++ b/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes @@ -12,7 +13,7 @@ public interface IVideoFrame int Height { get; } string Format { get; } - void Serialize(System.IO.Stream pipe); - Task SerializeAsync(System.IO.Stream pipe, CancellationToken token); + void Serialize(Stream pipe); + Task SerializeAsync(Stream pipe, CancellationToken token); } } diff --git a/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs index 65f622e..0e3ab61 100644 --- a/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Threading; using System.Threading.Tasks; using FFMpegCore.Exceptions; @@ -46,7 +47,7 @@ public string GetStreamArguments() return $"-f rawvideo -r {FrameRate.ToString(CultureInfo.InvariantCulture)} -pix_fmt {StreamFormat} -s {Width}x{Height}"; } - public async Task WriteAsync(System.IO.Stream outputStream, CancellationToken cancellationToken) + public async Task WriteAsync(Stream outputStream, CancellationToken cancellationToken) { if (_framesEnumerator.Current != null) { diff --git a/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs b/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs index cd13f40..addc14e 100644 --- a/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs +++ b/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs @@ -20,7 +20,7 @@ public StreamPipeSink(Stream destination) Writer = (inputStream, cancellationToken) => inputStream.CopyToAsync(destination, BlockSize, cancellationToken); } - public Task ReadAsync(System.IO.Stream inputStream, CancellationToken cancellationToken) + public Task ReadAsync(Stream inputStream, CancellationToken cancellationToken) => Writer(inputStream, cancellationToken); public string GetFormat() => Format; diff --git a/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs index 404029f..87eaee7 100644 --- a/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes @@ -19,6 +20,6 @@ public StreamPipeSource(System.IO.Stream source) public string GetStreamArguments() => StreamFormat; - public Task WriteAsync(System.IO.Stream outputStream, CancellationToken cancellationToken) => Source.CopyToAsync(outputStream, BlockSize, cancellationToken); + public Task WriteAsync(Stream outputStream, CancellationToken cancellationToken) => Source.CopyToAsync(outputStream, BlockSize, cancellationToken); } } From 1711f98bd535609355dd7cae45e1edb389c784dd Mon Sep 17 00:00:00 2001 From: Julien Loir Date: Mon, 12 Apr 2021 13:49:36 +0200 Subject: [PATCH 2/9] Add support for `Format16bppRgb555` in Bitmap wrapper --- FFMpegCore/Extend/BitmapVideoFrameWrapper.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs index 36790d4..bc81643 100644 --- a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs +++ b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs @@ -68,6 +68,8 @@ private static string ConvertStreamFormat(PixelFormat fmt) { case PixelFormat.Format16bppGrayScale: return "gray16le"; + case PixelFormat.Format16bppRgb555: + return "bgr555le"; case PixelFormat.Format16bppRgb565: return "bgr565le"; case PixelFormat.Format24bppRgb: From d8810682efdfc63aa194d16f39211736cd3a514d Mon Sep 17 00:00:00 2001 From: Julien Loir Date: Mon, 12 Apr 2021 13:50:27 +0200 Subject: [PATCH 3/9] Add simple support for PCM audio source wrapping --- FFMpegCore/Extend/PcmAudioSampleWrapper.cs | 27 +++++++++++ FFMpegCore/FFMpeg/Pipes/IAudioSample.cs | 16 +++++++ FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs | 45 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 FFMpegCore/Extend/PcmAudioSampleWrapper.cs create mode 100644 FFMpegCore/FFMpeg/Pipes/IAudioSample.cs create mode 100644 FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs diff --git a/FFMpegCore/Extend/PcmAudioSampleWrapper.cs b/FFMpegCore/Extend/PcmAudioSampleWrapper.cs new file mode 100644 index 0000000..d67038b --- /dev/null +++ b/FFMpegCore/Extend/PcmAudioSampleWrapper.cs @@ -0,0 +1,27 @@ +using FFMpegCore.Pipes; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +public class PcmAudioSampleWrapper : IAudioSample +{ + //This could actually be short or int, but copies would be inefficient. + //Handling bytes lets the user decide on the conversion, and abstract the library + //from handling shorts, unsigned shorts, integers, unsigned integers and floats. + private readonly byte[] _sample; + + public PcmAudioSampleWrapper(byte[] sample) + { + _sample = sample; + } + + public void Serialize(Stream stream) + { + stream.Write(_sample, 0, _sample.Length); + } + + public async Task SerializeAsync(Stream stream, CancellationToken token) + { + await stream.WriteAsync(_sample, 0, _sample.Length, token); + } +} diff --git a/FFMpegCore/FFMpeg/Pipes/IAudioSample.cs b/FFMpegCore/FFMpeg/Pipes/IAudioSample.cs new file mode 100644 index 0000000..c7dea65 --- /dev/null +++ b/FFMpegCore/FFMpeg/Pipes/IAudioSample.cs @@ -0,0 +1,16 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace FFMpegCore.Pipes +{ + /// + /// Interface for Audio sample + /// + public interface IAudioSample + { + void Serialize(Stream stream); + + Task SerializeAsync(Stream stream, CancellationToken token); + } +} diff --git a/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs new file mode 100644 index 0000000..40b964c --- /dev/null +++ b/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace FFMpegCore.Pipes +{ + /// + /// Implementation of for a raw audio stream that is gathered from + /// + public class RawAudioPipeSource : IPipeSource + { + private readonly IEnumerator _sampleEnumerator; + + public string Format { get; set; } = "s16le"; + public uint SampleRate { get; set; } = 8000; + public uint Channels { get; set; } = 1; + + public RawAudioPipeSource(IEnumerator sampleEnumerator) + { + _sampleEnumerator = sampleEnumerator; + } + + public RawAudioPipeSource(IEnumerable sampleEnumerator) + : this(sampleEnumerator.GetEnumerator()) { } + + public string GetStreamArguments() + { + return $"-f {Format} -ar {SampleRate} -ac {Channels}"; + } + + public async Task WriteAsync(Stream outputStream, CancellationToken cancellationToken) + { + if (_sampleEnumerator.Current != null) + { + await _sampleEnumerator.Current.SerializeAsync(outputStream, cancellationToken).ConfigureAwait(false); + } + + while (_sampleEnumerator.MoveNext()) + { + await _sampleEnumerator.Current!.SerializeAsync(outputStream, cancellationToken).ConfigureAwait(false); + } + } + } +} From 6c3129d41779f3ffb5f512d5108ae9fac8ca83fe Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 15 May 2021 11:17:12 +0200 Subject: [PATCH 4/9] Cleanup in using directives --- FFMpegCore.Test/AudioTest.cs | 1 - FFMpegCore.Test/Resources/TestResources.cs | 6 +----- FFMpegCore/Extend/BitmapVideoFrameWrapper.cs | 5 +++-- FFMpegCore/FFMpeg/Arguments/SetMirroringArgument.cs | 2 -- FFMpegCore/FFMpeg/Arguments/SizeArgument.cs | 1 - FFMpegCore/FFMpeg/Pipes/IPipeSink.cs | 5 +++-- FFMpegCore/FFMpeg/Pipes/IPipeSource.cs | 5 +++-- FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs | 7 ++++--- FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs | 3 ++- FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs | 2 +- FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs | 9 +++++---- 11 files changed, 22 insertions(+), 24 deletions(-) diff --git a/FFMpegCore.Test/AudioTest.cs b/FFMpegCore.Test/AudioTest.cs index bd53541..2f7e4e9 100644 --- a/FFMpegCore.Test/AudioTest.cs +++ b/FFMpegCore.Test/AudioTest.cs @@ -1,5 +1,4 @@ using System; -using FFMpegCore.Enums; using FFMpegCore.Test.Resources; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.IO; diff --git a/FFMpegCore.Test/Resources/TestResources.cs b/FFMpegCore.Test/Resources/TestResources.cs index f37ed0c..6277dd3 100644 --- a/FFMpegCore.Test/Resources/TestResources.cs +++ b/FFMpegCore.Test/Resources/TestResources.cs @@ -1,8 +1,4 @@ -using System; -using System.IO; -using FFMpegCore.Enums; - -namespace FFMpegCore.Test.Resources +namespace FFMpegCore.Test.Resources { public enum AudioType { diff --git a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs index e2f0737..b7f4c65 100644 --- a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs +++ b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; using System.Drawing.Imaging; +using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -24,7 +25,7 @@ public BitmapVideoFrameWrapper(Bitmap bitmap) Format = ConvertStreamFormat(bitmap.PixelFormat); } - public void Serialize(System.IO.Stream stream) + public void Serialize(Stream stream) { var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat); @@ -40,7 +41,7 @@ public void Serialize(System.IO.Stream stream) } } - public async Task SerializeAsync(System.IO.Stream stream, CancellationToken token) + public async Task SerializeAsync(Stream stream, CancellationToken token) { var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat); diff --git a/FFMpegCore/FFMpeg/Arguments/SetMirroringArgument.cs b/FFMpegCore/FFMpeg/Arguments/SetMirroringArgument.cs index f042f77..fff98f3 100644 --- a/FFMpegCore/FFMpeg/Arguments/SetMirroringArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/SetMirroringArgument.cs @@ -1,7 +1,5 @@ using FFMpegCore.Enums; using System; -using System.Collections.Generic; -using System.Text; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Arguments/SizeArgument.cs b/FFMpegCore/FFMpeg/Arguments/SizeArgument.cs index 04fe615..924c0a0 100644 --- a/FFMpegCore/FFMpeg/Arguments/SizeArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/SizeArgument.cs @@ -1,5 +1,4 @@ using System.Drawing; -using FFMpegCore.Enums; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs b/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs index 875407e..e5f2bf4 100644 --- a/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs +++ b/FFMpegCore/FFMpeg/Pipes/IPipeSink.cs @@ -1,11 +1,12 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes { public interface IPipeSink { - Task ReadAsync(System.IO.Stream inputStream, CancellationToken cancellationToken); + Task ReadAsync(Stream inputStream, CancellationToken cancellationToken); string GetFormat(); } } diff --git a/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs index cdd5139..c250421 100644 --- a/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/IPipeSource.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes @@ -9,6 +10,6 @@ namespace FFMpegCore.Pipes public interface IPipeSource { string GetStreamArguments(); - Task WriteAsync(System.IO.Stream outputStream, CancellationToken cancellationToken); + Task WriteAsync(Stream outputStream, CancellationToken cancellationToken); } } diff --git a/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs b/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs index 094040b..dd583d9 100644 --- a/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs +++ b/FFMpegCore/FFMpeg/Pipes/IVideoFrame.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes @@ -12,7 +13,7 @@ public interface IVideoFrame int Height { get; } string Format { get; } - void Serialize(System.IO.Stream pipe); - Task SerializeAsync(System.IO.Stream pipe, CancellationToken token); + void Serialize(Stream pipe); + Task SerializeAsync(Stream pipe, CancellationToken token); } } diff --git a/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs index 65f622e..0e3ab61 100644 --- a/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/RawVideoPipeSource.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Threading; using System.Threading.Tasks; using FFMpegCore.Exceptions; @@ -46,7 +47,7 @@ public string GetStreamArguments() return $"-f rawvideo -r {FrameRate.ToString(CultureInfo.InvariantCulture)} -pix_fmt {StreamFormat} -s {Width}x{Height}"; } - public async Task WriteAsync(System.IO.Stream outputStream, CancellationToken cancellationToken) + public async Task WriteAsync(Stream outputStream, CancellationToken cancellationToken) { if (_framesEnumerator.Current != null) { diff --git a/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs b/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs index cd13f40..addc14e 100644 --- a/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs +++ b/FFMpegCore/FFMpeg/Pipes/StreamPipeSink.cs @@ -20,7 +20,7 @@ public StreamPipeSink(Stream destination) Writer = (inputStream, cancellationToken) => inputStream.CopyToAsync(destination, BlockSize, cancellationToken); } - public Task ReadAsync(System.IO.Stream inputStream, CancellationToken cancellationToken) + public Task ReadAsync(Stream inputStream, CancellationToken cancellationToken) => Writer(inputStream, cancellationToken); public string GetFormat() => Format; diff --git a/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs index 404029f..99bc081 100644 --- a/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/StreamPipeSource.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace FFMpegCore.Pipes @@ -8,17 +9,17 @@ namespace FFMpegCore.Pipes /// public class StreamPipeSource : IPipeSource { - public System.IO.Stream Source { get; } + public Stream Source { get; } public int BlockSize { get; } = 4096; public string StreamFormat { get; } = string.Empty; - public StreamPipeSource(System.IO.Stream source) + public StreamPipeSource(Stream source) { Source = source; } public string GetStreamArguments() => StreamFormat; - public Task WriteAsync(System.IO.Stream outputStream, CancellationToken cancellationToken) => Source.CopyToAsync(outputStream, BlockSize, cancellationToken); + public Task WriteAsync(Stream outputStream, CancellationToken cancellationToken) => Source.CopyToAsync(outputStream, BlockSize, cancellationToken); } } From be32a14619c37cc3fa8b4538544e33ede295204f Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 15 May 2021 11:19:22 +0200 Subject: [PATCH 5/9] Reorder using directives --- FFMpegCore/Extend/BitmapVideoFrameWrapper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs index bc81643..678bdcb 100644 --- a/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs +++ b/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs @@ -1,11 +1,11 @@ -using FFMpegCore.Pipes; -using System; +using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using FFMpegCore.Pipes; namespace FFMpegCore.Extend { From 274bb9667ecf55b5bdcee3d65c9c5bf21959749f Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 15 May 2021 11:50:34 +0200 Subject: [PATCH 6/9] Update used GitHub Actions --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6fe6cb..6946920 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,12 +18,12 @@ jobs: timeout-minutes: 6 steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Prepare .NET uses: actions/setup-dotnet@v1 with: dotnet-version: '5.0.x' - name: Prepare FFMpeg - uses: FedericoCarboni/setup-ffmpeg@v1-beta + uses: FedericoCarboni/setup-ffmpeg@v1 - name: Test with dotnet run: dotnet test --logger GitHubActions diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f10b27..5ef0a4c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Prepare .NET uses: actions/setup-dotnet@v1 with: From acd462a5276eea2cf75cb3e6d7e209bd7157f1a8 Mon Sep 17 00:00:00 2001 From: Julien Loir Date: Tue, 25 May 2021 16:14:40 +0200 Subject: [PATCH 7/9] Add test for the new audio pipe --- FFMpegCore.Test/AudioTest.cs | 157 +++++++++++++++++- FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs | 3 +- 2 files changed, 157 insertions(+), 3 deletions(-) diff --git a/FFMpegCore.Test/AudioTest.cs b/FFMpegCore.Test/AudioTest.cs index 2f7e4e9..f1abb72 100644 --- a/FFMpegCore.Test/AudioTest.cs +++ b/FFMpegCore.Test/AudioTest.cs @@ -1,10 +1,13 @@ -using System; +using FFMpegCore.Enums; +using FFMpegCore.Exceptions; +using FFMpegCore.Pipes; using FFMpegCore.Test.Resources; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using FFMpegCore.Pipes; namespace FFMpegCore.Test { @@ -69,5 +72,155 @@ public void Image_AddAudio() Assert.IsTrue(analysis.Duration.TotalSeconds > 0); Assert.IsTrue(File.Exists(outputFile)); } + + [TestMethod, Timeout(10000)] + public void Audio_ToAAC_Args_Pipe() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var samples = new List + { + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + }; + + var audioSamplesSource = new RawAudioPipeSource(samples) + { + Channels = 2, + Format = "s8", + SampleRate = 8000, + }; + + var success = FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.Aac)) + .ProcessSynchronously(); + Assert.IsTrue(success); + } + + [TestMethod, Timeout(10000)] + public void Audio_ToLibVorbis_Args_Pipe() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var samples = new List + { + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + }; + + var audioSamplesSource = new RawAudioPipeSource(samples) + { + Channels = 2, + Format = "s8", + SampleRate = 8000, + }; + + var success = FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.LibVorbis)) + .ProcessSynchronously(); + Assert.IsTrue(success); + } + + [TestMethod, Timeout(10000)] + public async Task Audio_ToAAC_Args_Pipe_Async() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var samples = new List + { + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + }; + + var audioSamplesSource = new RawAudioPipeSource(samples) + { + Channels = 2, + Format = "s8", + SampleRate = 8000, + }; + + var success = await FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.Aac)) + .ProcessAsynchronously(); + Assert.IsTrue(success); + } + + [TestMethod, Timeout(10000)] + public void Audio_ToAAC_Args_Pipe_ValidDefaultConfiguration() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var samples = new List + { + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + new PcmAudioSampleWrapper(new byte[] { 0, 0 }), + }; + + var audioSamplesSource = new RawAudioPipeSource(samples); + + var success = FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.Aac)) + .ProcessSynchronously(); + Assert.IsTrue(success); + } + + [TestMethod, Timeout(10000)] + public void Audio_ToAAC_Args_Pipe_InvalidChannels() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var audioSamplesSource = new RawAudioPipeSource(new List()) + { + Channels = 0, + }; + + var ex = Assert.ThrowsException(() => FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.Aac)) + .ProcessSynchronously()); + } + + [TestMethod, Timeout(10000)] + public void Audio_ToAAC_Args_Pipe_InvalidFormat() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var audioSamplesSource = new RawAudioPipeSource(new List()) + { + Format = "s8le", + }; + + var ex = Assert.ThrowsException(() => FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.Aac)) + .ProcessSynchronously()); + } + + [TestMethod, Timeout(10000)] + public void Audio_ToAAC_Args_Pipe_InvalidSampleRate() + { + using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); + + var audioSamplesSource = new RawAudioPipeSource(new List()) + { + SampleRate = 0, + }; + + var ex = Assert.ThrowsException(() => FFMpegArguments + .FromPipeInput(audioSamplesSource) + .OutputToFile(outputFile, false, opt => opt + .WithAudioCodec(AudioCodec.Aac)) + .ProcessSynchronously()); + } } } \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs b/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs index 40b964c..8797694 100644 --- a/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs +++ b/FFMpegCore/FFMpeg/Pipes/RawAudioPipeSource.cs @@ -6,7 +6,8 @@ namespace FFMpegCore.Pipes { /// - /// Implementation of for a raw audio stream that is gathered from + /// Implementation of for a raw audio stream that is gathered from . + /// It is the user's responbility to make sure the enumerated samples match the configuration provided to this pipe. /// public class RawAudioPipeSource : IPipeSource { From 366a1cd6c018604bd2b2dd24dcd942aefb171051 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Tue, 8 Jun 2021 18:49:22 +0200 Subject: [PATCH 8/9] Remove -y --- FFMpegCore/FFMpeg/Arguments/InputPipeArgument.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFMpegCore/FFMpeg/Arguments/InputPipeArgument.cs b/FFMpegCore/FFMpeg/Arguments/InputPipeArgument.cs index 479fa90..199d324 100644 --- a/FFMpegCore/FFMpeg/Arguments/InputPipeArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/InputPipeArgument.cs @@ -17,7 +17,7 @@ public InputPipeArgument(IPipeSource writer) : base(PipeDirection.Out) Writer = writer; } - public override string Text => $"-y {Writer.GetStreamArguments()} -i \"{PipePath}\""; + public override string Text => $"{Writer.GetStreamArguments()} -i \"{PipePath}\""; protected override async Task ProcessDataAsync(CancellationToken token) { From d5e8444cb8bc734e0ebfa75ff78bf48958ad21df Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Tue, 8 Jun 2021 19:10:30 +0200 Subject: [PATCH 9/9] Update nuget info --- FFMpegCore/FFMpegCore.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index bf9e682..c8fa692 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -9,9 +9,10 @@ 3.0.0.0 3.0.0.0 3.0.0.0 - - Added support for mirroring video filter (thanks gorobvictor) + - Added support for PCM audio through RawAudioPipeSource (thanks to Namaneo) +- Removed -y in InputPipeArgument due to reported problems 8 - 4.2.0 + 4.3.0 MIT Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev ffmpeg ffprobe convert video audio mediafile resize analyze muxing