James O'Neill's Blog

October 21, 2008

PowerShell and Windows Media Player, part 2

Filed under: Uncategorized — jamesone111 @ 11:39 pm

In the previous post on this topic I showed how to get a media player object

$wmp = New-object  –COM WMPlayer.OCX

And introduced functions which worked with its playListCollection, mediaCollection and CurrentPlaylist to implement

Get-media Get-mediaByAttribute

At the end of that piece I introduced



Which use the Controls collection of the media object.  There were 3 other functions which used the controls collection of the Windows Media Player object.

Function Select-nextmedia  {$wmp.controls.Next() } 

Function Select-Previousmedia {$wmp.controls.Next() }

Function Resume-media   {$wmp.controls.play() }

In fact start media was more complicated because I said in my introduction I wanted to set things up so that media would finish at a pre-ordained time, which meant figuring out how long a play list would take to play

filter Get-PlaylistDuration 

{param ($Playlist) if ($playlist -eq $null) {$Playlist = $_}
(Get-Mediainplaylist $PlayList | measure-object -sum duration).sum $playlist = $null

Although you can get the duration without looking at the detailed attributes for each item I wanted to get those too, in an object form which can be used in format-table and the like.

Filter Get-MediaDetails
{param($mediaItem) if ($mediaItem -eq $null) {$mediaItem=$_}
0..($mediaItem.attributeCount -1) |
   foreach -begin {$MediaObj = New-Object -TypeName System.Object } ` -process {$attributeName=$mediaItem.GetattributeName($_) if ($mediaItem.GetitemInfo($attributeName)) {
Add-Member -inputObject $mediaObj -MemberType NoteProperty `
-Name $AttributeName -Value $mediaItem.GetitemInfo($attributeName)}}
-end {$MediaObj}}

I wanted to wait until a particular song was playing and do something or wait till a particular point in the song, or just a particular time.  So that meant 3 more functions

Function Wait-Medianame 

while ($waiting) {
   start-sleep -seconds 1    Write-Progress -Activity $wmp.currentMedia.Name -Status "Waiting for song name to match $name"    $waiting= ($wmp.currentMedia.name  -notlike $name) } }

Function wait-mediaoffset
while ($waiting) {
   start-sleep -seconds 1    Write-Progress -Activity $wmp.currentMedia.Name -Status "Waiting until $seconds - position now : $($wmp.controls.currentPositionString)"    $waiting= ($wmp.controls.currentPosition -lt $seconds) } }

Function wait-until
$TotalTime=($endTime - (Get-date)).totalSeconds
$Waiting=$TotalTime -gt 0
while ($waiting) {
   Write-Progress -Activity ("Counting down to " + (get-Date).toString("t") ) -Status "Waiting" `
-percentcomplete (100 * ((($endTime - (Get-date)).totalSeconds / $totalTime)))
   Start-sleep -seconds 1
   $waiting= ($endtime.compareto((get-date))  -gt 0 ) }

With those in place I could go back to Start-Media and tell it I wanted the music to stop at a particular time, and knowing how long the playlist would play for I could tell it to wait for a particular time. I quite like the way that write progress is setup  so the progress bar retreats to 0 in wait-until

Function Start-media 

{Param ($EndAt)
if ($endAt) {wait-until ([dateTime]$EndAt).addSeconds(-1 * (get-PlayListDuration))}

The only thing left on the music side was to set the volume level, first the simple way, then the a fade up or down. 

Function Set-MediaVolume {Param ($volume); $wmp.settings.volume = $volume} 

function Fade-Media 

{param ($level, $seconds) $steps = ($level - $wmp.settings.volume) if ($steps -gt 0) {   $interval = 1000 * $seconds / $Steps    for(;$wmp.settings.volume -lt $level;$wmp.settings.volume ++) { Write-Progress -Activity $wmp.currentMedia.Name -Status "Fading in " `
   -PercentComplete (100 * (1 -  ($level - $wmp.settings.volume )/$Steps)) start-Sleep -milliseconds $interval} } if ($steps -lt 0) { $interval = -1000 * $seconds / $Steps    for(;$wmp.settings.volume -gt $level;$wmp.settings.volume –) {
Write-Progress -Activity $wmp.currentMedia.Name -Status "Fading Out" 
-PercentComplete (100 *  ($level - $wmp.settings.volume) / $steps ) start-Sleep -milliseconds $interval} }

That took care of just about everything – except that for video it is necessary to launch a full media player window instead of just using the object. Fortunately that is a method on the main object so that got coded up as well. Job done. 

Filter Launch-media

{Param ($file);
if ($File -eq $null) {$file=$_}
   if   ($File -is [string])  {$wmp.openplayer($file) }
   else {$wmp.openplayer($file.sourceURL) }


This post originally appeared on my technet blog.

Create a free website or blog at WordPress.com.

%d bloggers like this: