Generating 'Recently Added' Playlist with Powershell

No Comments June 23, 2010

A feature that I used to like in Windows Media Player 11 that was dropped in version 12 was the 'Recently Added' view. There is a way to produce an automatic playlist that includes recently added items, but it occurred to me that I use a variety of media players depending on my current whim (sometimes it'll even be a command line instance of mplayer through cygwin) and wouldn't it be great to have an auto-generated 'Recently Added' playlist in a format that any respectable media player would understand - namely M3U.

And besides, I wanted to play around with Powershell.

So, I put together the following Powershell script; something that stumped me for a while was to do with resolving absolute paths to relative paths; my issue was:

resolve-path -relative "E:\Music\Autechre\Quaristice\01 Altibzz.mp3"

would return

.\Autechre\Quaristice\01 Altibzz.mp3

but

resolve-path -relative "E:\Music\Peter Gabriel\Hit Disc 2\14 Downside Up [Live].mp3"

would return absolutely nothing. After returning to the script a few hours later, I realised that the issue was to do with wildcard expansion - Powershell uses '[...]' to match ranges or specified characters (see 'help wildcards' in Powershell). A quick flick through the help pages for resolve-path revealed a '-literalpath' parameter, which means that no wildcard expansion is performed. The following command therefore:

resolve-path -relative -literalpath "E:\Music\Peter Gabriel\Hit Disc 2\14 Downside Up [Live].mp3"

gives

.\Peter Gabriel\Hit Disc 2\14 Downside Up [Live].mp3

as expected.

Just to round things off, I decided to emit extended M3U directives for applications that understand them. I stole the GetMP3MetaData function from Johan Straarup's blog entry which uses an interesting trick by instantiating a Shell.Application COM object and accessing the properties that it exposes on a selected file. From this information I could write out the relevant tag information from the selected files and calculate the length of the file in seconds.

From the Powershell command line, you can run the script as

.\Recently-Added.ps1 | Set-Content "Recently Added.m3u"

By default, it will produce a playlist of MP3 files that were created within the last 14 days; this can be adjusted by specifying the '-Days' parameter. For example, to create a list containing files created within the last 21 days:

.\Recently-Added.ps1 -Days 21

I hope someone finds this useful someday.

#

Recently-Added.ps1

# param([int]$Days = 14) $objShell = New-Object -ComObject Shell.Application

function GetMP3MetaData($path) { $file = split-path $path -leaf $path = split-path $path $objFolder = $objShell.namespace($path) $objFile = $objFolder.parsename($file) $result = @{} 0..266 | % { if ($objFolder.getDetailsOf($objFile, $)) { $result[$($objFolder.getDetailsOf($objFolder.items, $))] = $objFolder.getDetailsOf($objFile, $_) } } return $result }

"#EXTM3U" gci -recurse -include *.mp3 | ? { $_.CreationTime -gt (get-date).AddDays($Days <SPAN style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">*</SPAN> -1) } <SPAN style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">|</SPAN> % { $path = resolve-path -relative -literalpath $.FullName $info = GetMP3MetaData($) $duration = [timespan]$info.Duration "#EXTINF:{0},{1} - {2}" -f $duration.TotalSeconds, $info.Artist, $info.Title $path }

 


No Comments

  • Gravatar Image
    vince April 25, 2012 11:20 AM

    hey i found this really useful! thanks