mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
parent
b46fd7b2ad
commit
96ec0613d3
5 changed files with 136 additions and 0 deletions
|
@ -317,6 +317,27 @@ public void Builder_BuildString_DrawtextFilter_Alt()
|
||||||
str);
|
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:si=0:force_style='FontName=DejaVu Serif\\,PrimaryColour=&HAA00FF00'\" \"output.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Builder_BuildString_StartNumber()
|
public void Builder_BuildString_StartNumber()
|
||||||
{
|
{
|
||||||
|
|
15
FFMpegCore/Extend/KeyValuePairExtensions.cs
Normal file
15
FFMpegCore/Extend/KeyValuePairExtensions.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Extend
|
||||||
|
{
|
||||||
|
internal static class KeyValuePairExtensions
|
||||||
|
{
|
||||||
|
public static string FormatArgumentPair(this KeyValuePair<string, string> pair, bool enclose)
|
||||||
|
{
|
||||||
|
var key = pair.Key;
|
||||||
|
var value = enclose ? pair.Value.EncloseIfContainsSpace() : pair.Value;
|
||||||
|
|
||||||
|
return $"{key}={value}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
FFMpegCore/Extend/StringExtensions.cs
Normal file
10
FFMpegCore/Extend/StringExtensions.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace FFMpegCore.Extend
|
||||||
|
{
|
||||||
|
internal static class StringExtensions
|
||||||
|
{
|
||||||
|
public static string EncloseIfContainsSpace(this string input)
|
||||||
|
{
|
||||||
|
return input.Contains(" ") ? $"'{input}'" : input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
FFMpegCore/FFMpeg/Arguments/SubtitleHardBurnArgument.cs
Normal file
89
FFMpegCore/FFMpeg/Arguments/SubtitleHardBurnArgument.cs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
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<string, string> Parameters = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
public static SubtitleHardBurnOptions Create(string subtitlePath)
|
||||||
|
{
|
||||||
|
return new SubtitleHardBurnOptions(subtitlePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SubtitleHardBurnOptions(string subtitle)
|
||||||
|
{
|
||||||
|
_subtitle = subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubtitleHardBurnOptions SetOriginalSize(int width, int height)
|
||||||
|
{
|
||||||
|
return WithParameter("original_size", $"{width}x{height}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubtitleHardBurnOptions SetOriginalSize(Size size)
|
||||||
|
{
|
||||||
|
return SetOriginalSize(size.Width, size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubtitleHardBurnOptions SetSubtitleIndex(int index)
|
||||||
|
{
|
||||||
|
return WithParameter("si", index.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubtitleHardBurnOptions SetCharacterEncoding(string encode)
|
||||||
|
{
|
||||||
|
return WithParameter("charenc", encode);
|
||||||
|
}
|
||||||
|
|
||||||
|
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<string, string> Parameters = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
public static StyleOptions Create()
|
||||||
|
{
|
||||||
|
return new StyleOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,6 +50,7 @@ public class VideoFilterOptions
|
||||||
public VideoFilterOptions Transpose(Transposition transposition) => WithArgument(new TransposeArgument(transposition));
|
public VideoFilterOptions Transpose(Transposition transposition) => WithArgument(new TransposeArgument(transposition));
|
||||||
public VideoFilterOptions Mirror(Mirroring mirroring) => WithArgument(new SetMirroringArgument(mirroring));
|
public VideoFilterOptions Mirror(Mirroring mirroring) => WithArgument(new SetMirroringArgument(mirroring));
|
||||||
public VideoFilterOptions DrawText(DrawTextOptions drawTextOptions) => WithArgument(new DrawTextArgument(drawTextOptions));
|
public VideoFilterOptions DrawText(DrawTextOptions drawTextOptions) => WithArgument(new DrawTextArgument(drawTextOptions));
|
||||||
|
public VideoFilterOptions HardBurnSubtitle(SubtitleHardBurnOptions subtitleHardBurnOptions) => WithArgument(new SubtitleHardBurnArgument(subtitleHardBurnOptions));
|
||||||
|
|
||||||
private VideoFilterOptions WithArgument(IVideoFilterArgument argument)
|
private VideoFilterOptions WithArgument(IVideoFilterArgument argument)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue