Skip Ribbon Commands
Skip to main content

Quick Launch

Todd Klindt's home page > Todd Klindt's Office 365 Admin Blog > Posts > Using PowerShell to edit MP3 tags
January 24
Using PowerShell to edit MP3 tags

As most of you know, I do a wildly successfully weekly SharePoint Netcast. Not only am I the star, I’m also the writer, director, producer, and janitor. As the years have gone by I’ve tried to improve the Netcast, but that almost always means I spend more time producing it. Because of that I’ve tried automate as much of the production as I can. One  piece of that is putting all the tags on the MP3 files. The program I use to produce my Netcast, Camtasia, is fantastic, absolutely fantastic. But it doesn’t tag the MP3 files it produces. Windows will let you manually tag the text fields of an MP3 file in Explorer, but you can’t add cover art that way. I’m way too pretty to not be on the cover art of my MP3. So I have had to import the MP3 into Windows Media Player and add the cover art that way. Awfully labor intensive. I’m way too lazy for all that. Time to bring out the big guns, PowerShell.

I spent some time trying to find a way to edit MP3 tags in PowerShell natively. I was surprised that I couldn’t find one. Fortunately PowerShell can wedge its way into all kinds of places. I was able to find a library, Taglib, that did the job. It allowed me to easily add both the text and picture information I needed. Here’s roughly the code I used to tag the MP3 for Netcast 185.

# Load the assembly. I used a relative path so I could off using the Resolve-Path cmdlet
[Reflection.Assembly]::LoadFrom( (Resolve-Path "..\Common\taglib-sharp.dll"))

# Load up the MP3 file. Again, I used a relative path, but an absolute path works too
$media = [TagLib.File]::Create((resolve-path ".\Netcast 185 - Growing Old with Todd.mp3"))

# set the tags
$media.Tag.Album = "Todd Klindt's SharePoint Netcast"
$media.Tag.Year = "2014"
$media.Tag.Title = "Netcast 185 - Growing Old with Todd"
$media.Tag.Track = "185"
$media.Tag.AlbumArtists = "Todd Klindt"
$media.Tag.Comment = "http://www.toddklindt.com/blog"

# Load up the picture and set it
$pic = [taglib.picture]::createfrompath("c:\Dropbox\Netcasts\Todd Netcast 1 - 480.jpg")
$media.Tag.Pictures = $pic

# Save the file back
$media.Save()

I’m only setting a few properties, but there are many more. To get the full list of properties you can get and set, issue this command:

$media.tag | Get-Member

Most, but not all, of the properties can be written to. Here are a couple of properties to compare:

Grouping                   Property   string Grouping {get;set;}
IsEmpty                    Property   bool IsEmpty {get;}

Properties with only a “get” in their definition, like “IsEmpty” are read-only. You can only get them. Properties that have both “get” and “set,” like “Grouping” are read and write. That’s not something that’s specific to taglib or MP3 files, that’s a PowerShell thing.

Once you’ve set whichever properties you want to set, use the .Save() method to write those changes back to your MP3 file. I’m using this weekly to tag a single file, but this could just as easily be used to bulk tag (or retag) MP3s, or move MP3s around based on information in their properties.

Enjoy. Leave a comment below if you use this in an interesting way.

tk

ShortURL: http://www.toddklindt.com/MP3TagswithPowerShell

Comments

Re: Using PowerShell to edit MP3 tags

While definitely a fun way to edit MP3 Tags, but I would gladly use a readily available tool such as MP3Tag: http://www.mp3tag.de/en/ . But again: Again interesting how one can use just any DLL inside PowerShell and move away from small console applications.
 on 1/26/2014 6:57 AM

Awesome Article

Thanks for posting this - it will come in useful one day!
 on 1/27/2014 9:02 PM

Helped organize files from multiple sources -- Thanks

I used it to mass-change the Album name of a collection of songs I wanted to keep associated as the collection rather than the albums they came from (but I kept that information in the Comments tag)
 on 3/9/2014 2:31 PM

Add Props?

Can you use this assembly to write new properties? For instance I am using the itunes object to pull play count and I would love to add that property directly to the file.
 on 4/17/2014 3:11 PM

Need to save a TAG into a parameter

Is there any way to pull the string from a tag, then save it into a parameter??

# Load the assembly. I used a relative path so I could off using the Resolve-Path cmdlet
[Reflection.Assembly]::LoadFrom( (Resolve-Path "\\MyPath\taglib-sharp.dll"))

# Load up the MP3 file. Again, I used a relative path, but an absolute path works too
$media = [TagLib.File]::Create((resolve-path ".\MyMP3File.mp3"))

$year = $media.Tag.Year //does not work

