Merge pull request #260 from alex6dj/fix/subtitle-hardburning-path-scape

Fixed error when burning subtitle with some special charaters in path

Former-commit-id: ce18f3b2ed
This commit is contained in:
Malte Rosenbjerg 2021-10-21 20:38:21 +02:00 committed by GitHub
commit 466d0c6cad
4 changed files with 77 additions and 5 deletions

View file

@ -341,7 +341,22 @@ public void Builder_BuildString_SubtitleHardBurnFilter()
.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\"",
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);
}

View file

@ -16,7 +16,7 @@ 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;
var value = enclose ? StringExtensions.EncloseIfContainsSpace(pair.Value) : pair.Value;
return $"{key}={value}";
}

View file

@ -1,15 +1,70 @@
namespace FFMpegCore.Extend
using System.Collections.Generic;
using System.Text;
namespace FFMpegCore.Extend
{
internal static class StringExtensions
{
private static Dictionary<char, string> CharactersSubstitution { get; } = new Dictionary<char, string>
{
{ '\\', @"\\" },
{ ':', @"\:" },
{ '[', @"\[" },
{ ']', @"\]" },
{ '\'', @"'\\\''" }
};
/// <summary>
/// Enclose string between quotes if contains an space character
/// </summary>
/// <param name="input">The input</param>
/// <returns>The enclosed string</returns>
public static string EncloseIfContainsSpace(this string input)
public static string EncloseIfContainsSpace(string 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();
}
}
}

View file

@ -103,7 +103,9 @@ public SubtitleHardBurnOptions WithParameter(string key, string value)
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