Po$H Pete | Those who can… $cript
4May/115

Controlling Media Playback from Powershell

Ever wanted to control your media playback from Powershell?

Now you can send Play, Pause, Next, Previous and Stop commands directly to any media player you have open without leaving the powershell shell :-)

Feel free to chop and change the function names around. I wasn't feeling overly creative when I came up with them.

$SendKeyClass = @"
 
       [DllImport("user32.dll")]
        private static extern int keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
 
        public static void SendKey(Keys key)
        {
            keybd_event((byte)key, 0, 0, 0);
        }
 
 
"@
 
function Set-PlayPausetrack
{
	if($app -eq $null)
	{
		$app = Add-Type -MemberDefinition $SendKeyClass -Name Win32Window -Namespace PoshPete.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru
	}
	$app::SendKey([System.Windows.Forms.Keys]::MediaPlayPause)
}
 
function Set-StopTrack
{
	if($app -eq $null)
	{
		$app = Add-Type -MemberDefinition $SendKeyClass -Name Win32Window -Namespace PoshPete.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru
	}
	$app::SendKey([System.Windows.Forms.Keys]::MediaStop)
}
 
function Set-NextTrack
{
	if($app -eq $null)
	{
		$app = Add-Type -MemberDefinition $SendKeyClass -Name Win32Window -Namespace PoshPete.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru
	}
	$app::SendKey([System.Windows.Forms.Keys]::MediaNextTrack)
}
 
function Set-PreviousTrack
{
	if($app -eq $null)
	{
		$app = Add-Type -MemberDefinition $SendKeyClass -Name Win32Window -Namespace PoshPete.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru
	}
	$app::SendKey([System.Windows.Forms.Keys]::MediaPreviousTrack)
}
Comments (5) Trackbacks (0)
  1. This is verry intresting, makes me wonder if it is possible to retreive the title of the currently played song.

    • Hi Carl, I suspect you can get that via the window title. Have a look at the process object that you can get back with “get-process spotify”.

  2. Hi Pete,

    I could us get-process to get the winamp process and after doing more research I found that I can pipe and use where to get the manwindow title:

    Get-Process winamp | where {$_.mainWindowTitle} | format-table mainWindowTitle

    MainWindowTitle
    —————
    6. A Tribe Called Quest – I Left My Wallet in El Segundo – Winamp

    Great! And I tried it for the VLC player that also works :

    Get-Process vlc | where {$_.mainWindowTitle} | format-table mainWindowTitle

    MainWindowTitle
    —————
    De Staat – Sleep Tight – VLC Media Player

    However when I try to do the same with the mediaplayer I can’t get the title because it is not in the mainwindow title

    Get-Process wmplayer | where {$_.mainWindowTitle} | Format-table mainWindowTitle

    MainWindowTitle
    —————
    Windows Media Player

    Unfortunately trying ” get-process wmplayer | format-list * “does not seem to give anyhing usefull

    Maybe I should use SetWindow and GetWindow from the API, unfortunately I have found some C# .NET and VB .NET code ( http://www.codeproject.com/Articles/5780/Retrieve-the-Winamp-song-title-with-NET# ) but I do not understand the code. I think that I should study the creation of the an object first n order to use the user32dll.

    Workaround for now:
    Not using the mediaplayer ;) and I will study the object maybe I can also retrieve more information.

    Thanks,
    Carl

  3. Hi Pete,

    Thank you for the link to the information, I think I understand abouth 80% off it, the syntax for the class, the ['s the ::'s and the .'s is confusing but I will read up. In the meanwhile I have studie your example and the example code on the code-project and I was able to combine making the play/pauze button in Powershell using the FindWindow and SendMessage functions.

    First I find the ihandle of the Media Player and then I use this to use the play/pauze functionality.

    First expirimental (working) code is as follows:

    $TestClass = @"
    public const int WM_COMMAND = 0x111;

    [DllImport("User32.dll")]
    public static extern int FindWindow(string strClassName, string strWindowName);

    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, int lParam);
    “@

    $TestVariable = Add-Type -MemberDefinition $TestClass -Name Win32Window -Namespace TestClas9 -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru
    [int] $ihandle=$TestVariable::FindWindow(“WMPlayerApp”, “Windows Media Player”)
    write-Host Hhandle of media player is $ihandle, now the pause button will be toggled
    $TestVariable::SendMessage($iHandle, $TestVariable::WM_COMMAND, 18808, 0);

    Next week I will try to free up some time and investigate the above more deeply.

    Carl


Leave a comment

(required)

No trackbacks yet.