From a69f99cdc817054fd1a979f939e81573e9e4b164 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 27 Feb 2017 10:05:04 -0500 Subject: [PATCH 01/11] Add support for Reverse and AReverse filters --- Hudl.FFmpeg/Filters/AReverse.cs | 14 ++++++++++++++ Hudl.FFmpeg/Filters/Reverse.cs | 14 ++++++++++++++ Hudl.FFmpeg/Hudl.Ffmpeg.csproj | 2 ++ 3 files changed, 30 insertions(+) create mode 100644 Hudl.FFmpeg/Filters/AReverse.cs create mode 100644 Hudl.FFmpeg/Filters/Reverse.cs diff --git a/Hudl.FFmpeg/Filters/AReverse.cs b/Hudl.FFmpeg/Filters/AReverse.cs new file mode 100644 index 0000000..388b9ee --- /dev/null +++ b/Hudl.FFmpeg/Filters/AReverse.cs @@ -0,0 +1,14 @@ +using Hudl.FFmpeg.Attributes; +using Hudl.FFmpeg.Filters.Attributes; +using Hudl.FFmpeg.Filters.Interfaces; +using Hudl.FFmpeg.Resources.BaseTypes; + +namespace Hudl.FFmpeg.Filters +{ + [ForStream(Type = typeof(AudioStream))] + [Filter(Name ="areverse", MinInputs = 1, MaxInputs = 1)] + public class AReverse : IFilter + { + //This filter accepts no parameters + } +} diff --git a/Hudl.FFmpeg/Filters/Reverse.cs b/Hudl.FFmpeg/Filters/Reverse.cs new file mode 100644 index 0000000..9702007 --- /dev/null +++ b/Hudl.FFmpeg/Filters/Reverse.cs @@ -0,0 +1,14 @@ +using Hudl.FFmpeg.Attributes; +using Hudl.FFmpeg.Filters.Attributes; +using Hudl.FFmpeg.Filters.Interfaces; +using Hudl.FFmpeg.Resources.BaseTypes; + +namespace Hudl.FFmpeg.Filters +{ + [ForStream(Type = typeof(VideoStream))] + [Filter(Name ="reverse", MinInputs = 1, MaxInputs = 1)] + public class Reverse : IFilter + { + //This filter accepts no parameters + } +} diff --git a/Hudl.FFmpeg/Hudl.Ffmpeg.csproj b/Hudl.FFmpeg/Hudl.Ffmpeg.csproj index 6e97d7d..7bfc608 100644 --- a/Hudl.FFmpeg/Hudl.Ffmpeg.csproj +++ b/Hudl.FFmpeg/Hudl.Ffmpeg.csproj @@ -61,6 +61,8 @@ + + From b4eae1ffbb941616d232683f40ff4a1e6a12f552 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 27 Feb 2017 10:06:53 -0500 Subject: [PATCH 02/11] Add filter comment --- Hudl.FFmpeg/Filters/AReverse.cs | 4 ++++ Hudl.FFmpeg/Filters/Reverse.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Hudl.FFmpeg/Filters/AReverse.cs b/Hudl.FFmpeg/Filters/AReverse.cs index 388b9ee..a17f254 100644 --- a/Hudl.FFmpeg/Filters/AReverse.cs +++ b/Hudl.FFmpeg/Filters/AReverse.cs @@ -5,6 +5,10 @@ namespace Hudl.FFmpeg.Filters { + /// + /// Reverses an audio clip. Note that it will buffer the entire clip, + /// so it's recommented to use trimming. + /// [ForStream(Type = typeof(AudioStream))] [Filter(Name ="areverse", MinInputs = 1, MaxInputs = 1)] public class AReverse : IFilter diff --git a/Hudl.FFmpeg/Filters/Reverse.cs b/Hudl.FFmpeg/Filters/Reverse.cs index 9702007..30bd946 100644 --- a/Hudl.FFmpeg/Filters/Reverse.cs +++ b/Hudl.FFmpeg/Filters/Reverse.cs @@ -5,6 +5,10 @@ namespace Hudl.FFmpeg.Filters { + /// + /// Reverses a video clip. Note that it will buffer the entire clip, + /// so it's recommented to use trimming. + /// [ForStream(Type = typeof(VideoStream))] [Filter(Name ="reverse", MinInputs = 1, MaxInputs = 1)] public class Reverse : IFilter From ef297b2001ce099a07227fb4f6db65e7da3ca59f Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 27 Feb 2017 11:01:52 -0500 Subject: [PATCH 03/11] First pass at ZoomPan filter --- Hudl.FFmpeg/Filters/ZoomPan.cs | 57 ++++++++++++++++++++++++++++++++++ Hudl.FFmpeg/Hudl.Ffmpeg.csproj | 1 + 2 files changed, 58 insertions(+) create mode 100644 Hudl.FFmpeg/Filters/ZoomPan.cs diff --git a/Hudl.FFmpeg/Filters/ZoomPan.cs b/Hudl.FFmpeg/Filters/ZoomPan.cs new file mode 100644 index 0000000..acec02f --- /dev/null +++ b/Hudl.FFmpeg/Filters/ZoomPan.cs @@ -0,0 +1,57 @@ +using Hudl.FFmpeg.Attributes; +using Hudl.FFmpeg.Enums; +using Hudl.FFmpeg.Filters.Attributes; +using Hudl.FFmpeg.Filters.Interfaces; +using Hudl.FFmpeg.Formatters; +using Hudl.FFmpeg.Metadata; +using Hudl.FFmpeg.Resources.BaseTypes; +using System.Collections.Generic; + +namespace Hudl.FFmpeg.Filters +{ + /// + /// Applies Zoom & Pan effect. + /// + [ForStream(Type = typeof(VideoStream))] + [Filter(Name ="zoompan", MinInputs = 1, MaxInputs = 1)] + public class ZoomPan : IFilter + { + public ZoomPan() + { + + } + + public ZoomPan(string zoom, string x, string y, string d, ScalePresetType size) + { + Zoom = zoom; + X = x; + Y = y; + D = d; + S = size; + } + + [FilterParameter(Name = "zoom", Default = "1", Formatter = typeof(SingleQuoteFormatter))] + public string Zoom { get; set; } + + [FilterParameter(Name = "x", Default = "0", Formatter = typeof(SingleQuoteFormatter))] + public string X { get; set; } + + [FilterParameter(Name = "y", Default = "0", Formatter = typeof(SingleQuoteFormatter))] + public string Y { get; set; } + + [FilterParameter(Name = "d")] + public string D { get; set; } + + [FilterParameter(Name = "s", Default = ScalePresetType.Hd720)] + public ScalePresetType S { get; set; } + + [FilterParameter(Name = "fps", Default = 25)] + public string Fps { get; set; } + + public virtual MetadataInfoTreeContainer EditInfo(MetadataInfoTreeContainer infoToUpdate, List suppliedInfo) + { + //To-do: Need to fill this in. + return infoToUpdate; + } + } +} diff --git a/Hudl.FFmpeg/Hudl.Ffmpeg.csproj b/Hudl.FFmpeg/Hudl.Ffmpeg.csproj index 7bfc608..1d6e7cb 100644 --- a/Hudl.FFmpeg/Hudl.Ffmpeg.csproj +++ b/Hudl.FFmpeg/Hudl.Ffmpeg.csproj @@ -62,6 +62,7 @@ + From f13572b9cb48839e205714a12f7fe19a46cb0de0 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 27 Feb 2017 12:02:35 -0500 Subject: [PATCH 04/11] Add alphaextract and alphamerge filters --- Hudl.FFmpeg/Filters/AlphaExtract.cs | 17 +++++++++++++++++ Hudl.FFmpeg/Filters/AlphaMerge.cs | 18 ++++++++++++++++++ Hudl.FFmpeg/Filters/ZoomPan.cs | 12 ++++++------ Hudl.FFmpeg/Hudl.Ffmpeg.csproj | 2 ++ 4 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 Hudl.FFmpeg/Filters/AlphaExtract.cs create mode 100644 Hudl.FFmpeg/Filters/AlphaMerge.cs diff --git a/Hudl.FFmpeg/Filters/AlphaExtract.cs b/Hudl.FFmpeg/Filters/AlphaExtract.cs new file mode 100644 index 0000000..bfb3b97 --- /dev/null +++ b/Hudl.FFmpeg/Filters/AlphaExtract.cs @@ -0,0 +1,17 @@ +using Hudl.FFmpeg.Attributes; +using Hudl.FFmpeg.Filters.Attributes; +using Hudl.FFmpeg.Filters.Interfaces; +using Hudl.FFmpeg.Resources.BaseTypes; + +namespace Hudl.FFmpeg.Filters +{ + /// + /// Extracts the alpha component from the input as a grayscale video. + /// + [ForStream(Type = typeof(VideoStream))] + [Filter(Name ="alphaextract", MinInputs = 1, MaxInputs = 1)] + public class AlphaExtract : IFilter + { + //This filter accepts no parameters + } +} diff --git a/Hudl.FFmpeg/Filters/AlphaMerge.cs b/Hudl.FFmpeg/Filters/AlphaMerge.cs new file mode 100644 index 0000000..a520ab3 --- /dev/null +++ b/Hudl.FFmpeg/Filters/AlphaMerge.cs @@ -0,0 +1,18 @@ +using Hudl.FFmpeg.Attributes; +using Hudl.FFmpeg.Filters.Attributes; +using Hudl.FFmpeg.Filters.Interfaces; +using Hudl.FFmpeg.Resources.BaseTypes; + +namespace Hudl.FFmpeg.Filters +{ + /// + /// Adds or replaces the alpha component of the primary input with + /// the grayscale value of a second input. + /// + [ForStream(Type = typeof(VideoStream))] + [Filter(Name ="alphamerge", MinInputs = 2, MaxInputs = 2)] + public class AlphaMerge : IFilter + { + //This filter accepts no parameters + } +} diff --git a/Hudl.FFmpeg/Filters/ZoomPan.cs b/Hudl.FFmpeg/Filters/ZoomPan.cs index acec02f..f7d012e 100644 --- a/Hudl.FFmpeg/Filters/ZoomPan.cs +++ b/Hudl.FFmpeg/Filters/ZoomPan.cs @@ -21,22 +21,22 @@ public ZoomPan() } - public ZoomPan(string zoom, string x, string y, string d, ScalePresetType size) + public ZoomPan(string zoom, string x, string y, string d, ScalePresetType? size) { Zoom = zoom; X = x; Y = y; D = d; - S = size; + S = size.HasValue ? size.Value : ScalePresetType.Hd720; } - [FilterParameter(Name = "zoom", Default = "1", Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Name = "zoom", Formatter = typeof(SingleQuoteFormatter))] public string Zoom { get; set; } - [FilterParameter(Name = "x", Default = "0", Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Name = "x", Formatter = typeof(SingleQuoteFormatter))] public string X { get; set; } - [FilterParameter(Name = "y", Default = "0", Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Name = "y", Formatter = typeof(SingleQuoteFormatter))] public string Y { get; set; } [FilterParameter(Name = "d")] @@ -46,7 +46,7 @@ public ZoomPan(string zoom, string x, string y, string d, ScalePresetType size) public ScalePresetType S { get; set; } [FilterParameter(Name = "fps", Default = 25)] - public string Fps { get; set; } + public double Fps { get; set; } public virtual MetadataInfoTreeContainer EditInfo(MetadataInfoTreeContainer infoToUpdate, List suppliedInfo) { diff --git a/Hudl.FFmpeg/Hudl.Ffmpeg.csproj b/Hudl.FFmpeg/Hudl.Ffmpeg.csproj index 1d6e7cb..0611fd6 100644 --- a/Hudl.FFmpeg/Hudl.Ffmpeg.csproj +++ b/Hudl.FFmpeg/Hudl.Ffmpeg.csproj @@ -59,9 +59,11 @@ + + From d7223efbb00f63b5c8a5f7c8c09c1d79020b9af0 Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Mon, 27 Feb 2017 20:26:53 -0600 Subject: [PATCH 05/11] chnage the color formatter to be seconds only based --- .../Formatters/TimeSpanSecondsFormatter.cs | 14 ++++++++++++++ Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj | 1 + Hudl.FFmpeg/Filters/Color.cs | 2 +- Hudl.Ffmpeg.Tests/Filter/FilterTests.cs | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Hudl.FFmpeg.Core/Formatters/TimeSpanSecondsFormatter.cs diff --git a/Hudl.FFmpeg.Core/Formatters/TimeSpanSecondsFormatter.cs b/Hudl.FFmpeg.Core/Formatters/TimeSpanSecondsFormatter.cs new file mode 100644 index 0000000..6d9e52c --- /dev/null +++ b/Hudl.FFmpeg.Core/Formatters/TimeSpanSecondsFormatter.cs @@ -0,0 +1,14 @@ +using System; +using Hudl.FFmpeg.Formatters.Utility; +using Hudl.FFmpeg.Interfaces; + +namespace Hudl.FFmpeg.Formatters +{ + public class TimeSpanSecondsFormatter : IFormatter + { + public string Format(object value) + { + return ((TimeSpan)value).TotalSeconds.ToString(); + } + } +} diff --git a/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj b/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj index 3384587..6d0144f 100644 --- a/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj +++ b/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj @@ -115,6 +115,7 @@ + diff --git a/Hudl.FFmpeg/Filters/Color.cs b/Hudl.FFmpeg/Filters/Color.cs index 9f2a30f..346fb10 100644 --- a/Hudl.FFmpeg/Filters/Color.cs +++ b/Hudl.FFmpeg/Filters/Color.cs @@ -32,7 +32,7 @@ public class Color : IFilter, IMetadataManipulation [FilterParameter(Name = "r", Default = 25)] public int? FrameRate { get; set; } - [FilterParameter(Name = "d", Formatter = typeof(TimeSpanFormatter))] + [FilterParameter(Name = "d", Formatter = typeof(TimeSpanSecondsFormatter))] [Validate(typeof(TimeSpanGreterThanZeroValidator))] public TimeSpan? Duration { get; set; } diff --git a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs index 648eede..3f024d6 100644 --- a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs +++ b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs @@ -692,7 +692,7 @@ public void Color_Verify() Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); filter.Duration = TimeSpan.FromSeconds(3.222); - filterValue.Append(":d=00:00:03.222"); + filterValue.Append(":d=3.222"); Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); filter.SampleAspectRatio = Ratio.Create(1, 1); From c21175f32d460bedae089b14a7a9e6cec3a64193 Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Mon, 27 Feb 2017 23:29:34 -0600 Subject: [PATCH 06/11] update pad validation rules --- Hudl.FFmpeg/Filters/Pad.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Hudl.FFmpeg/Filters/Pad.cs b/Hudl.FFmpeg/Filters/Pad.cs index eaeb568..f7cd46a 100644 --- a/Hudl.FFmpeg/Filters/Pad.cs +++ b/Hudl.FFmpeg/Filters/Pad.cs @@ -45,11 +45,11 @@ public Pad(string expression) public int? Height { get; set; } [FilterParameter(Name = "x")] - [Validate(LogicalOperators.GreaterThan, 0)] + [Validate(LogicalOperators.GreaterThanOrEqual 0)] public int? X { get; set; } [FilterParameter(Name = "y")] - [Validate(LogicalOperators.GreaterThan, 0)] + [Validate(LogicalOperators.GreaterThanOrEqual, 0)] public int? Y { get; set; } [FilterParameter(Name = "color")] From f21b43b6f3605633de9c7eba7916bc2f19362136 Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Mon, 27 Feb 2017 23:31:16 -0600 Subject: [PATCH 07/11] missing comma --- Hudl.FFmpeg/Filters/Pad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hudl.FFmpeg/Filters/Pad.cs b/Hudl.FFmpeg/Filters/Pad.cs index f7cd46a..27d0ba0 100644 --- a/Hudl.FFmpeg/Filters/Pad.cs +++ b/Hudl.FFmpeg/Filters/Pad.cs @@ -45,7 +45,7 @@ public Pad(string expression) public int? Height { get; set; } [FilterParameter(Name = "x")] - [Validate(LogicalOperators.GreaterThanOrEqual 0)] + [Validate(LogicalOperators.GreaterThanOrEqual, 0)] public int? X { get; set; } [FilterParameter(Name = "y")] From 4bee81b510680ddd95b63ce28e28fcff1f57365a Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Tue, 28 Feb 2017 08:21:02 -0600 Subject: [PATCH 08/11] update tests and zoom pan filter --- .../SingleQuoteExpressionFormatter.cs | 17 ++++++ Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj | 1 + Hudl.FFmpeg/Filters/ZoomPan.cs | 38 +++++++----- Hudl.Ffmpeg.Tests/Filter/FilterTests.cs | 60 +++++++++++++++++++ 4 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 Hudl.FFmpeg.Core/Formatters/SingleQuoteExpressionFormatter.cs diff --git a/Hudl.FFmpeg.Core/Formatters/SingleQuoteExpressionFormatter.cs b/Hudl.FFmpeg.Core/Formatters/SingleQuoteExpressionFormatter.cs new file mode 100644 index 0000000..35b2a57 --- /dev/null +++ b/Hudl.FFmpeg.Core/Formatters/SingleQuoteExpressionFormatter.cs @@ -0,0 +1,17 @@ +using Hudl.FFmpeg.Interfaces; +using System.Text.RegularExpressions; + +namespace Hudl.FFmpeg.Formatters +{ + public class SingleQuoteExpressionFormatter : IFormatter + { + public string Format(object value) + { + var valueAsString = value.ToString(); + var valueIsNumeric = Regex.IsMatch(valueAsString, @"^\d+$"); + return (!valueIsNumeric) + ? $"'{valueAsString}'" + : valueAsString; + } + } +} diff --git a/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj b/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj index 6d0144f..05d942f 100644 --- a/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj +++ b/Hudl.FFmpeg.Core/Hudl.FFmpeg.Core.csproj @@ -111,6 +111,7 @@ + diff --git a/Hudl.FFmpeg/Filters/ZoomPan.cs b/Hudl.FFmpeg/Filters/ZoomPan.cs index f7d012e..24cad75 100644 --- a/Hudl.FFmpeg/Filters/ZoomPan.cs +++ b/Hudl.FFmpeg/Filters/ZoomPan.cs @@ -1,4 +1,5 @@ using Hudl.FFmpeg.Attributes; +using Hudl.FFmpeg.Common; using Hudl.FFmpeg.Enums; using Hudl.FFmpeg.Filters.Attributes; using Hudl.FFmpeg.Filters.Interfaces; @@ -6,6 +7,7 @@ using Hudl.FFmpeg.Metadata; using Hudl.FFmpeg.Resources.BaseTypes; using System.Collections.Generic; +using System.Drawing; namespace Hudl.FFmpeg.Filters { @@ -18,40 +20,44 @@ public class ZoomPan : IFilter { public ZoomPan() { - } - public ZoomPan(string zoom, string x, string y, string d, ScalePresetType? size) + public ZoomPan(string zoom, string x, string y, string d, double? fps, Size? size) { Zoom = zoom; X = x; Y = y; D = d; - S = size.HasValue ? size.Value : ScalePresetType.Hd720; + S = size; + Fps = fps; + } + + public ZoomPan(string zoom, string x, string y, string d, double? fps, ScalePresetType? preset) + : this(zoom, x, y, d, fps, (Size?)null) + { + Size sizeValue = default(Size); + if (preset.HasValue && Helpers.ScalingPresets.TryGetValue(preset.Value, out sizeValue)) + { + S = sizeValue; + } } - [FilterParameter(Name = "zoom", Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Name = "zoom", Formatter = typeof(SingleQuoteExpressionFormatter))] public string Zoom { get; set; } - [FilterParameter(Name = "x", Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Name = "x", Formatter = typeof(SingleQuoteExpressionFormatter))] public string X { get; set; } - [FilterParameter(Name = "y", Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Name = "y", Formatter = typeof(SingleQuoteExpressionFormatter))] public string Y { get; set; } [FilterParameter(Name = "d")] public string D { get; set; } - [FilterParameter(Name = "s", Default = ScalePresetType.Hd720)] - public ScalePresetType S { get; set; } + [FilterParameter(Name = "s", Formatter = typeof(SizeFormatter))] + public Size? S { get; set; } - [FilterParameter(Name = "fps", Default = 25)] - public double Fps { get; set; } - - public virtual MetadataInfoTreeContainer EditInfo(MetadataInfoTreeContainer infoToUpdate, List suppliedInfo) - { - //To-do: Need to fill this in. - return infoToUpdate; - } + [FilterParameter(Name = "fps")] + public double? Fps { get; set; } } } diff --git a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs index 3f024d6..5647aa3 100644 --- a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs +++ b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs @@ -702,6 +702,66 @@ public void Color_Verify() } + [Fact] + public void ZoomPan_Verify() + { + var filter = FilterFactory.CreateEmpty(); + var filterValue = new StringBuilder(100); + Assert.DoesNotThrow(() => FilterSerializer.Serialize(filter)); + + filter.Zoom = "2"; + filterValue.Append("zoompan=zoom=2"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.X = "100"; + filterValue.Append(":x=100"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.Y = "200"; + filterValue.Append(":y=200"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.D = "1"; + filterValue.Append(":d=1"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.S = new Size(1280, 720); + filterValue.Append(":s=1280x720"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.Fps = 30; + filterValue.Append(":fps=30"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + var filter2 = FilterFactory.CreateEmpty(); + filterValue = new StringBuilder(100); + Assert.DoesNotThrow(() => FilterSerializer.Serialize(filter2)); + + filter2.Zoom = "in_w"; + filterValue.Append("zoompan=zoom='in_w'"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter2)); + + filter2.X = "in_w+2"; + filterValue.Append(":x='in_w+2'"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter2)); + + filter2.Y = "out_w+3"; + filterValue.Append(":y='out_w+3'"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter2)); + + filter2.D = "1"; + filterValue.Append(":d=1"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter2)); + + filter2.S = new Size(1280, 720); + filterValue.Append(":s=1280x720"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter2)); + + filter2.Fps = 30; + filterValue.Append(":fps=30"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter2)); + } + private class FilterFactory { internal static TFilter CreateEmpty() From 650bce206f0ef8362f71cb8cf083378a6d1f5409 Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Tue, 28 Feb 2017 14:45:41 -0600 Subject: [PATCH 09/11] update blend filter and filter serializer so that they load and filter correctly --- .../Filters/Attributes/FilterParameterAttribute.cs | 2 ++ .../Serialization/FilterSerializerAttributeParser.cs | 5 +++++ Hudl.FFmpeg/Filters/Blend.cs | 9 ++++++--- Hudl.Ffmpeg.Tests/Filter/FilterTests.cs | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Hudl.FFmpeg.Core/Filters/Attributes/FilterParameterAttribute.cs b/Hudl.FFmpeg.Core/Filters/Attributes/FilterParameterAttribute.cs index dc1e354..19c3bc4 100644 --- a/Hudl.FFmpeg.Core/Filters/Attributes/FilterParameterAttribute.cs +++ b/Hudl.FFmpeg.Core/Filters/Attributes/FilterParameterAttribute.cs @@ -24,5 +24,7 @@ public FilterParameterAttribute(string name) public Type Formatter { get; set; } public Type Binding { get; set; } + + public int Order { get; set; } } } diff --git a/Hudl.FFmpeg.Core/Filters/Serialization/FilterSerializerAttributeParser.cs b/Hudl.FFmpeg.Core/Filters/Serialization/FilterSerializerAttributeParser.cs index 937d90d..2d4a791 100644 --- a/Hudl.FFmpeg.Core/Filters/Serialization/FilterSerializerAttributeParser.cs +++ b/Hudl.FFmpeg.Core/Filters/Serialization/FilterSerializerAttributeParser.cs @@ -69,6 +69,11 @@ private static void FillFilterParameterAttributes(FilterSerializerData filterSer IsDefault = filterPropertyIsDefault }); } + + if (filterSerializerData.Parameters.Any(f => f.Parameter.Order > 0)) + { + filterSerializerData.Parameters = filterSerializerData.Parameters.OrderBy(f => f.Parameter.Order).ToList(); + } } private static object GetFilterSerializationBindingValue(FilterParameterAttribute filterParameterAttribute, PropertyInfo propertyInfo, FilterBindingContext context, IFilter filter) diff --git a/Hudl.FFmpeg/Filters/Blend.cs b/Hudl.FFmpeg/Filters/Blend.cs index a398dd3..050c539 100644 --- a/Hudl.FFmpeg/Filters/Blend.cs +++ b/Hudl.FFmpeg/Filters/Blend.cs @@ -31,18 +31,21 @@ public Blend(string expression) Expression = expression; } - [FilterParameter] + [FilterParameter(Order = 1)] public BlendVideoOptionType? Option { get; set; } - [FilterParameter(Default = BlendVideoModeType.and)] + [FilterParameter(Order = 2, Default = BlendVideoModeType.and)] public BlendVideoModeType? Mode { get; set; } /// /// the blend expression details can be found at http://ffmpeg.org/ffmpeg-all.html#blend. /// - [FilterParameter(Formatter = typeof(SingleQuoteFormatter))] + [FilterParameter(Order = 3, Formatter = typeof(SingleQuoteFormatter))] public string Expression { get; set; } + [FilterParameter(Order = 4, Name = "repeatlast", Default = false, Formatter = typeof(BoolToInt32Formatter))] + public bool RepeatLast { get; set; } + public virtual MetadataInfoTreeContainer EditInfo(MetadataInfoTreeContainer infoToUpdate, List suppliedInfo) { infoToUpdate.VideoStream.VideoMetadata.Duration = suppliedInfo.Min(r => r.VideoStream.VideoMetadata.Duration); diff --git a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs index 5647aa3..2dbf71b 100644 --- a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs +++ b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs @@ -330,6 +330,10 @@ public void Blend_Verify() filter.Expression = "A*(if(gte(T,{0}),1,T/{0}))+B*(1-(if(gte(T,{0}),1,T/{0})))"; filterValue.Append("blend=all_expr='A*(if(gte(T,{0}),1,T/{0}))+B*(1-(if(gte(T,{0}),1,T/{0})))'"); Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.RepeatLast = true; + filterValue.Append(":repeatlast=1"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); } [Fact] From 02c16301e63609f10c0b82517cc1a126de2f56c5 Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Tue, 28 Feb 2017 15:04:46 -0600 Subject: [PATCH 10/11] update blend filter --- Hudl.FFmpeg/Filters/Blend.cs | 3 ++- Hudl.Ffmpeg.Tests/Filter/FilterTests.cs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Hudl.FFmpeg/Filters/Blend.cs b/Hudl.FFmpeg/Filters/Blend.cs index 050c539..d72273b 100644 --- a/Hudl.FFmpeg/Filters/Blend.cs +++ b/Hudl.FFmpeg/Filters/Blend.cs @@ -24,6 +24,7 @@ public Blend() { Mode = BlendVideoModeType.and; Option = BlendVideoOptionType.all_expr; + RepeatLast = true; } public Blend(string expression) : this() @@ -43,7 +44,7 @@ public Blend(string expression) [FilterParameter(Order = 3, Formatter = typeof(SingleQuoteFormatter))] public string Expression { get; set; } - [FilterParameter(Order = 4, Name = "repeatlast", Default = false, Formatter = typeof(BoolToInt32Formatter))] + [FilterParameter(Order = 4, Name = "repeatlast", Default = true, Formatter = typeof(BoolToInt32Formatter))] public bool RepeatLast { get; set; } public virtual MetadataInfoTreeContainer EditInfo(MetadataInfoTreeContainer infoToUpdate, List suppliedInfo) diff --git a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs index 2dbf71b..48e7690 100644 --- a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs +++ b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs @@ -331,8 +331,8 @@ public void Blend_Verify() filterValue.Append("blend=all_expr='A*(if(gte(T,{0}),1,T/{0}))+B*(1-(if(gte(T,{0}),1,T/{0})))'"); Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); - filter.RepeatLast = true; - filterValue.Append(":repeatlast=1"); + filter.RepeatLast = false; + filterValue.Append(":repeatlast=0"); Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); } From 16522ed8eb06e2b1faeb81b0c7f7b09e200e9e7b Mon Sep 17 00:00:00 2001 From: Casey Bateman Date: Wed, 1 Mar 2017 09:48:57 -0600 Subject: [PATCH 11/11] update filters for blend to inlude all settings --- Hudl.FFmpeg/Filters/Blend.cs | 3 +++ Hudl.Ffmpeg.Tests/Filter/FilterTests.cs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Hudl.FFmpeg/Filters/Blend.cs b/Hudl.FFmpeg/Filters/Blend.cs index d72273b..e57fb22 100644 --- a/Hudl.FFmpeg/Filters/Blend.cs +++ b/Hudl.FFmpeg/Filters/Blend.cs @@ -47,6 +47,9 @@ public Blend(string expression) [FilterParameter(Order = 4, Name = "repeatlast", Default = true, Formatter = typeof(BoolToInt32Formatter))] public bool RepeatLast { get; set; } + [FilterParameter(Order = 5, Name = "shortest", Default = false, Formatter = typeof(BoolToInt32Formatter))] + public bool Shortest { get; set; } + public virtual MetadataInfoTreeContainer EditInfo(MetadataInfoTreeContainer infoToUpdate, List suppliedInfo) { infoToUpdate.VideoStream.VideoMetadata.Duration = suppliedInfo.Min(r => r.VideoStream.VideoMetadata.Duration); diff --git a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs index 48e7690..e579943 100644 --- a/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs +++ b/Hudl.Ffmpeg.Tests/Filter/FilterTests.cs @@ -334,6 +334,10 @@ public void Blend_Verify() filter.RepeatLast = false; filterValue.Append(":repeatlast=0"); Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); + + filter.Shortest = true; + filterValue.Append(":shortest=1"); + Assert.Equal(filterValue.ToString(), FilterSerializer.Serialize(filter)); } [Fact]