It’s not polite to ask a techiebird her age, but I’ll tell you that I’m old enough that most of the music I’ve listened to has been albums, not singles. And many of my albums sound better as albums, i.e. played from start to finish in the order the artist intended.
Sometimes I don’t want to have to decide what to listen to. I just want to hear something good and I want to hear all of it. Or sometimes I just like the familiarity of a compilation playing the tracks in the order I expect. So it’s a shame there isn’t a “shuffle albums” feature in any media player hardware I’ve come across, or any of the major software media players.
However, we have PowerShell, Windows Media Player has an object model, and how hard can it be to create a playlist of complete albums anyway?
Actually, harder than I expected. But, helpfully, James O’Neill wrote about the quirks of the WMP Object Model some time ago, which helped a lot. (Definitely read his two posts on scripting for WMP if you’re thinking of doing something similar. They’re written for PowerShell v1 but everything works much the same.)
Anyway, here’s what I came up with (usual disclaimer applies):
1: Function Shuffle-Albums
2: {Param ([int]$NumberOfAlbums, [int]$MinTracks, [int]$MinStars=0)
3:
4: write-host $NumberOfAlbums.tostring() "albums, containing at least" $MinTracks.tostring() "tracks rated at least" $MinStars.tostring() "/5"
5:
6: #Set up objects
7: $wmp=new-object -COM WMPlayer.ocx
8: $all=$wmp.mediacollection
9:
10: #Get the names of all the albums from the track attribute db
11: $albs=$all.getAttributeStringCollection("Album","Audio")
12: $Albums=@()
13: $AlbumNames=@()
14:
15: #Put the album names in an array
16: for ($n=0;$n -lt $albs.count;$n++)
17: {$AlbumNames+=$albs.item($n)}
18:
19: #Step through and put the tracks for each album in a temporary playlist
20: $Albumnames | foreach {
21: $p=$all.getByAlbum($_)
22: if (($p.count -ge $MinTracks) -and ($_ -ne "")) {
23: $p.name = $_
24: $Albums+=$p
25: }
26: }
27:
28: #Pick some random albums
29: $AlbumSet=$Albums|get-random -count $NumberOfAlbums
30:
31: $m=$wmp.mediacollection
32:
33: #If we already created a playlist, delete it
34: if($m.getbyname("Random albums").count -gt 0) {
35: For ($i=0;$i -lt $m.getbyname("Random albums").count;$i++) {
36: $r=$m.getbyname("Random albums").item($i)
37: $rURL=$r.sourceURL
38: $wmp.playlistcollection.remove($r)
39: remove-item $rURL
40: }
41: }
42:
43: #Create our new playlist
44: $PlayList=$wmp.newPlaylist("Random albums","")
45:
46: #Add all our songs to the new playlist, checking they meet the minimum star rating (or haven't been rated)
47: $AlbumSet | foreach {
48: for ($t=0;$t -lt $_.count;$t++){
49: $s=$_.item($t)
50: if(($s.getItemInfo("UserRating") -gt $MinStars-1*25-13) -or $s.getItemInfo("UserRating") -eq 0) {
51: $Playlist.appendItem($s)
52: }
53: }
54: }
55:
56: "Added " + ($playlist.count).tostring() + " items to playlist" | out-host
57:
58: #Write our playlist to a file
59: $wmp.playlistcollection.importplaylist($Playlist) | out-null
60:
61: #Pass back the filename (URL) of our playlist
62: Write-Output $wmp.mediacollection.getbyname("Random albums").item(0).sourceurl
63:
64: $wmp.close | Out-Null
65: $wmp = $null | Out-Null
66:
67: }
68:
69: $url=$null
70: $url=Shuffle-Albums 10 6 3
71:
72: "Playlist saved as " + ($url).tostring() | out-host
73:
74: while ((Get-Item $url).length -le 250) {start-sleep -seconds 5}
75:
76: $Player=new-object -COM WMPlayer.ocx
77: $Player.openPlayer($url)
NumberOfAlbums | How many albums to add to the playlist |
MinTracks | The minimum number of tracks for an album to be considered ‘complete’. (I have singles and other miscellaneous tracks which have album information in WMP, and the database doesn’t have anything to distinguish these from complete albums. This seemed like the easiest way to avoid having one-track ‘albums’ in my playlist. |
MinStars | Counter to my argument for having an album shuffler in the first place, some albums have one or two sucky tracks I prefer to skip over. This parameter gives me the option of giving those tracks a low rating and having them missed out from my playlist. Most of my tracks are unrated, so those always get included. |
I’d quite like to put a UI on this but realistically I may never get round to it. If anyone else wants to have a go then I’m very happy for you to use my code as long as you share the results for free :)
And as always, please let me know in the comments if you spot anything I could fix to make the code better.
No comments:
Post a Comment