Spring cleaning your digital music with PowerShell

It’s that time of the year again. I’m helping get a room ready to become the baby’s play room, and part of the tidying up is deciding what to do with all the CDs in there. They’re mostly gathering dust because we listen to music almost exclusively through Zune on the Xbox or PC, so a move to the garage is warranted. At the same time, my friend Bill was talking the other week about his digital music cleanup project. So I cracked out PowerShell and set about doing some scripting with two goals:

  1. Find out if a CD has been ripped
  2. Find out if an album that’s been ripped on the computer has been ripped lossless.

I’m ripping lossless so that I can transcode at will in the future.

Item one is fairly easy because I have been ripping CDs into a hierarchy of Album Artist/Album Name, but two is a little harder. Turns out that getting the codec requires inspecting the file. Rather than write my own parser I just took up the suggestion of Saveen Reddy and used the Windows Media Player library. The extra little bit of work I did was to spelunk around the MSDN Library until I found the appropriate table of GUIDs to constants that enumerates the codec reported back. I just bundled it into a hash table after a bit of copy and paste magic. Was a little easier than trying to generate the list from the Windows SDK.

Finally, I drop the hash table into out-gridview which (for free!) gives me a lovely little form with free text search that lets me query the title or artist as I pull the cd to see if it’s been ripped, or needs to be re-ripped.

 

# Based on some code from http://blogs.msdn.com/b/saveenr/archive/2006/07/09/661036.aspx

# from http://msdn.microsoft.com/en-us/library/dd757532(VS.85).aspx
# List of GUIDs and types for the "AudioFormat" Attribute
# More info: http://msdn.microsoft.com/en-us/library/dd743121(VS.85).aspx
#            http://msdn.microsoft.com/en-us/library/aa372553(VS.85).aspx

# Create an COM/.NET interop stub for the Windows Media Player Library
'C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\TlbImp.exe' %SystemRoot%\system32\wmp.dll /out:WMPLib-Interop.dll                     
$assemblyInfo = [System.Reflection.Assembly]::LoadFrom((Resolve-Path .\WMPLib-Interop.dll))
$wmp = New-Object WMPLib.WindowsMediaPlayerClass                                                                  

# Hashtable of GUID -> codec information
& .\mediaGuidsHashTable.ps1
# Hashtable for albums
$albums = @{}
$pathToMusic = "Insert your music library root path here"
gci -include "*.wma", "*.mp3", "*.m4a" -recurse -path $pathToMusic  | foreach {
  $wmpMedia = $wmp.newMedia($($_.FullName))
  # Lookup the album from the metadata in the hashtable
  if ($albums[$($wmpMedia.getItemInfo("AlbumArtist") + "|" + $wmpMedia.getItemInfo("Album"))] -eq $null) {
    $albums[$($wmpMedia.getItemInfo("AlbumArtist") + "|" + $wmpMedia.getItemInfo("Album"))] = $mediaGuid[$wmpMedia.getItemInfo("AudioFormat")]
  }
}
$albums | out-gridview

Here is the Hashtable of GUIDs to Codecs

(Text file, rename PS1 or copy and paste into your shell)


About this entry