C#调用 Windows 辅助功能 API "AccSetRunningUtilityState" 函数实现音频避闪功能

音频闪避是指当自身应用程序,例如辅助功能程序,正在播放音频的时候,降低其他应用程序的音量。这样可以让用户更清楚地听到自身应用程序的音频,例如文字转语音或者导航提示。Windows API 提供了一个函数,AccSetRunningUtilityState,可以让辅助功能程序设置自己的音频闪避选项。本文将介绍如何使用这个函数实现音频闪避的功能。

AccSetRunningUtilityState 函数
AccSetRunningUtilityState 函数的原型如下:
HRESULT AccSetRunningUtilityState(
[in] HWND hwndApp,
[in] DWORD dwUtilityStateMask,
[in] DWORD dwUtilityState
);
这个函数接受三个参数: - hwndApp:辅助功能程序的主窗口句柄。这个参数不能为 NULL。 - dwUtilityStateMask:一个掩码,表示要设置的系统值。它可以是下面的值的组合: - ANRUS_ON_SCREEN_KEYBOARD_ACTIVE:辅助功能程序提供了一个屏幕键盘。 - ANRUS_TOUCH_MODIFICATION_ACTIVE:辅助功能程序正在消费重定向的触摸输入。 - ANRUS_PRIORITY_AUDIO_ACTIVE:辅助功能程序依赖音频(例如文字转语音)来传达重要信息给用户,并且应该在其他系统声音上保持可听性。 - ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK:辅助功能程序依赖音频(例如文字转语音)来传达重要信息给用户,但不应该相对于其他系统声音发生变化。 - dwUtilityState:dwUtilityStateMask 所指示的系统值的新设置。这个参数可以是零来重置系统值,或者是上面的值的组合。 如果成功,这个函数返回 S_OK,否则返回一个标准的 COM 错误码。 这个函数需要调用进程拥有 UIAccess 或更高的权限。如果调用者没有必要的权限,调用 AccSetRunningUtilityState 会失败,并返回 E_ACCESSDENIED。 在退出之前,辅助功能程序应该重置之前设置的任何系统值。
音频闪避选项
为了实现音频闪避的功能,我们需要使用 ANRUS_PRIORITY_AUDIO_ACTIVE 和 ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK 这两个值。它们分别表示: - ANRUS_PRIORITY_AUDIO_ACTIVE:辅助功能程序正在播放重要的音频,并且希望系统降低其他应用程序的音量。 - ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK:辅助功能程序正在播放重要的音频,但不希望系统降低其他应用程序的音量。 我们可以根据自己的需求,选择其中一个或者两个都使用。如果我们想要让自己的音频始终保持高于其他应用程序的音量,我们可以同时使用这两个值。如果我们想要让自己的音频在开始播放时降低其他应用程序的音量,然后在停止播放时恢复其他应用程序的音量,我们可以在开始播放时使用 ANRUS_PRIORITY_AUDIO_ACTIVE,然后在停止播放时使用 ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK。
示例代码
下面是一个使用 C# 编写的示例代码,演示了如何调用 AccSetRunningUtilityState 函数实现音频闪避的功能。这个代码定义了一个静态类 AudioDucking,提供了两个静态方法: - SetAudioDucking:设置音频闪避选项为 ANRUS_PRIORITY_AUDIO_ACTIVE,表示辅助功能程序处于活动状态,正在播放重要的音频,并且希望系统降低其他应用程序的音量。 - ResetAudioDucking:设置音频闪避选项为 ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK,表示辅助功能程序已经停止播放重要的音频,或者不希望系统降低其他应用程序的音量。 这两个方法都接受一个参数,即辅助功能程序的主窗口句柄。它们都调用了 AccSetRunningUtilityState 函数,并返回一个布尔值,表示是否成功。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace WinForms
{
public static class AudioDucking
{
private const uint ANRUS_PRIORITY_AUDIO_ACTIVE = 0x0000004;
private const uint ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK = 0x0000008;
[DllImport("oleacc.dll", SetLastError = true)]
private static extern int AccSetRunningUtilityState(IntPtr hwndApp, uint dwUtilityStateMask, uint dwUtilityState);
public static bool SetAudioDucking(IntPtr hwnd)
{
int result = AccSetRunningUtilityState(hwnd, ANRUS_PRIORITY_AUDIO_ACTIVE | ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK, ANRUS_PRIORITY_AUDIO_ACTIVE | ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK);
return result == 0;
}
public static bool ResetAudioDucking(IntPtr hwnd)
{
int result = AccSetRunningUtilityState(hwnd, ANRUS_PRIORITY_AUDIO_ACTIVE | ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK, ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK);
return result == 0;
}
}
}
使用方法
为了使用这个示例代码,我们需要在程序中引用 AudioDucking 类,并在合适的时机调用它的方法。例如,如果我们的辅助功能程序是一个文字转语音的应用程序,我们可以在开始播放语音时调用 SetAudioDucking 方法,然后在停止播放语音时调用 ResetAudioDucking 方法。这样就可以实现音频闪避的功能,让用户更清楚地听到我们的语音输出。
总结
本文介绍了如何使用 Windows API 中的 AccSetRunningUtilityState 函数实现音频闪避的功能。这个函数可以让辅助功能程序设置自己的音频闪避选项,从而影响系统对其他应用程序的音量控制。我们还给出了一个使用 C# 编写的示例代码,演示了如何调用这个函数。希望本文对你有所帮助。
参考资料
1.NVDA Audio Ducking Mode: https://github.com/nvaccess/nvda/blob/master/source/audioDucking.py
2.AccSetRunningUtilityState function (oleacc.h): https://learn.microsoft.com/en-us/windows/win32/api/oleacc/nf-oleacc-accsetrunningutilitystate#anrus_priority_audio_active_noduck

用 C# 实现独占音频设备降低其它程序的音量相关推荐

  1. 怎么禁止windows音频设备图形隔离程序_Windows 10中音频设备图形间隔内存占用较高的处理方法...

    在使用Windows 10的操作系统的时候,有时会出现程序或者其他的软件在使用时出现卡顿的情况.通过运行Windows 10的"任务管理器"中观察,发现有一个"Windo ...

  2. java中接口降低耦合性_如何降低一个程序的耦合性

    耦合性是程序结构中各个模块之间相互关联的度量.它取决于各个模块之间接口的复杂程度.调用模块的方式以及哪些信息通过接口. 一般模块之间可能的连接方式有七种,构成耦合性的七种类型.它们之间的关系为(由弱到 ...

  3. java无法调用音频设备_win10下程序无法录音或使用麦克风

    操作系统名称    Microsoft Windows 10 专业 版本    10.0.17134 版本 17134 简言之,win10采用类似移动操作系统的设备权限管理方式,对麦克风.摄像头.定位 ...

  4. windows如何调整某个应用程序的音量 c++_微软对重启Windows 10的应用程序进行控制测试...

    尽管近年来个人电脑发生了很多变化,但至少有一件事没有改变:在某个时候,你需要重启电脑.考虑到这一点,明年Windows 10的两次大更新中的第一次可能会对操作系统重启的处理方式做出微妙但有益的调整. ...

  5. 抢购 mysql 优化_处理抢购、秒杀应用场景降低“超卖”发生几个优化方案(php)...

    加深下文件锁理论 flock-轻便的咨询文件锁定 说明 参数 handle 文件系统指针,是典型地由fopen()创建的resource(资源). operation operation可以是以下值之 ...

  6. STM32 之三 标准外设版USB驱动库详解(架构+文件+函数+使用说明+示例程序)

    写在前面 目前,ST的USB驱动有两套,一套是早期的独立版USB驱动,官方培训文档中称为Legacy library:一套为针对其Cube 系列的驱动,根据芯片不同可能有区别,具体见对应芯片的Cube ...

  7. 2021哈工大计算机系统大作业——程序人生-Hello’s P2P

    计算机系统 大作业 题     目 程序人生-Hello's P2P 计算机科学与技术学院 2021年6月 摘  要 本文介绍了hello的整个生命过程.利用gcc,gdb,edb,readelf,H ...

  8. 谁说.NET没有GC调优,只改一行代码就让程序不再占用内存

    经常看到有群友调侃"为什么搞Java的总在学习JVM调优?那是因为Java烂!我们.NET就不需要搞这些!"真的是这样吗?今天我就用一个案例来分析一下. 昨天,一位学生问了我一个问 ...

  9. DIRECTX中独占模式与窗口模式的切换(译)

    <script language="javascript" type="text/javascript">document.title=" ...

最新文章

  1. VS2005 / windows sdk7.1配置
  2. vue之Render函数
  3. C语言 递归实现辗转相除法 和 辗转相减法
  4. 检查电脑是否被安装***的三个小命令
  5. selenium java 滚动条_java+selenium使用JS、键盘滑动滚动条
  6. android基础知识之一
  7. for jq 嵌套_遍历嵌套列表 – jQuery
  8. 4个基本不等式的公式高中_写作 | 高中英语作文4个高分写作技巧
  9. OpenCV精进之路(九):图像轮廓和图像分割修复——图像修复技术
  10. 计算机网络之数据链路层协议总结
  11. 软件测试自学好还是培训好?软件测试自学与培训的优劣势对比
  12. vue路由守卫(页面鉴权)
  13. js把汉字转换成拼音
  14. 关于Ubuntu18.04双系统安装后无法连接WiFi问题解决方法
  15. Smart3D(ContextCapture)跑三维到底要啥配置?!40000元来组建建模集群
  16. 【hive-3.1.3】ORC 格式的表和 text 格式的表,当分区的字段数量和表的字段数量不一致,检索结果不相同
  17. 金融时报:电信改革重拼成软骨巨人?
  18. LOL云顶开心果、阿米、夜猫
  19. 酒桌游戏,初期训练思维
  20. Node Sass does not yet support your current environment: OS X Unsupported architecture (arm64)

热门文章

  1. java商品搜索功能_JavaWeb实现简单查询商品功能
  2. 亚马逊差评怎么删?常用的几种删差评方法介绍
  3. 手机抓包+注入黑科技HttpCanary——最强大的Android抓包注入工具
  4. 数据库数字孪生技术获突破,Ganos两项研究成果入选VLDB
  5. snat与dnat的区别
  6. 一文了解BLDC与PMSM的区别
  7. vue编程式导航跳转到当前路由多次执行抛出NavigationDuplicated: Avoided redundant navigation to current location:
  8. QML---Repeater
  9. 百度云搜索引擎森林战士_华为拟安装“俄版安卓”;百度回应内部贪腐;Android Studio 3.5 RC2 发布 | 极客头条...
  10. 牛逼的js--就是d3.js