Skip to content

Creating Custom Filters

simonbuehler edited this page Feb 16, 2016 · 2 revisions

Getting Started

Hudl.FFmpeg is already packaged with support for many of the commonly used filters. Still if you find yourself in need of one that we have not included, you may create and use them yourselves.

Filter Serialization

In Hudl.FFmpeg we use classes to represent filters. These classes are serialized to command strings at the time of rendering. In order to correctly serialize a filter we need to know a little bit about it. We can start by taking a simple filter such as setdar, which is used for setting the display aspect ratio on an input stream. Let's start by stubbing out our class.

public class SetDar
{
    public SetDar()
    {
    }

    public Ratio Ratio { get; set; }
}

IFilter

The IFilter interface is what Hudl.FFmpeg uses to identify a class as a filter. All filter implementations must implement the IFilter interface in order to use them in production.

public class SetDar : IFilter
  ...

ForStream Attribute

ForStream is a class-level attribute used to tell Hudl.FFmpeg what kinds of streams the filter supports. This is done by passing the Type of stream to expect. For example if I was to implement an audio only filter, such as afade, I would write [ForStream(typeof(AudioStream)]. You may use multiple attributes if your filter supports both VideoStreams and AudioStreams.

Parameter Type Description
Type Type sets the type of stream that is allowed when using this filter.

Example

[ForStream(Type=typeof(VideoStream)]
public class SetDar : IFilter
  ...

Filter Attribute

Filter is a class-level attribute used in serialization and validation. It contains the following parameters

Parameter Type Description
Name string sets the ffmpeg name of the filter, this name is used in serialization.
MinInputs int sets the minimum number of accepted input streams.
MaxInputs int sets the maximum number of accepted input streams.

Example

[ForStream(typeof(VideoStream)]
[Filter(Name = "setdar", MinInputs = 1, MaxInputs = 1)]
public class SetDar : IFilter
  ...

FilterParameter Attribute

FilterParameter is a property-level attribute used in serialization. It is used to dictate which properties make up the filter properties. It contains the following parameters

Parameter Type Description
Name string sets the ffmpeg name of the filter parameter, this name is used in serialization.
Default object sets the default value for the parameter. if the value matches the default then this parameter will not be serialized.
ShouldHideName bool sets a boolean indicating if the name value should be hidden during serialization.
ShouldHideValue bool sets a boolean indicating if the value should be hidden during serialization.
Formatter Type sets a type of IFormatter that will be used to format the value object to string.
Binding Type sets a type of IFilterParameterBinding that will bind the value object to a value within the FilterBindingContext.

Example

 ...

    [FilterParameter(Name = "dar", Formatter = typeof(RatioFractionalStringFormatter))]
    public Ratio Ratio { get; set; }

Closing

When you put it all together you get something that looks like this

    [ForStream(Type = typeof(VideoStream))]
    [Filter(Name = "setdar", MinInputs = 1, MaxInputs = 1)]
    public class SetDar : IFilter
    {
        public SetDar()
        {
        }
        public SetDar(Ratio ratio)
            : this()
        {
            if (ratio == null)
            {
                throw new ArgumentNullException("ratio");
            }

            Ratio = ratio;
        }

        [FilterParameter(Name = "dar", Formatter = typeof(RatioFractionalStringFormatter))]
        public Ratio Ratio { get; set; }
    }

Please contribute your custom filters to our project, if you need them then there is a good chance that someone else does too!