Get "initial Key" value from .mp3 file

755 Views Asked by At

I can't find a way to read the "initial key" property from an mp3 file to use the song information in my application.

I've already tried to find libraries which do the job for me. I found TagLib# which is a very cool solution for getting tags/properties of different file formats. (including mp3).

I can use this library to get the title, the artist, the beats per minute and so on.. only the initial key value is missing for my use which isn't featured, unfortunately.

I also tried to find other solutions which support the initial key property but I haven't found one.

I already found a source which seems to address the same issue and solves it with using TagLib#, but I can't figure out how he solved that problem. Use Ctrl + F and search for "Initial" to find the code block. You can find the link here

I'll post a short part of my code which can be used to determine different info about one song in a pattern like this: (["bpm"]"title" - "artist")

    var file = TagLib.File.Create(filePath);
    return $"[{file.Tag.BeatsPerMinute}]{file.Tag.Title} - {file.Tag.FirstPerformer}";

Thanks for any help or recommendations in advance! :)

3

There are 3 best solutions below

2
AudioBubble On BEST ANSWER

Try this:

public static void Main(string[] args)
{
    var path = …
    var file = TagLib.File.Create (path);
    var id3tag = (TagLib.Id3v2.Tag)file.GetTag (TagTypes.Id3v2);
    var key = ReadInitialKey (id3tag);
    Console.WriteLine ("Key = " + key);
}

static string ReadInitialKey(TagLib.Id3v2.Tag id3tag)
{
    var frame = id3tag.GetFrames<TextInformationFrame>().Where (f => f.FrameId == "TKEY").FirstOrDefault();
    return frame.Text.FirstOrDefault() ;
}

On Windows 10 you can also use:

async Task<string> ReadInitialKey(string path)
    {
        StorageFile file = await StorageFile.GetFileFromPathAsync(path);
        Windows.Storage.FileProperties.MusicProperties musicProperties = await file.Properties.GetMusicPropertiesAsync();
        var props = await musicProperties.RetrievePropertiesAsync(null);
        var inkp = props["System.Music.InitialKey"];
        return (string)inkp;
    }

See here for documentation on MusicProperties object and here for the valid music properties.

0
Castorix On

You can use the Shell to read all MP3 properties.

Test on Windows 10, VS 2015 =>

// Add Reference Shell32.DLL
string sFolder = "e:\\";
string sFile= "01. IMANY - Don't Be so Shy (Filatov & Karas Remix).mp3";
List<string> arrProperties = new List<string>();
Shell objShell = new Shell();
Folder objFolder;
objFolder = objShell.NameSpace(sFolder);
int nMaxProperties = 332;
for (int i = 0; i < nMaxProperties; i++)
{
    string sHeader = objFolder.GetDetailsOf(null, i);
    arrProperties.Add(sHeader);
}
FolderItem objFolderItem = objFolder.ParseName(sFile);
if (objFolderItem != null)
{
    for (int i = 0; i < arrProperties.Count; i++)
    {
        Console.WriteLine((i + ('\t' + (arrProperties[i] + (": " + objFolder.GetDetailsOf(objFolderItem, i))))));
    }
}
0
vladimir On

Just borrowing code from nuget: mono TaglibSharp:

var tfile = TagLib.File.Create(@"..");
string initialKey = null;

if (tfile.GetTag(TagTypes.Id3v2) is TagLib.Id3v2.Tag id3v2)
{
    /*
    // test: add custom Initial Key tag 
    var frame = TextInformationFrame.Get(id3v2, "TKEY", true);
    frame.Text = new[] {"qMMM"};
    frame.TextEncoding = StringType.UTF8;
    tfile.Save();
    */

    var frame = TextInformationFrame.Get(id3v2, "TKEY", false);         
    initialKey = frame?.ToString();
}