mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
commit
7de7a67623
5 changed files with 80 additions and 6 deletions
|
@ -341,7 +341,22 @@ public void Builder_BuildString_SubtitleHardBurnFilter()
|
||||||
.WithParameter("PrimaryColour", "&HAA00FF00")))))
|
.WithParameter("PrimaryColour", "&HAA00FF00")))))
|
||||||
.Arguments;
|
.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\"",
|
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_SubtitleHardBurnFilterFixedPaths()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output.mp4", false, opt => opt
|
||||||
|
.WithVideoFilters(filterOptions => filterOptions
|
||||||
|
.HardBurnSubtitle(SubtitleHardBurnOptions
|
||||||
|
.Create(subtitlePath: @"sample( \ : [ ] , ' ).srt"))))
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(@"-i ""input.mp4"" -vf ""subtitles='sample( \\ \: \[ \] \, '\\\'' ).srt'"" ""output.mp4""",
|
||||||
str);
|
str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ internal static class KeyValuePairExtensions
|
||||||
public static string FormatArgumentPair(this KeyValuePair<string, string> pair, bool enclose)
|
public static string FormatArgumentPair(this KeyValuePair<string, string> pair, bool enclose)
|
||||||
{
|
{
|
||||||
var key = pair.Key;
|
var key = pair.Key;
|
||||||
var value = enclose ? pair.Value.EncloseIfContainsSpace() : pair.Value;
|
var value = enclose ? StringExtensions.EncloseIfContainsSpace(pair.Value) : pair.Value;
|
||||||
|
|
||||||
return $"{key}={value}";
|
return $"{key}={value}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,70 @@
|
||||||
namespace FFMpegCore.Extend
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Extend
|
||||||
{
|
{
|
||||||
internal static class StringExtensions
|
internal static class StringExtensions
|
||||||
{
|
{
|
||||||
|
private static Dictionary<char, string> CharactersSubstitution { get; } = new Dictionary<char, string>
|
||||||
|
{
|
||||||
|
{ '\\', @"\\" },
|
||||||
|
{ ':', @"\:" },
|
||||||
|
{ '[', @"\[" },
|
||||||
|
{ ']', @"\]" },
|
||||||
|
{ '\'', @"'\\\''" }
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enclose string between quotes if contains an space character
|
/// Enclose string between quotes if contains an space character
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input">The input</param>
|
/// <param name="input">The input</param>
|
||||||
/// <returns>The enclosed string</returns>
|
/// <returns>The enclosed string</returns>
|
||||||
public static string EncloseIfContainsSpace(this string input)
|
public static string EncloseIfContainsSpace(string input)
|
||||||
{
|
{
|
||||||
return input.Contains(" ") ? $"'{input}'" : input;
|
return input.Contains(" ") ? $"'{input}'" : input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enclose an string in quotes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string EncloseInQuotes(string input)
|
||||||
|
{
|
||||||
|
return $"'{input}'";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scape several characters in subtitle path used by FFmpeg
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is needed because internally FFmpeg use Libav Filters
|
||||||
|
/// and the info send to it must be in an specific format
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <returns>Scaped path</returns>
|
||||||
|
public static string ToFFmpegLibavfilterPath(string source)
|
||||||
|
{
|
||||||
|
return source.Replace(CharactersSubstitution);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Replace(this string str, Dictionary<char, string> replaceList)
|
||||||
|
{
|
||||||
|
var parsedString = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var l in str)
|
||||||
|
{
|
||||||
|
if (replaceList.ContainsKey(l))
|
||||||
|
{
|
||||||
|
parsedString.Append(replaceList[l]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parsedString.Append(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedString.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -103,7 +103,9 @@ public SubtitleHardBurnOptions WithParameter(string key, string value)
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string TextInternal => string.Join(":", new[] { _subtitle.EncloseIfContainsSpace() }.Concat(Parameters.Select(parameter => parameter.FormatArgumentPair(enclose: true))));
|
internal string TextInternal => string
|
||||||
|
.Join(":", new[] { StringExtensions.EncloseInQuotes(StringExtensions.ToFFmpegLibavfilterPath(_subtitle)) }
|
||||||
|
.Concat(Parameters.Select(parameter => parameter.FormatArgumentPair(enclose: true))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StyleOptions
|
public class StyleOptions
|
||||||
|
|
|
@ -116,7 +116,9 @@ private static (FFMpegArguments, Action<FFMpegArgumentOptions> outputOptions) Bu
|
||||||
{
|
{
|
||||||
captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3);
|
captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3);
|
||||||
size = PrepareSnapshotSize(source, size);
|
size = PrepareSnapshotSize(source, size);
|
||||||
streamIndex = streamIndex == null ? 0 : source.VideoStreams.FirstOrDefault(videoStream => videoStream.Index == streamIndex).Index;
|
streamIndex ??= source.PrimaryVideoStream?.Index
|
||||||
|
?? source.VideoStreams.FirstOrDefault()?.Index
|
||||||
|
?? 0;
|
||||||
|
|
||||||
return (FFMpegArguments
|
return (FFMpegArguments
|
||||||
.FromFileInput(input, false, options => options
|
.FromFileInput(input, false, options => options
|
||||||
|
|
Loading…
Reference in a new issue