如何从 PowerShell 静音/取消静音
Posted
技术标签:
【中文标题】如何从 PowerShell 静音/取消静音【英文标题】:How can I mute/unmute my sound from PowerShell 【发布时间】:2008-11-01 02:11:17 【问题描述】:尝试编写一个 PowerShell cmdlet,该 cmdlet 将在开始时静音,除非已经静音,然后在结束时取消静音(只有在开始时没有静音)。 找不到我可以使用的任何 PoweShell 或 WMI 对象。我一直在玩弄诸如auxGetVolume 或auxSetVolume 之类的Win32 函数,但不能让它工作(如何从IntPtr 中读取值?)。
我正在使用 V2 CTP2。大家有什么想法吗?
谢谢!
【问题讨论】:
你见过这个问题吗(它与哔哔声有关,但我不确定你在说什么声音)? ***.com/questions/252799/… 【参考方案1】:从 Vista 开始,您必须使用 Core Audio API 来控制系统音量。它是一个不支持自动化的 COM API,因此需要从 .NET 和 PowerShell 中使用大量样板。
无论如何,下面的代码让您可以从 PowerShell 访问 [Audio]::Volume
和 [Audio]::Mute
属性。这也适用于可能有用的远程计算机。只需将代码复制粘贴到您的 PowerShell 窗口中即可。
Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
// f(), g(), ... are unused COM method slots. Define these if you care
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(); // Unused
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));
'@
使用示例:
PS C:\> [Audio]::Volume # Check current volume (now about 10%)
0,09999999
PS C:\> [Audio]::Mute # See if speaker is muted
False
PS C:\> [Audio]::Mute = $true # Mute speaker
PS C:\> [Audio]::Volume = 0.75 # Set volume to 75%
PS C:\> [Audio]::Volume # Check that the changes are applied
0,75
PS C:\> [Audio]::Mute
True
PS C:\>
如果您需要,还有更全面的 Core Audio API .NET 包装器,但我不知道有一组 PowerShell 友好的 cmdlet。
P.S. Diogo answer 看起来很聪明,但对我不起作用。
【讨论】:
您有没有机会分享如何使用这种方法使麦克风静音/取消静音? 我发现 this 更完整:github.com/frgnca/AudioDeviceCmdlets 非常感谢!【参考方案2】:在 ps1 powershell 脚本上使用以下命令:
$obj = new-object -com wscript.shell
$obj.SendKeys([char]173)
【讨论】:
要使用 .bat 运行,将此代码放入文件中并写入 powershell.exe -file "C:\file.ps1" 谢谢.. 添加键盘快捷键“F4”就像一个魅力。 这是敲击静音键的好方法和简单方法,但它只是一个切换而不是离散静音。在不知道卷的状态的情况下,它可能会做与预期相反的事情。【参考方案3】:Alexandre 的回答适合我的情况,但由于关于“var”命名空间的编译错误,他的示例不起作用。似乎较新/不同版本的 .net 可能会导致该示例不起作用。如果您发现收到编译错误,可以尝试使用以下替代版本:
Add-Type -Language CsharpVersion3 -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
// f(), g(), ... are unused COM method slots. Define these if you care
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(); // Unused
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));
'@
用法同理:
PS C:\> [Audio]::Volume # Check current volume (now about 10%)
0,09999999
PS C:\> [Audio]::Mute # See if speaker is muted
False
PS C:\> [Audio]::Mute = $true # Mute speaker
PS C:\> [Audio]::Volume = 0.75 # Set volume to 75%
PS C:\> [Audio]::Volume # Check that the changes are applied
0,75
PS C:\> [Audio]::Mute
True
PS C:\>
【讨论】:
不错。这是否可以扩展到涵盖麦克风/录音设备? 好喜欢晚上的尼克!! @monojohnny 是的,如果您将第一个参数更改为enumerator.GetDefaultAudioEndpoint
为 1
(eCapture) 而不是 0
(eRender),那么这可以使默认麦克风/输入设备静音/取消静音.
还值得指出这与上面亚历山大的答案 (***.com/a/19348221) 之间的唯一区别是添加了-Language CsharpVersion3
。如果这个答案只是对那个问题的评论,那可能就不那么令人困惑了。【参考方案4】:
似乎没有一种快速简便的方法来调整音量。如果你有 c++ 经验,你可以用this blog post 做一些事情,Larry Osterman 描述了如何从平台 api 调用 IAudioEndpointVolume 接口(对于 Vista,从我在几次搜索中发现的内容来看,XP 可能更难)。
V2 确实允许您编译内联代码(通过 Add-Type),所以这可能是一个选项。
【讨论】:
【参考方案5】:您可以通过简单地管理 Windows 音频服务以另一种方式给猫剥皮。停止静音,启动取消静音。
【讨论】:
这是我今天在搜索中找到的最简单的选项 +1。 "net stop "Windows 音频" 在 powershell 中:Stop-Service -DisplayName "Windows Audio" & Start-Service -DisplayName "Windows Audio"。希望我早点想到这一点。 简单,工作(在我的 Win10 机器上),并导致发送其他密钥或使用其他 shell 方法等的可能性。NICE @Brian Adams ***.com/users/32992/brian-adams 如果在停止和重新启动服务时媒体文件处于暂停状态,这可能会出现问题。视频播放器稍后可能无法播放声音,除非您停止并重新开始播放。 注意 - 这需要管理员权限,这对我来说是一个交易破坏者。【参考方案6】:我知道这不是 PowerShell,但结合 Michael 和 Diogo 的答案给出了一个单行 VBScript 解决方案:
CreateObject("WScript.Shell").SendKeys(chr(173))
把这个打到mute.vbs
,你可以双击切换静音
Set-ExecutionPolicy
【讨论】:
【参考方案7】:我没有找到如何在 PowerShell 中执行此操作,但是有一个名为 NirCmd 的命令行实用程序可以通过运行以下命令来解决问题:
C:\utils\nircmd.exe mutesysvolume 2
NirCmd 可在此处免费获得: http://www.nirsoft.net/utils/nircmd.html
【讨论】:
【参考方案8】:vbscript 中的解决方案:
Set WshShell = CreateObject("WScript.Shell")
For i = 0 To 50
WshShell.SendKeys(chr(174))
WScript.Sleep 100
Next
按键每次将音量降低 2。
【讨论】:
【参考方案9】:查看我对Change audio level from powershell?的回复
Set-DefaultAudioDeviceMute
【讨论】:
【参考方案10】:在我的回答得到一些反馈后,让我再试一次
这是基于@frgnca 的 AudioDeviceCmdlets,可在此处找到:https://github.com/frgnca/AudioDeviceCmdlets
这里的代码将使每个录音设备静音。
Import-Module .\AudioDeviceCmdlets
$audio_device_list = Get-AudioDevice -list
$recording_devices = $audio_device_list | ? $_.Type -eq "Recording"
$recording_devices
$recording_device_index = $recording_devices.Index | Out-String -stream
foreach ($i in $recording_device_index)
$inti = [int]$i
Set-AudioDevice $inti | out-null -erroraction SilentlyContinue
Set-AudioDevice -RecordingMute 1 -erroraction SilentlyContinue
您导入 AudioDeviceCmdlets dll,然后保存所有音频设备的列表,过滤到录音设备中。您获取所有录制设备的索引,然后遍历每个设备,首先将设备设置为主音频设备,然后将该设备设置为静音(这 2 步过程是 dll 施加的限制)。
要取消静音,请将 -RecordingMute 1 更改为 RecordingMute 0
同样,您可以使用以下代码静音播放设备:
Import-Module .\AudioDeviceCmdlets
$audio_device_list = Get-AudioDevice -list
$playback_devices = $audio_device_list | ? $_.Type -eq "Playback"
$playback_devices
$playback_device_index = $playback_devices.Index | Out-String -stream
foreach ($i in $playback_device_index)
$inti = [int]$i
Set-AudioDevice $inti | out-null -erroraction SilentlyContinue
Set-AudioDevice -PlaybackMute 1 -erroraction SilentlyContinue
要取消静音,请将 -PlaybackMute 1 更改为 PlaybackMute 0
此代码来自我拥有的一个更大项目的一部分,该项目通过 Arduino 连接到物理按钮/LED 静音状态显示,以启用单按钮按下以静音/取消静音所有系统麦克风(以帮助 Zoom、Meet、Teams、 Discord 等)并帮助人们避免尴尬的热点事件。
https://github.com/dakota-mewt/mewt
附:我真的很喜欢Change audio level from powershell?这样的一些单行解决方案@
但是,请注意,单线静音通常仅适用于当前设置为 Windows 默认设置的单个设备。因此,如果您的软件能够处理不同的音频设备(例如 Zoom 和 Meet),而它们恰好使用的是非默认设备,那么它可能无法正常工作。
【讨论】:
发布一个独立的解决方案而不是链接【参考方案11】:在上面的第二个脚本中,要在 PowerShell 7 或 PowerShell Core 中工作的第一行更改:
-Language CsharpVersion3
到...
-Language Csharp
在 W10 上工作
【讨论】:
或者完全省略-Language
参数(CSharp
是 PowerShell 7 中唯一可接受的值,也是默认值,请参阅 documentation)为Alexandre 的original answer 就是这种情况 - 即这不是一个新答案,作为对上述答案的评论可能会更好。以上是关于如何从 PowerShell 静音/取消静音的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ionic 平台的 APIRTC 上静音和取消静音视频/音频?