Basically, my iTunes Library is messed up, iTunes cannot read the tags on the files, but Windows explorer can see them just fine.  This has caused over 1000 songs to be dropped into the "UNKOWN" Category for Album and Artist, which has also broken many of the links for our play lists.  If I manually edit them and simply replace the existing text and save the file, it works fine.  But I have over 1000 songs with this problem and I would really like to script it.  All I need to do is read the tag into a variable, then set the variable with the tag and it will work.

Any Ideas?
 on 9/10/2014 11:44 PM

Couldn't get Taglib to work

I am interested to know what version of the library you used and whether there were any other steps you needed to perform that you didn't mention in the article.  I can't get the library to work for me.  Here is a quick rundown of what I did; I'm curious to know how that differed from your process.  I'm running Windows 8.1 running PowerShell v. 4.0, and CLRVersion 4.0.30319.34014.

I downloaded the files for 2.1.0.0, which is the most recent version, and saved to c:\temp and then attempted to run just the first line alone:

[Reflection.Assembly]::LoadFrom( 'c:\temp\taglib\taglib-sharp.dll')

But I get the following error:

Exception calling "LoadFrom" with "1" argument(s): "Could not load file or assembly 'file:///C:\temp\taglib\taglib-sharp.dll' or one of its dependencies. Operation is not
supported. (Exception from HRESULT: 0x80131515)"

So then I tried:

Add-Type -Path C:\temp\taglib\src\TagLib\tag.cs

and I get the following error:

Add-Type : c:\temp\taglib\src\TagLib\Tag.cs(851) : The type or namespace name 'IPicture' could not be found (are you missing a using directive or an assembly reference?)

I don't have VS installed on this machine but I did take a look at the .cs files and everything looks correct.

Hopefully you see something obvious.  I appreciate the article.

  
 on 3/8/2015 10:13 PM

Error loading assembly

I had the error as the previous comment and found that Windows had blocked the file. Browsing to the file location (C:\Temp\taglib-sharp.dll in my case) and then right-click, "Unblock" fixed it for me.

Hope that helps anyone else in the same boat.
 on 3/16/2015 1:13 PM

Alter Script to Automate Import From CSV

Hopefully someone can kindly help me out with modifying Todd's script to modify/update tags by reading file names and new tag data from a csv. Basically what I've done to this point, is export current MP3 file information to a csv. I've edited the csv to contain the desired metadata. i.e. Album, Artist, Year etc. the csv also contains the name of the file complete with file path. i.e. c:\mymusic\myalbum\mysong.mp3.  So what I want to do is import the csv, read the "Name" field which as the path and file name, and then set the other tag properties from the csv. i.e. $Media.Tag.property = 'value'.  the problems I'm having are like input object cannot be bound to parameters, does not take pipeline input, and empty pipeline not allowed.
Obviously I'm not experienced in PS to any moderate degree even. So any assistance is greatly appreciated.
in short, my main goals is to read the correct tag properties from the csv, and apply those tags to the correct file, without having to individually change the above script to the individual file and individual properties.

thanks again
 on 6/17/2015 1:27 AM

Alter Script to Automate Import From CSV

Hopefully someone can kindly help me out with modifying Todd's script to modify/update tags by reading file names and new tag data from a csv. Basically what I've done to this point, is export current MP3 file information to a csv. I've edited the csv to contain the desired metadata. i.e. Album, Artist, Year etc. the csv also contains the name of the file complete with file path. i.e. c:\mymusic\myalbum\mysong.mp3.  So what I want to do is import the csv, read the "Name" field which as the path and file name, and then set the other tag properties from the csv. i.e. $Media.Tag.property = 'value'.  the problems I'm having are like input object cannot be bound to parameters, does not take pipeline input, and empty pipeline not allowed.
Obviously I'm not experienced in PS to any moderate degree even. So any assistance is greatly appreciated.
in short, my main goals is to read the correct tag properties from the csv, and apply those tags to the correct file, without having to individually change the above script to the individual file and individual properties.

thanks again
 on 6/18/2015 12:09 AM

One-liner for every media file in a folder

Thanks for this writeup!

I was having some trouble with Resovle-Path because my files are located on an SMB share. Turns out that feeding the .FullName property into the TagSharp Create() function was the way to go.

Since I wanted to work on a set of a dozen or so FLAC files, I loaded the assembly as in your instructions above, then I came up with this one-liner to modify them. For setting each .flac file's Year tag to 2006, it works like this:

Get-ChildItem -Filter *.flac | ForEach-Object { [TagLib.File]::Create($_.FullName) | ForEach-Object { $_.tag.Year = 2006 ; $_.Save() } }

Run that line after CD'ing into your target directory, or feed the target directory into the initial call to Get-ChildItem.
 on 7/13/2016 6:16 AM
1 - 10Next

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

Title


Body *


Today's date *

Select a date from the calendar.
Please enter today's date so I know you are a real person

Twitter


Want a message when I reply to your comment? Put your Twitter handle here.

Attachments

 

 SysKit