Jak automaticky ztlumit zvuk při odpojení sluchátek v systému Windows 10

Operační systém Windows 10 má schopnost ukládat individuální zvukové profily pro různé zvukové výstupní zařízení. Ke každému připojenému zařízení si můžete nastavit odlišnou úroveň hlasitosti, která se po připojení automaticky aplikuje. Je samozřejmé, že nikdo nemá zvuková zařízení trvale ztlumená. Hlasitost se běžně upravuje podle potřeby, a nikoli permanentně ztišuje.

Pokud často používáte sluchátka a musíte je odpojovat, může vám malý skript PowerShell výrazně ulehčit život. Skript automaticky ztlumí zvuk, když sluchátka odpojíte.

Tato funkce je podobná tomu, jak se chovají mobilní telefony – při odpojení sluchátek se přehrávání hudby automaticky pozastaví. Cílem je, abyste buď ukončili poslech, nebo v případě nechtěného vyjmutí sluchátek měli možnost rychle zvuk deaktivovat. Scénář vychází z podobné myšlenky, kterou popsal Prateek Singh na GEEKEEFY.

Automatické ztlumení zvuku

Spusťte program Poznámkový blok a vložte do něj následující kód:

[cmdletbinding()]
Param()
 
#Definice pro přístup k Audio API
Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume {
// f(), g(), ... jsou nevyužité COM metody. Definujte je, pokud je potřebujete
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(); // Nevyužito
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)
{
#Vyčištění všech událostí v aktuální relaci před začátkem nové iterace
Get-Event | Remove-Event -ErrorAction SilentlyContinue
 
#Registrace události a čekání na její spuštění
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
 
#Podmínková logika pro ztlumení/odtlumení zvuku pomocí Audio API
If($EventType -eq 3)
{
[Audio]::Mute = $true
Write-Verbose "Ztlumeno [$((Get-Date).tostring())]"
}
elseif($EventType -eq 2 -and [Audio]::Mute -eq $true)
{
[Audio]::Mute = $false
Write-Verbose "Odtlumeno [$((Get-Date).tostring())]"
}
}

Uložte tento soubor s příponou .ps1. Nezapomeňte vybrat možnost „Všechny soubory“ v rozevírací nabídce pro typ souboru. Soubor pojmenujte tak, abyste hned věděli, co dělá. Uložte ho na místo, kde jej omylem nesmažete, ale zároveň kde ho v případě potřeby snadno naleznete.

Spuštění skriptu

PowerShell z bezpečnostních důvodů nemůže automaticky spouštět skripty. Existuje však způsob, jak toto omezení obejít. Podrobný návod, jak automatizovat spouštění skriptu PowerShell, naleznete v našem dalším článku. Využijte Plánovač úloh k tomu, aby se skript automaticky spouštěl při každém startu počítače.

Alternativně můžete skript spouštět ručně při startu systému. Osobne ho používám necelých 30 minut a už si nedokážu představit, že bych bez něj fungoval.