mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
Pan filter implementation and testing
This commit is contained in:
parent
78a703fc93
commit
7a661b6ab3
4 changed files with 138 additions and 3 deletions
|
@ -414,5 +414,38 @@ public void Builder_BuildString_ForcePixelFormat()
|
|||
.OutputToFile("output.mp4", false, opt => opt.ForcePixelFormat("yuv444p")).Arguments;
|
||||
Assert.AreEqual("-i \"input.mp4\" -pix_fmt yuv444p \"output.mp4\"", str);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Builder_BuildString_PanAudioFilterChannelNumber()
|
||||
{
|
||||
var str = FFMpegArguments.FromFileInput("input.mp4")
|
||||
.OutputToFile("output.mp4", false,
|
||||
opt => opt.WithAudioFilters(filterOptions => filterOptions.Pan(2, "c0=c1", "c1=c1")))
|
||||
.Arguments;
|
||||
|
||||
Assert.AreEqual("-i \"input.mp4\" -af \"pan=2c|c0=c1|c1=c1\" \"output.mp4\"", str);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Builder_BuildString_PanAudioFilterChannelLayout()
|
||||
{
|
||||
var str = FFMpegArguments.FromFileInput("input.mp4")
|
||||
.OutputToFile("output.mp4", false,
|
||||
opt => opt.WithAudioFilters(filterOptions => filterOptions.Pan("stereo", "c0=c0", "c1=c1")))
|
||||
.Arguments;
|
||||
|
||||
Assert.AreEqual("-i \"input.mp4\" -af \"pan=stereo|c0=c0|c1=c1\" \"output.mp4\"", str);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Builder_BuildString_PanAudioFilterChannelNoOutputDefinition()
|
||||
{
|
||||
var str = FFMpegArguments.FromFileInput("input.mp4")
|
||||
.OutputToFile("output.mp4", false,
|
||||
opt => opt.WithAudioFilters(filterOptions => filterOptions.Pan("stereo")))
|
||||
.Arguments;
|
||||
|
||||
Assert.AreEqual("-i \"input.mp4\" -af \"pan=stereo\" \"output.mp4\"", str);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -223,5 +223,63 @@ public void Audio_ToAAC_Args_Pipe_InvalidSampleRate()
|
|||
.WithAudioCodec(AudioCodec.Aac))
|
||||
.ProcessSynchronously());
|
||||
}
|
||||
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void Audio_Pan_ToMono()
|
||||
{
|
||||
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
|
||||
|
||||
var success = FFMpegArguments.FromFileInput(TestResources.Mp4Video)
|
||||
.OutputToFile(outputFile, true,
|
||||
argumentOptions => argumentOptions
|
||||
.WithAudioFilters(filter => filter.Pan(1, "c0 < 0.9 * c0 + 0.1 * c1")))
|
||||
.ProcessSynchronously();
|
||||
|
||||
var mediaAnalysis = FFProbe.Analyse(outputFile);
|
||||
|
||||
Assert.IsTrue(success);
|
||||
Assert.AreEqual(1, mediaAnalysis.AudioStreams.Count);
|
||||
}
|
||||
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void Audio_Pan_ToMonoNoDefinitions()
|
||||
{
|
||||
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
|
||||
|
||||
var success = FFMpegArguments.FromFileInput(TestResources.Mp4Video)
|
||||
.OutputToFile(outputFile, true,
|
||||
argumentOptions => argumentOptions
|
||||
.WithAudioFilters(filter => filter.Pan(1)))
|
||||
.ProcessSynchronously();
|
||||
|
||||
var mediaAnalysis = FFProbe.Analyse(outputFile);
|
||||
|
||||
Assert.IsTrue(success);
|
||||
Assert.AreEqual(1, mediaAnalysis.AudioStreams.Count);
|
||||
}
|
||||
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void Audio_Pan_ToMonoChannelsToOutputDefinitionsMismatch()
|
||||
{
|
||||
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
|
||||
|
||||
var ex = Assert.ThrowsException<ArgumentException>(() => FFMpegArguments.FromFileInput(TestResources.Mp4Video)
|
||||
.OutputToFile(outputFile, true,
|
||||
argumentOptions => argumentOptions
|
||||
.WithAudioFilters(filter => filter.Pan(1, "c0=c0", "c1=c1")))
|
||||
.ProcessSynchronously());
|
||||
}
|
||||
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void Audio_Pan_ToMonoChannelsLayoutToOutputDefinitionsMismatch()
|
||||
{
|
||||
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
|
||||
|
||||
var ex = Assert.ThrowsException<FFMpegException>(() => FFMpegArguments.FromFileInput(TestResources.Mp4Video)
|
||||
.OutputToFile(outputFile, true,
|
||||
argumentOptions => argumentOptions
|
||||
.WithAudioFilters(filter => filter.Pan("mono", "c0=c0", "c1=c1")))
|
||||
.ProcessSynchronously());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using FFMpegCore.Enums;
|
||||
using FFMpegCore.Exceptions;
|
||||
|
||||
namespace FFMpegCore.Arguments
|
||||
|
@ -44,6 +42,9 @@ public class AudioFilterOptions
|
|||
{
|
||||
public List<IAudioFilterArgument> Arguments { get; } = new List<IAudioFilterArgument>();
|
||||
|
||||
public AudioFilterOptions Pan(string channelLayout, params string[] outputDefinitions) => WithArgument(new PanArgument(channelLayout, outputDefinitions));
|
||||
public AudioFilterOptions Pan(int channels, params string[] outputDefinitions) => WithArgument(new PanArgument(channels, outputDefinitions));
|
||||
|
||||
private AudioFilterOptions WithArgument(IAudioFilterArgument argument)
|
||||
{
|
||||
Arguments.Add(argument);
|
||||
|
|
43
FFMpegCore/FFMpeg/Arguments/PanArgument.cs
Normal file
43
FFMpegCore/FFMpeg/Arguments/PanArgument.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace FFMpegCore.Arguments
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents scale parameter
|
||||
/// </summary>
|
||||
public class PanArgument : IAudioFilterArgument
|
||||
{
|
||||
public readonly string ChannelLayout;
|
||||
private readonly string[] _outputDefinitions;
|
||||
|
||||
public PanArgument(string channelLayout, params string[] outputDefinitions)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(channelLayout))
|
||||
{
|
||||
throw new ArgumentException("The channel layout must be set" ,nameof(channelLayout));
|
||||
}
|
||||
|
||||
ChannelLayout = channelLayout;
|
||||
|
||||
_outputDefinitions = outputDefinitions;
|
||||
}
|
||||
|
||||
public PanArgument(int channels, params string[] outputDefinitions)
|
||||
{
|
||||
if (channels <= 0) throw new ArgumentOutOfRangeException(nameof(channels));
|
||||
|
||||
if (outputDefinitions.Length > channels)
|
||||
throw new ArgumentException("The number of output definitions must be equal or lower than number of channels", nameof(outputDefinitions));
|
||||
|
||||
ChannelLayout = $"{channels}c";
|
||||
|
||||
_outputDefinitions = outputDefinitions;
|
||||
}
|
||||
|
||||
public string Key { get; } = "pan";
|
||||
|
||||
public string Value =>
|
||||
string.Join("|", Enumerable.Empty<string>().Append(ChannelLayout).Concat(_outputDefinitions));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue