Skip to content

Instantly share code, notes, and snippets.

@Manuel-S
Created December 2, 2021 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Manuel-S/37fb8f84e8d5f86d8a266f536c9e0610 to your computer and use it in GitHub Desktop.
Save Manuel-S/37fb8f84e8d5f86d8a266f536c9e0610 to your computer and use it in GitHub Desktop.
Read tags set by windows 10 explorer on audio files using taglib nuget package
/// DISCLAIMER: This is a hacky reverse engineering, I have no idea what the actual syntax is or how it works
/// will probably break in some cases, but so far has worked for a couple hundred different files for me
/// Line 27 is a sanity check for this hack, if you use special characters in your tags it will alert you
using System;
using System.Linq;
using System.Collections.Generic;
using TagLib;
static class AudioFileTagReader
{
static readonly string[] allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 äöüÄÖÜ!?:".ToArray();
static IEnumerable<string> getCategories(TagLib.File file)
{
var ubox = (List<TagLib.Mpeg4.IsoUserDataBox>)file.GetType().GetProperty("UdtaBoxes", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(file);
return getCategories(ubox, file.Name);
}
static IEnumerable<string> getCategories(List<TagLib.Mpeg4.IsoUserDataBox> userDataBoxes, string filename)
{
foreach (var dbox in userDataBoxes)
foreach (var result in recursiveExplore(dbox))
{
if(Debugger.IsAttached)
{
if(result.Any(x => !allowed.Contains(x)))
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Suspicious Tag in File {filename}: {result}");
Console.ResetColor();
}
}
yield return result;
}
}
static IEnumerable<string> recursiveExplore(TagLib.Mpeg4.Box box)
{
if (box.Data != null)
{
if (box.BoxType == (ReadOnlyByteVector)"Xtra")
{
var category = box.Data.ToString(TagLib.StringType.Latin1);
var items = category.Split(new[] { /*"\u0010"*/ "\0\b" }, StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
foreach (var item in items)
{
string local = item;
var end = item.IndexOf("\0\0\0\0\0\0");
if (end != -1)
{
local = local.Substring(0, end);
}
local = local.Replace("\u0010", "").Replace("\u001c", "").Replace("\0", "").Replace("\b", "");
if (local.StartsWith("("))
local = local.Substring(1);
if (local.EndsWith("("))
local = local.Substring(0, local.Length - 1);
if (!string.IsNullOrWhiteSpace(local))
yield return local.Trim();
}
}
}
if (box.HasChildren)
foreach (var child in box.Children)
foreach (var result in recursiveExplore(child))
yield return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment