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

 Get-Playlist   
Set-Playlist
Get-media 
Get-mediaByAttribute 

Get-MediaInPlaylist  
Append-Media 

Reset-media 

At the end of that piece I introduced

Stop-media 
Pause-media

Play-media

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 

{Param($name)

 $Waiting=$true

 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 

{Param($seconds)

 $Waiting=$true

 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

{Param([dateTime]$EndTime)

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

$wmp.controls.play() 

}

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