Jak automatycznie wyciszyć dźwięk, gdy słuchawki są odłączone w systemie Windows 10

System operacyjny Windows 10 ma zdolność do zarządzania niezależnymi profilami audio dla różnych urządzeń dźwiękowych. Dla każdego podłączonego urządzenia można ustawić odrębny poziom głośności, a po jego podłączeniu głośność dostosowuje się automatycznie. Oczywiście, mało kto wciąż wycisza urządzenia audio, częściej zmienia się ich głośność, ale zazwyczaj nie wyłącza ich całkowicie.

Jeżeli korzystasz z pary słuchawek podłączonych do komputera i często je odłączasz, istnieje możliwość zastosowania prostego skryptu PowerShell, który automatycznie wyciszy dźwięk po ich odłączeniu.

To rozwiązanie przypomina to, co robią telefony komórkowe, które zatrzymują muzykę po odłączeniu słuchawek. Logika tego działania jest prosta: albo zakończyłeś słuchanie muzyki, albo przypadkowo zdjąłeś słuchawki i potrzebujesz szybkiego sposobu na ich wyciszenie. Scenariusz ten został stworzony na podobnych zasadach przez Prateek Singh z GEEKEEFY.

Automatyczne wyciszanie dźwięku

Otwórz Notatnik i wklej poniższy kod:

[cmdletbinding()]
Param()

# Dodawanie definicji do uzyskania dostępu do Audio API
Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume {
// f(), g(), ... to nieużywane sloty metod COM. Zdefiniuj je, jeśli są istotne
int f(); int g(); int h(); int i();
int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
int j();
int GetMasterVolumeLevelScalar(out float pfLevel);
int k(); int l(); int m(); int n();
int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice {
int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator {
int f(); // Nie używane
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio {
static IAudioEndpointVolume Vol() {
var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
IMMDevice dev = null;
Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
IAudioEndpointVolume epv = null;
var epvid = typeof(IAudioEndpointVolume).GUID;
Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
return epv;
}
public static float Volume {
get {float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v;}
set {Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty));}
}
public static bool Mute {
get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
}
}
'@ -Verbose


While($true)
{
# Czyszczenie wszystkich zdarzeń w bieżącej sesji, aby rozpocząć od nowa w pętli
Get-Event | Remove-Event -ErrorAction SilentlyContinue

# Rejestracja zdarzenia i oczekiwanie na jego wywołanie
Register-WmiEvent -Class Win32_DeviceChangeEvent
Wait-Event -OutVariable Event |Out-Null

$EventType = $Event.sourceargs.newevent | `
Sort-Object TIME_CREATED -Descending | `
Select-Object EventType -ExpandProperty EventType -First 1

# Logika warunkowa do obsługi wyciszania/odciszania maszyny przy użyciu Audio API
If($EventType -eq 3) 
{
[Audio]::Mute = $true
Write-Verbose "Wyciszone [$((Get-Date).tostring())]"
}
elseif($EventType -eq 2 -and [Audio]::Mute -eq $true)
{
[Audio]::Mute = $false
Write-Verbose "Odciszone [$((Get-Date).tostring())]"
}
}

Zapisz plik z rozszerzeniem .PS1. Upewnij się, że w menu rozwijanym typu pliku wybrałeś opcję „Wszystkie pliki”. Nadaj mu nazwę, która jasno określa jego przeznaczenie. Umieść go w lokalizacji, w której nie zostanie przypadkowo usunięty, ale jednocześnie łatwo go znajdziesz w razie potrzeby.

Uruchamianie skryptu

PowerShell nie może automatycznie uruchomić skryptu, ponieważ posiada wbudowane zabezpieczenia, które to uniemożliwiają. Istnieje jednak sposób na to. Mamy szczegółowy artykuł opisujący, jak możesz to zrobić. Postępuj zgodnie z instrukcjami, aby automatycznie uruchomić utworzony skrypt PowerShell oraz użyj zaplanowanego zadania, aby uruchamiać go za każdym razem przy starcie systemu.

Alternatywnie, możesz ręcznie uruchomić skrypt przy starcie systemu. Sam korzystam z tego rozwiązania od mniej niż 30 minut i nie wyobrażam sobie, jak mogłem wcześniej bez niego żyć.