Added MetadataBuilder

This commit is contained in:
Weirdo 2021-12-21 00:34:33 +01:00
parent e3eb2f2056
commit 2605ac1a54
7 changed files with 209 additions and 0 deletions

View file

@ -0,0 +1,18 @@
using System;
namespace FFMpegCore.Builders.MetaData
{
public class ChapterData
{
public string Title { get; private set; }
public TimeSpan Start { get; private set; }
public TimeSpan End { get; private set; }
public ChapterData(string title, TimeSpan start, TimeSpan end)
{
Title = title;
Start = start;
End = end;
}
}
}

View file

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace FFMpegCore.Builders.MetaData
{
public interface IReadOnlyMetaData
{
IReadOnlyList<ChapterData> Chapters { get; }
IReadOnlyDictionary<string, string> Entries { get; }
}
}

View file

@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Linq;
namespace FFMpegCore.Builders.MetaData
{
public class MetaData : IReadOnlyMetaData
{
public Dictionary<string, string> Entries { get; private set; }
public List<ChapterData> Chapters { get; private set; }
IReadOnlyList<ChapterData> IReadOnlyMetaData.Chapters => this.Chapters;
IReadOnlyDictionary<string, string> IReadOnlyMetaData.Entries => this.Entries;
public MetaData()
{
Entries = new Dictionary<string, string>();
Chapters = new List<ChapterData>();
}
public MetaData(MetaData cloneSource)
{
Entries = new Dictionary<string, string>(cloneSource.Entries);
Chapters = cloneSource.Chapters
.Select(x => new ChapterData
(
start: x.Start,
end: x.End,
title: x.Title
))
.ToList();
}
}
}

View file

@ -0,0 +1,82 @@
using System;
using System.Linq;
namespace FFMpegCore.Builders.MetaData
{
public class MetaDataBuilder
{
private MetaData _metaData = new MetaData();
public MetaDataBuilder WithEntry(string key, string value)
{
_metaData.Entries[key] = value;
return this;
}
public MetaDataBuilder AddChapter(ChapterData chapterData)
{
_metaData.Chapters.Add(chapterData);
return this;
}
public MetaDataBuilder AddChapter(TimeSpan duration, string? title = null)
{
var start = _metaData.Chapters.LastOrDefault()?.End ?? TimeSpan.Zero;
var end = start + duration;
title = String.IsNullOrEmpty(title) ? $"Chapter {_metaData.Chapters.Count + 1}" : title;
_metaData.Chapters.Add(new ChapterData
(
start: start,
end: end,
title: title
));
return this;
}
//major_brand=M4A
public MetaDataBuilder WithMajorBrand(string value) => WithEntry("major_brand", value);
//minor_version=512
public MetaDataBuilder WithMinorVersion(string value) => WithEntry("minor_version", value);
//compatible_brands=M4A isomiso2
public MetaDataBuilder WithCompatibleBrands(string value) => WithEntry("compatible_brands", value);
//copyright=©2017 / 2019 Dennis E. Taylor / Random House Audio / Wilhelm Heyne Verlag. Übersetzung von Urban Hofstetter (P)2019 Random House Audio
public MetaDataBuilder WithCopyright(string value) => WithEntry("copyright", value);
//title=Alle diese Welten: Bobiverse 3
public MetaDataBuilder WithTitle(string value) => WithEntry("title", value);
//artist=Dennis E. Taylor
public MetaDataBuilder WithArtist(string value) => WithEntry("artist", value);
//composer=J. K. Rowling
public MetaDataBuilder WithComposer(string value) => WithEntry("composer", value);
//album_artist=Dennis E. Taylor
public MetaDataBuilder WithAlbumArtist(string value) => WithEntry("album_artist", value);
//album=Alle diese Welten: Bobiverse 3
public MetaDataBuilder WithAlbum(string value) => WithEntry("album", value);
//date=2019
public MetaDataBuilder WithDate(string value) => WithEntry("date", value);
//genre=Hörbuch
public MetaDataBuilder WithGenre(string value) => WithEntry("genre", value);
//comment=Chapter 200
public MetaDataBuilder WithComment(string value) => WithEntry("comment", value);
//encoder=Lavf58.47.100
public MetaDataBuilder WithEncoder(string value) => WithEntry("encoder", value);
public ReadOnlyMetaData Build()
{
return new MetaData(_metaData);
}
}
}

View file

@ -0,0 +1,38 @@
using System.Linq;
using System.Text;
namespace FFMpegCore.Builders.MetaData
{
public class MetaDataSerializer
{
public static readonly MetaDataSerializer Instance = new MetaDataSerializer();
public string Serialize(IReadOnlyMetaData metaData)
{
var sb = new StringBuilder()
.AppendLine(";FFMETADATA1");
foreach (var value in metaData.Entries)
{
sb.AppendLine($"{value.Key}={value.Value}");
}
int chapterNumber = 0;
foreach (var chapter in metaData.Chapters ?? Enumerable.Empty<ChapterData>())
{
chapterNumber++;
var title = string.IsNullOrEmpty(chapter.Title) ? $"Chapter {chapterNumber}" : chapter.Title;
sb
.AppendLine("[CHAPTER]")
.AppendLine($"TIMEBASE=1/1000")
.AppendLine($"START={(int)chapter.Start.TotalMilliseconds}")
.AppendLine($"END={(int)chapter.End.TotalMilliseconds}")
.AppendLine($"title={title}")
;
}
return sb.ToString();
}
}
}

View file

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
namespace FFMpegCore.Builders.MetaData
{
public class ReadOnlyMetaData : IReadOnlyMetaData
{
public IReadOnlyDictionary<string, string> Entries { get; private set; }
public IReadOnlyList<ChapterData> Chapters { get; private set; }
public ReadOnlyMetaData(MetaData metaData)
{
Entries = new Dictionary<string, string>(metaData.Entries);
Chapters = metaData.Chapters
.Select(x => new ChapterData
(
start: x.Start,
end: x.End,
title: x.Title
))
.ToList()
.AsReadOnly();
}
}
}

View file

@ -5,6 +5,7 @@
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.Pipes; using FFMpegCore.Pipes;
namespace FFMpegCore namespace FFMpegCore
@ -39,6 +40,7 @@ public FFMpegArguments WithGlobalOptions(Action<FFMpegGlobalArguments> configure
public FFMpegArguments AddUrlInput(Uri uri, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new InputArgument(uri.AbsoluteUri, false), addArguments); public FFMpegArguments AddUrlInput(Uri uri, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new InputArgument(uri.AbsoluteUri, false), addArguments);
public FFMpegArguments AddPipeInput(IPipeSource sourcePipe, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new InputPipeArgument(sourcePipe), addArguments); public FFMpegArguments AddPipeInput(IPipeSource sourcePipe, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new InputPipeArgument(sourcePipe), addArguments);
public FFMpegArguments AddMetaData(string content, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new MetaDataArgument(content), addArguments); public FFMpegArguments AddMetaData(string content, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new MetaDataArgument(content), addArguments);
public FFMpegArguments AddMetaData(IReadOnlyMetaData metaData, Action<FFMpegArgumentOptions>? addArguments = null) => WithInput(new MetaDataArgument(MetaDataSerializer.Instance.Serialize(metaData)), addArguments);
private FFMpegArguments WithInput(IInputArgument inputArgument, Action<FFMpegArgumentOptions>? addArguments) private FFMpegArguments WithInput(IInputArgument inputArgument, Action<FFMpegArgumentOptions>? addArguments)
{ {