# Now-playing helper for the Go agent. # Reads the current Windows media session via WinRT and emits a compact JSON # blob on stdout, or `null` when nothing is playing. Compatible with PS5+. # # The Go agent shells out to this every few seconds and ships a `media` # event when the song/state changes. $ErrorActionPreference = 'SilentlyContinue' try { [Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager, Windows.Media.Control, ContentType=WindowsRuntime] | Out-Null } catch { Write-Output 'null' exit 0 } Add-Type -AssemblyName System.Runtime.WindowsRuntime $asTaskGeneric = [System.WindowsRuntimeSystemExtensions].GetMethods() | Where-Object { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' } | Select-Object -First 1 function Await($op, $resultType) { if ($null -eq $op) { return $null } $task = $asTaskGeneric.MakeGenericMethod($resultType).Invoke($null, @($op)) $task.Wait(-1) | Out-Null return $task.Result } try { $mgrType = [Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager] $mgr = Await ($mgrType::RequestAsync()) ($mgrType) $session = $mgr.GetCurrentSession() if ($null -eq $session) { Write-Output 'null'; exit 0 } $infoType = [Windows.Media.Control.GlobalSystemMediaTransportControlsSessionMediaProperties] $info = Await ($session.TryGetMediaPropertiesAsync()) ($infoType) $pb = $session.GetPlaybackInfo() $payload = [pscustomobject]@{ app = $session.SourceAppUserModelId title = $info.Title artist = $info.Artist album = $info.AlbumTitle status = if ($pb) { $pb.PlaybackStatus.ToString() } else { $null } } $payload | ConvertTo-Json -Compress } catch { Write-Output 'null' }