mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
parent
a74866c08a
commit
dd2bfac840
5 changed files with 123 additions and 7 deletions
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FFMpegCore.Test
|
namespace FFMpegCore.Test
|
||||||
|
@ -50,5 +52,29 @@ public void TestMetaDataBuilderIntegrity()
|
||||||
Assert.IsTrue(serialized.Contains("title=Chapter 01", StringComparison.OrdinalIgnoreCase));
|
Assert.IsTrue(serialized.Contains("title=Chapter 01", StringComparison.OrdinalIgnoreCase));
|
||||||
Assert.IsTrue(serialized.Contains("album_artist=Pachelbel", StringComparison.OrdinalIgnoreCase));
|
Assert.IsTrue(serialized.Contains("album_artist=Pachelbel", StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestMapMetadata()
|
||||||
|
{
|
||||||
|
//-i "whaterver0" // index: 0
|
||||||
|
//-f concat -safe 0
|
||||||
|
//-i "\AppData\Local\Temp\concat_b511f2bf-c4af-4f71-b9bd-24d706bf4861.txt" // index: 1
|
||||||
|
//-i "\AppData\Local\Temp\metadata_210d3259-3d5c-43c8-9786-54b5c414fa70.txt" // index: 2
|
||||||
|
//-map_metadata 2
|
||||||
|
|
||||||
|
var text0 = FFMpegArguments.FromFileInput("whaterver0")
|
||||||
|
.AddMetaData("WhatEver3")
|
||||||
|
.Text;
|
||||||
|
|
||||||
|
var text1 = FFMpegArguments.FromFileInput("whaterver0")
|
||||||
|
.AddDemuxConcatInput(new[] { "whaterver", "whaterver1" })
|
||||||
|
.AddMetaData("WhatEver3")
|
||||||
|
.Text;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Assert.IsTrue(Regex.IsMatch(text0, "metadata_[0-9a-f-]+\\.txt\" -map_metadata 1"), "map_metadata index is calculated incorrectly.");
|
||||||
|
Assert.IsTrue(Regex.IsMatch(text1, "metadata_[0-9a-f-]+\\.txt\" -map_metadata 2"), "map_metadata index is calculated incorrectly.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFMpegCore.Extend
|
namespace FFMpegCore.Extend
|
||||||
|
@ -66,5 +67,51 @@ public static string Replace(this string str, Dictionary<char, string> replaceLi
|
||||||
|
|
||||||
return parsedString.ToString();
|
return parsedString.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Counts the number of occurrences of the specified substring within
|
||||||
|
/// the current string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s">The current string.</param>
|
||||||
|
/// <param name="substring">The substring we are searching for.</param>
|
||||||
|
/// <param name="aggressiveSearch">Indicates whether or not the algorithm
|
||||||
|
/// should be aggressive in its search behavior (see Remarks). Default
|
||||||
|
/// behavior is non-aggressive.</param>
|
||||||
|
/// <remarks>This algorithm has two search modes - aggressive and
|
||||||
|
/// non-aggressive. When in aggressive search mode (aggressiveSearch =
|
||||||
|
/// true), the algorithm will try to match at every possible starting
|
||||||
|
/// character index within the string. When false, all subsequent
|
||||||
|
/// character indexes within a substring match will not be evaluated.
|
||||||
|
/// For example, if the string was 'abbbc' and we were searching for
|
||||||
|
/// the substring 'bb', then aggressive search would find 2 matches
|
||||||
|
/// with starting indexes of 1 and 2. Non aggressive search would find
|
||||||
|
/// just 1 match with starting index at 1. After the match was made,
|
||||||
|
/// the non aggressive search would attempt to make it's next match
|
||||||
|
/// starting at index 3 instead of 2.</remarks>
|
||||||
|
/// <returns>The count of occurrences of the substring within the string.</returns>
|
||||||
|
public static int CountOccurrences(this string s, string substring,
|
||||||
|
bool aggressiveSearch = false)
|
||||||
|
{
|
||||||
|
// if s or substring is null or empty, substring cannot be found in s
|
||||||
|
if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(substring))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// if the length of substring is greater than the length of s,
|
||||||
|
// substring cannot be found in s
|
||||||
|
if (substring.Length > s.Length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int count = 0, n = 0;
|
||||||
|
while ((n = s.IndexOf(substring, n, StringComparison.InvariantCulture)) != -1)
|
||||||
|
{
|
||||||
|
if (aggressiveSearch)
|
||||||
|
n++;
|
||||||
|
else
|
||||||
|
n += substring.Length;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
14
FFMpegCore/FFMpeg/Arguments/IDynamicArgument.cs
Normal file
14
FFMpegCore/FFMpeg/Arguments/IDynamicArgument.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments
|
||||||
|
{
|
||||||
|
public interface IDynamicArgument
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Same as <see cref="IArgument.Text"/>, but this receives the arguments generated before as parameter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string GetText(StringBuilder context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,15 @@
|
||||||
using System;
|
using FFMpegCore.Extend;
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FFMpegCore.Arguments
|
namespace FFMpegCore.Arguments
|
||||||
{
|
{
|
||||||
public class MetaDataArgument : IInputArgument
|
public class MetaDataArgument : IInputArgument, IDynamicArgument
|
||||||
{
|
{
|
||||||
private readonly string _metaDataContent;
|
private readonly string _metaDataContent;
|
||||||
private readonly string _tempFileName = Path.Combine(GlobalFFOptions.Current.TemporaryFilesFolder, $"metadata_{Guid.NewGuid()}.txt");
|
private readonly string _tempFileName = Path.Combine(GlobalFFOptions.Current.TemporaryFilesFolder, $"metadata_{Guid.NewGuid()}.txt");
|
||||||
|
@ -15,7 +19,7 @@ public MetaDataArgument(string metaDataContent)
|
||||||
_metaDataContent = metaDataContent;
|
_metaDataContent = metaDataContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text => $"-i \"{_tempFileName}\" -map_metadata 1";
|
public string Text => GetText(null);
|
||||||
|
|
||||||
public Task During(CancellationToken cancellationToken = default) => Task.CompletedTask;
|
public Task During(CancellationToken cancellationToken = default) => Task.CompletedTask;
|
||||||
|
|
||||||
|
@ -23,5 +27,12 @@ public MetaDataArgument(string metaDataContent)
|
||||||
public void Pre() => File.WriteAllText(_tempFileName, _metaDataContent);
|
public void Pre() => File.WriteAllText(_tempFileName, _metaDataContent);
|
||||||
|
|
||||||
public void Post() => File.Delete(_tempFileName);
|
public void Post() => File.Delete(_tempFileName);
|
||||||
|
|
||||||
|
public string GetText(StringBuilder context)
|
||||||
|
{
|
||||||
|
var index = context.ToString().CountOccurrences("-i");
|
||||||
|
|
||||||
|
return $"-i \"{_tempFileName}\" -map_metadata {index}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using FFMpegCore.Arguments;
|
using FFMpegCore.Arguments;
|
||||||
using FFMpegCore.Builders.MetaData;
|
using FFMpegCore.Builders.MetaData;
|
||||||
using FFMpegCore.Pipes;
|
using FFMpegCore.Pipes;
|
||||||
|
@ -16,7 +18,23 @@ public sealed class FFMpegArguments : FFMpegArgumentsBase
|
||||||
|
|
||||||
private FFMpegArguments() { }
|
private FFMpegArguments() { }
|
||||||
|
|
||||||
public string Text => string.Join(" ", _globalArguments.Arguments.Concat(Arguments).Select(arg => arg.Text));
|
public string Text => GetText();
|
||||||
|
|
||||||
|
private string GetText()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var arg in _globalArguments.Arguments.Concat(Arguments))
|
||||||
|
{
|
||||||
|
if (sb.Length != 0)
|
||||||
|
{
|
||||||
|
sb.Append(' ');
|
||||||
|
}
|
||||||
|
sb.Append(arg is IDynamicArgument dynArg ? dynArg.GetText(sb) : arg.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
public static FFMpegArguments FromConcatInput(IEnumerable<string> filePaths, Action<FFMpegArgumentOptions>? addArguments = null) => new FFMpegArguments().WithInput(new ConcatArgument(filePaths), addArguments);
|
public static FFMpegArguments FromConcatInput(IEnumerable<string> filePaths, Action<FFMpegArgumentOptions>? addArguments = null) => new FFMpegArguments().WithInput(new ConcatArgument(filePaths), addArguments);
|
||||||
public static FFMpegArguments FromDemuxConcatInput(IEnumerable<string> filePaths, Action<FFMpegArgumentOptions>? addArguments = null) => new FFMpegArguments().WithInput(new DemuxConcatArgument(filePaths), addArguments);
|
public static FFMpegArguments FromDemuxConcatInput(IEnumerable<string> filePaths, Action<FFMpegArgumentOptions>? addArguments = null) => new FFMpegArguments().WithInput(new DemuxConcatArgument(filePaths), addArguments);
|
||||||
|
|
Loading…
Reference in a new issue