Fixed error when burning subtitle with some special charaters in path

This commit is contained in:
alex6dj 2021-10-01 23:34:56 -04:00
parent e6d85eea11
commit e6e07fc2fe
3 changed files with 73 additions and 3 deletions

View file

@ -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);
} }

View file

@ -1,7 +1,19 @@
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>
{
{'\\', @"\\"},
{':', @"\:"},
{'[', @"\["},
{']', @"\]"},
// {'\'', @"\'"} TODO: Quotes need to be escaped but i failed miserably
};
/// <summary> /// <summary>
/// Enclose string between quotes if contains an space character /// Enclose string between quotes if contains an space character
/// </summary> /// </summary>
@ -11,5 +23,48 @@ public static string EncloseIfContainsSpace(this 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(this 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(this 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,7 @@ 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[] { _subtitle.ToFFmpegLibavfilterPath().EncloseInQuotes() }.Concat(Parameters.Select(parameter => parameter.FormatArgumentPair(enclose: true))));
} }
public class StyleOptions public class StyleOptions