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