Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed more metadata in videos and clips #1185

Merged
merged 4 commits into from
Aug 11, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Rename SanitizeKeyValue to EscapeMetadataValue
ScrubN committed Aug 11, 2024
commit 934e0314af34bc279919f45615001d4b39e2ebc0
18 changes: 10 additions & 8 deletions TwitchDownloaderCore/Tools/FfmpegMetadata.cs
Original file line number Diff line number Diff line change
@@ -43,23 +43,23 @@ private static async Task SerializeGlobalMetadata(StreamWriter sw, [AllowNull] s
{
// ReSharper disable once StringLiteralTypo
await sw.WriteLineAsync(";FFMETADATA1");
await sw.WriteLineAsync($"title={SanitizeKeyValue(title)} ({SanitizeKeyValue(id)})");
await sw.WriteLineAsync($"title={EscapeMetadataValue(title)} ({EscapeMetadataValue(id)})");
if (!string.IsNullOrWhiteSpace(streamer))
await sw.WriteLineAsync($"artist={SanitizeKeyValue(streamer)}");
await sw.WriteLineAsync($"artist={EscapeMetadataValue(streamer)}");
await sw.WriteLineAsync($"date={createdAt:yyyy}"); // The 'date' key becomes 'year' in most formats
if (!string.IsNullOrWhiteSpace(game))
await sw.WriteLineAsync($"genre={game}");
await sw.WriteAsync(@"comment=");
if (!string.IsNullOrWhiteSpace(description))
{
// We could use the 'description' key, but so few media players support mp4 descriptions that users would probably think it was missing
await sw.WriteLineAsync(@$"{SanitizeKeyValue(description.TrimEnd())}\");
await sw.WriteLineAsync(@$"{EscapeMetadataValue(description.TrimEnd())}\");
await sw.WriteLineAsync(@"------------------------\");
}
if (!string.IsNullOrWhiteSpace(clipper))
await sw.WriteLineAsync($@"Clipped by: {SanitizeKeyValue(clipper)}\");
await sw.WriteLineAsync(@$"Created at: {SanitizeKeyValue(createdAt.ToString("u"))}\");
await sw.WriteLineAsync(@$"Video id: {SanitizeKeyValue(id)}\");
await sw.WriteLineAsync($@"Clipped by: {EscapeMetadataValue(clipper)}\");
await sw.WriteLineAsync(@$"Created at: {EscapeMetadataValue(createdAt.ToString("u"))}\");
await sw.WriteLineAsync(@$"Video id: {EscapeMetadataValue(id)}\");
await sw.WriteLineAsync(@$"Views: {viewCount}");
}

@@ -102,7 +102,7 @@ private static async Task SerializeChapters(StreamWriter sw, IEnumerable<VideoMo
await sw.WriteLineAsync("TIMEBASE=1/1000");
await sw.WriteLineAsync($"START={startMillis}");
await sw.WriteLineAsync($"END={startMillis + lengthMillis}");
await sw.WriteLineAsync($"title={SanitizeKeyValue(gameName)}");
await sw.WriteLineAsync($"title={EscapeMetadataValue(gameName)}");
}
}

@@ -128,7 +128,9 @@ private static string GetUserName([AllowNull] string displayName, [AllowNull] st
}

// https://trac.ffmpeg.org/ticket/11096 The Ffmpeg documentation is outdated and =;# do not need to be escaped.
private static string SanitizeKeyValue(string str)
// TODO: Use nameof(filename) when C# 11+
[return: NotNullIfNotNull("str")]
private static string EscapeMetadataValue([AllowNull] string str)
{
if (string.IsNullOrWhiteSpace(str))
{
Loading