Files
bjarneo--cliamp/player/audio_device_windows.go
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

62 lines
2.0 KiB
Go

//go:build windows
package player
import (
"fmt"
"os/exec"
"strings"
)
// ListAudioDevices lists audio output devices via PowerShell on Windows.
func ListAudioDevices() ([]AudioDevice, error) {
// Use Get-CimInstance Win32_SoundDevice for basic sound card enumeration.
script := `Get-CimInstance Win32_SoundDevice | ForEach-Object { $_.Name + '|' + $_.DeviceID }`
out, err := exec.Command("powershell", "-NoProfile", "-Command", script).Output()
if err != nil {
return nil, fmt.Errorf("powershell: %w", err)
}
var devices []AudioDevice
for i, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
name, id, _ := strings.Cut(line, "|")
devices = append(devices, AudioDevice{
Index: i,
Name: strings.TrimSpace(id),
Description: strings.TrimSpace(name),
Active: false,
})
}
return devices, nil
}
// PrepareAudioDevice is a no-op on Windows — the system default output
// device is used. Returns a no-op cleanup.
func PrepareAudioDevice(device string) func() {
return func() {}
}
// SwitchAudioDevice changes the Windows system default output device.
// The running audio stream keeps its original device; the change
// takes full effect on the next app restart.
func SwitchAudioDevice(deviceName string) error {
script := fmt.Sprintf(
`Get-AudioDevice -PlaybackCommunication | Out-Null; `+
`Set-AudioDevice -ID '%s' -ErrorAction Stop`,
strings.ReplaceAll(deviceName, "'", "''"),
)
if out, err := exec.Command("powershell", "-NoProfile", "-Command", script).CombinedOutput(); err != nil {
// AudioDeviceCmdlets may not be installed; fall back to nircmd.
cmd := exec.Command("nircmd", "setdefaultsounddevice", deviceName)
if out2, err2 := cmd.CombinedOutput(); err2 != nil {
return fmt.Errorf("failed to set output device (install AudioDeviceCmdlets or nircmd): %s / %s",
strings.TrimSpace(string(out)), strings.TrimSpace(string(out2)))
}
}
return nil
}