diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs
index daa3eda..6fd108d 100644
--- a/FFMpegCore.Test/ArgumentBuilderTest.cs
+++ b/FFMpegCore.Test/ArgumentBuilderTest.cs
@@ -317,6 +317,27 @@ public void Builder_BuildString_DrawtextFilter_Alt()
str);
}
+ [TestMethod]
+ public void Builder_BuildString_SubtitleHardBurnFilter()
+ {
+ var str = FFMpegArguments
+ .FromFileInput("input.mp4")
+ .OutputToFile("output.mp4", false, opt => opt
+ .WithVideoFilters(filterOptions => filterOptions
+ .HardBurnSubtitle(SubtitleHardBurnOptions
+ .Create(subtitlePath: "sample.srt")
+ .SetCharacterEncoding("UTF-8")
+ .SetOriginalSize(1366,768)
+ .SetSubtitleIndex(0)
+ .WithStyle(StyleOptions.Create()
+ .WithParameter("FontName", "DejaVu Serif")
+ .WithParameter("PrimaryColour", "&HAA00FF00")))))
+ .Arguments;
+
+ Assert.AreEqual("-i \"input.mp4\" -vf \"subtitles=sample.srt:charenc=UTF-8:original_size=1366x768:stream_index=0:force_style='FontName=DejaVu Serif\\,PrimaryColour=&HAA00FF00'\" \"output.mp4\"",
+ str);
+ }
+
[TestMethod]
public void Builder_BuildString_StartNumber()
{
diff --git a/FFMpegCore/Extend/KeyValuePairExtensions.cs b/FFMpegCore/Extend/KeyValuePairExtensions.cs
new file mode 100644
index 0000000..28cc087
--- /dev/null
+++ b/FFMpegCore/Extend/KeyValuePairExtensions.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace FFMpegCore.Extend
+{
+ internal static class KeyValuePairExtensions
+ {
+ ///
+ /// Concat the two members of a
+ ///
+ /// Input object
+ ///
+ /// If true encloses the value part between quotes if contains an space character. If false use the
+ /// value unmodified
+ ///
+ /// The formatted string
+ public static string FormatArgumentPair(this KeyValuePair pair, bool enclose)
+ {
+ var key = pair.Key;
+ var value = enclose ? pair.Value.EncloseIfContainsSpace() : pair.Value;
+
+ return $"{key}={value}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/FFMpegCore/Extend/StringExtensions.cs b/FFMpegCore/Extend/StringExtensions.cs
new file mode 100644
index 0000000..ddcf54b
--- /dev/null
+++ b/FFMpegCore/Extend/StringExtensions.cs
@@ -0,0 +1,15 @@
+namespace FFMpegCore.Extend
+{
+ internal static class StringExtensions
+ {
+ ///
+ /// Enclose string between quotes if contains an space character
+ ///
+ /// The input
+ /// The enclosed string
+ public static string EncloseIfContainsSpace(this string input)
+ {
+ return input.Contains(" ") ? $"'{input}'" : input;
+ }
+ }
+}
\ No newline at end of file
diff --git a/FFMpegCore/FFMpeg/Arguments/SubtitleHardBurnArgument.cs b/FFMpegCore/FFMpeg/Arguments/SubtitleHardBurnArgument.cs
new file mode 100644
index 0000000..a48f845
--- /dev/null
+++ b/FFMpegCore/FFMpeg/Arguments/SubtitleHardBurnArgument.cs
@@ -0,0 +1,132 @@
+using FFMpegCore.Extend;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+
+namespace FFMpegCore.Arguments
+{
+ public class SubtitleHardBurnArgument : IVideoFilterArgument
+ {
+ private readonly SubtitleHardBurnOptions _subtitleHardBurnOptions;
+
+ public SubtitleHardBurnArgument(SubtitleHardBurnOptions subtitleHardBurnOptions)
+ {
+ _subtitleHardBurnOptions = subtitleHardBurnOptions;
+ }
+
+ public string Key => "subtitles";
+
+ public string Value => _subtitleHardBurnOptions.TextInternal;
+ }
+
+ public class SubtitleHardBurnOptions
+ {
+ private readonly string _subtitle;
+
+ public readonly Dictionary Parameters = new Dictionary();
+
+ ///
+ /// Create a new using a provided subtitle file or a video file
+ /// containing one.
+ ///
+ ///
+ ///
+ /// Only support .srt and .ass files, and subrip and ssa subtitle streams
+ public static SubtitleHardBurnOptions Create(string subtitlePath)
+ {
+ return new SubtitleHardBurnOptions(subtitlePath);
+ }
+
+ private SubtitleHardBurnOptions(string subtitle)
+ {
+ _subtitle = subtitle;
+ }
+
+ ///
+ /// Specify the size of the original video, the video for which the ASS file was composed.
+ ///
+ ///
+ ///
+ ///
+ public SubtitleHardBurnOptions SetOriginalSize(int width, int height)
+ {
+ return WithParameter("original_size", $"{width}x{height}");
+ }
+
+ ///
+ /// Specify the size of the original video, the video for which the ASS file was composed.
+ ///
+ ///
+ ///
+ public SubtitleHardBurnOptions SetOriginalSize(Size size)
+ {
+ return SetOriginalSize(size.Width, size.Height);
+ }
+
+ ///
+ /// Set subtitles stream index.
+ ///
+ ///
+ ///
+ ///
+ /// Used when the provided subtitle is an stream of a video file (ex. .mkv) with multiple subtitles.
+ /// Represent the index of the subtitle not the stream, them the first subtitle index is 0 and second is 1
+ ///
+ public SubtitleHardBurnOptions SetSubtitleIndex(int index)
+ {
+ return WithParameter("stream_index", index.ToString());
+ }
+
+ ///
+ /// Set subtitles input character encoding. Only useful if not UTF-8
+ ///
+ /// Charset encoding
+ ///
+ public SubtitleHardBurnOptions SetCharacterEncoding(string encode)
+ {
+ return WithParameter("charenc", encode);
+ }
+
+ ///
+ /// Override default style or script info parameters of the subtitles
+ ///
+ ///
+ ///
+ public SubtitleHardBurnOptions WithStyle(StyleOptions styleOptions)
+ {
+ return WithParameter("force_style", styleOptions.TextInternal);
+ }
+
+ public SubtitleHardBurnOptions WithParameter(string key, string value)
+ {
+ Parameters.Add(key, value);
+ return this;
+ }
+
+ internal string TextInternal => string.Join(":", new[] { _subtitle.EncloseIfContainsSpace() }.Concat(Parameters.Select(parameter => parameter.FormatArgumentPair(enclose: true))));
+ }
+
+ public class StyleOptions
+ {
+ public readonly Dictionary Parameters = new Dictionary();
+
+ public static StyleOptions Create()
+ {
+ return new StyleOptions();
+ }
+
+ ///
+ /// Used to override default style or script info parameters of the subtitles. It accepts ASS style format
+ ///
+ ///
+ ///
+ ///
+ public StyleOptions WithParameter(string key, string value)
+ {
+ Parameters.Add(key, value);
+ return this;
+ }
+
+ internal string TextInternal => string.Join(",", Parameters.Select(parameter => parameter.FormatArgumentPair(enclose: false)));
+ }
+}
\ No newline at end of file
diff --git a/FFMpegCore/FFMpeg/Arguments/VideoFiltersArgument.cs b/FFMpegCore/FFMpeg/Arguments/VideoFiltersArgument.cs
index fa4ae1e..4d0dfde 100644
--- a/FFMpegCore/FFMpeg/Arguments/VideoFiltersArgument.cs
+++ b/FFMpegCore/FFMpeg/Arguments/VideoFiltersArgument.cs
@@ -50,6 +50,7 @@ public class VideoFilterOptions
public VideoFilterOptions Transpose(Transposition transposition) => WithArgument(new TransposeArgument(transposition));
public VideoFilterOptions Mirror(Mirroring mirroring) => WithArgument(new SetMirroringArgument(mirroring));
public VideoFilterOptions DrawText(DrawTextOptions drawTextOptions) => WithArgument(new DrawTextArgument(drawTextOptions));
+ public VideoFilterOptions HardBurnSubtitle(SubtitleHardBurnOptions subtitleHardBurnOptions) => WithArgument(new SubtitleHardBurnArgument(subtitleHardBurnOptions));
private VideoFilterOptions WithArgument(IVideoFilterArgument argument)
{