PowerShell and Windows Media Player, part 2

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




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
 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) }



Technorati Tags: Windows,Media Player,PowerShell