如何在 C# 中更改 Windows 中的扬声器配置?
Posted
技术标签:
【中文标题】如何在 C# 中更改 Windows 中的扬声器配置?【英文标题】:How to Change Speaker Configuration in Windows in C#? 【发布时间】:2016-12-30 05:21:42 【问题描述】:我知道这个旧线程:What APIs exist?,但它确实没有回答问题。而且已经有好几年了。是的,我正在使用 NAudio.CoreAudioApi 但我没有找到任何有用的信息。
MMDevice.Properties 是只读的。有没有办法在 C# 中以编程方式执行此操作?我不确定了。
您还可以通过以下方式找到频道: AudioEndpointVolumeChannels,但它只允许 Channels.count。
我想到的另一个解决方案是使用某种“宏”,它会随着鼠标点击动作而改变,但这很丑。
那个 NAudio API 应该有正确的东西,但我没有找到任何关于如何做到这一点的文档。我用谷歌搜索了一整天,一无所获。旧的 CoreAPI 被移到了那里。
using NAudio.Wave;
using NAudio.CoreAudioApi;
//Can't do anything with these Devices, but change the volume????!!!
var deviceEnum = new MMDeviceEnumerator();
var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
foreach (MMDevice device in devices)
Console.WriteLine(device.FriendlyName);
【问题讨论】:
你到底想配置什么?你能说得更具体些吗 我想将播放设备从 2CH 更改为 5.1。或将采样率从默认设置为 24 位、48000。我不确定上面引用的 NAudio 是否有工具。我尝试了其他几个 API,但文档很少,或者功能不存在。 【参考方案1】:Windows API 支持修改属性,但 NAudio 出于某种原因并未公开此功能。通过修改 NAudio 源很容易添加它。
在NAudio\CoreAudioApi\PropVariant.cs
添加
/// <summary>
/// Creates a new PropVariant containing a uint value
/// </summary>
public static PropVariant FromUInt(uint value)
return new PropVariant() vt = (short)VarEnum.VT_UI4, ulVal = value ;
在NAudio\CoreAudioApi\PropertyStore.cs
添加以下方法
/// <summary>
/// Sets property value at specified key
/// </summary>
/// <param name="key">Index</param>
/// <param name="value">Value</param>
public void SetValue(PropertyKey key, PropVariant value)
Marshal.ThrowExceptionForHR(storeInterface.SetValue(ref key, ref value));
在NAudio\CoreAudioApi\MMDevice.cs
修改下一行
Marshal.ThrowExceptionForHR(deviceInterface.OpenPropertyStore(StorageAccessMode.Read, out propstore));
成为
Marshal.ThrowExceptionForHR(deviceInterface.OpenPropertyStore(StorageAccessMode.ReadWrite, out propstore));
现在,如果您使用这些更改重建 NAudio.dll,您的示例可能看起来像这样,将播放设备更改为 5.1(您必须以管理员身份运行它,否则它将失败)
var deviceEnum = new MMDeviceEnumerator();
var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
foreach (MMDevice device in devices)
Console.WriteLine(device.FriendlyName);
if (device.Properties.Contains(PropertyKeys.PKEY_AudioEndpoint_PhysicalSpeakers))
var value = device.Properties[PropertyKeys.PKEY_AudioEndpoint_PhysicalSpeakers];
Console.WriteLine("Current value: " + value.Value.ToString());
// set configuration to 5.1, value is taken from ksmedia.h from Windows Driver Kit
PropVariant newvalue = PropVariant.FromUInt(63);
device.Properties.SetValue(PropertyKeys.PKEY_AudioEndpoint_PhysicalSpeakers, newvalue);
【讨论】:
您的答案看起来不错。但是在下载他们的源代码时。我得到一百万个无法解决的错误。就像它带有错误的框架或缺少依赖项一样。具体来说,我在'=>'和'预期标识符......'之类的东西上得到“无效令牌';'”。 127 个错误。 你用的是哪个版本的?我从这里得到了最新的github.com/naudio/NAudio,它在 VS 2015 中编译没有错误 OK 忽略上面的 cmets。我已经在 VS2015 中构建了它。下一个问题是它不起作用。在调试中,我看到它以正确的值命中设置器,但播放设备从未从 2CH 更改为 5.1。 也可以尝试不同的键,你可以使用SysInternals ProcessMonitor检查手动更改配置时HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render中哪些值发生了变化 为了减少事件数量添加过滤器只显示 ProcessName = svchost.exe 和 Operation=RegSetValue【参考方案2】:Eugene 和我发现有效的方法是找到播放设备注册表——“渲染”,即: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render 然后正斜杠 Guid... 您的播放设备。确保您的设备处于 5.1 或更高版本的模式。
然后将其“导出”到文件中。当您需要恢复到 5.1 或更高版本时,其中还包括“采样率”。然后在代码中使用导出文件中的以下内容:
Process regeditProcess = Process.Start("regedit.exe", "/s playback.reg");
regeditProcess.WaitForExit();
这将确保正确恢复密钥。 它仍然不是我想看到的最好的方式。但它确实有效。
【讨论】:
以上是关于如何在 C# 中更改 Windows 中的扬声器配置?的主要内容,如果未能解决你的问题,请参考以下文章
使用 C# 在 Windows 10 上控制左右扬声器平衡级别