在Delphi中控制应用程序音量
我什至不确定这是否适合一个问题,但它是一个单一的问题。我有一个用 Delphi XE 编写的网络广播播放器,使用 BASS 库进行音频流和播放。该应用程序需要在 Windows XP、Vista 和 7 下运行。
低音可以轻松控制全局音量,但没有静音功能,一般来说,最好在每个应用程序的基础上控制音量。
低音还可以轻松控制“通道”(流)的音量,但同样没有静音,这也不是正确的每个应用程序控制。 (Windows 混音器中的应用程序音量控制不受影响。)
我知道,对于 Vista 及以上版本,我需要 ISimpleAudioVolume 和/或 IAudioEndpointVolume,但找不到这些的 Delphi 实现。所以问题的一部分是,它是否作为第三方库存在?
第二部分是,在这些接口不可用的 XP 上控制音量和切换静音(系统范围或每个应用程序)的正确方法是什么?
I'm not even sure if this fits into one question, but it is a single problem. I have an internet radio player written in Delphi XE, using the BASS library for audio streaming and playback. The application needs to run under Windows XP, Vista and 7.
Bass makes it easy to control global volume, but has no facility for muting sound, and in general it's a better idea to control volume on per-application basis.
Bass also makes it easy to control the volume of a "channel" (stream), but again there is no muting, and this isn't the proper per-application control, either. (The application volume control in Windows mixer is unaffected.)
I understand that for Vista and above I need ISimpleAudioVolume and/or IAudioEndpointVolume, but cannot find a Delphi implementation of these. So one part of the question is, does it exist as a 3rd party library?
Part two is, what's the proper way to to control volume and toggle mute (system-wide or per application) on XP, where these interfaces are not available?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用这个简单的代码将我的机器上的主音量静音:
Use this simple code to mute the main volume it works on my machine:
真是巧合,我也在使用 bass.dll 编写我的个人广播流客户端,顺便说一句,这是一个很棒的库。然而,我仍然想与 Windows 的混音器集成,因此从外部应用程序(例如 EarTrumpet 或 Windows Mixer 本身)修改音量也会自动反映在我的应用程序的音量滑块中。
正如评论所提到的,Windows XP 存在一些缺点,因为 IAudioSession 是从 Vista 开始引入的,而 Windows 7 及更高版本包括 IAudioSessionManager2、IAudioVolumeDuckNotification 等改进。
仍然对于您自己的应用程序,IAudioSessionManager 可以很好地工作,特别是使用 IAudioSimpleVolume。很高兴,Vista+ 中支持这一点。
您可以在 GitHub 和许多其他论坛上获得各种 MMDeviceAPI 实现,但在这里我将剥离必要的接口来实现我们需要的功能。
您将需要 IAudioSessionEvents、IAudioSessionControl、ISimpleAudioVolume、IAudioSessionManager、IMMDevice、IMMDeviceCollection、IMMNotificationClient 和 IMMDeviceEnumerator 接口。
为了响应外部音频事件,我们需要实现扩展 IAudioSessionsEvents 的接口,如下所示:
这是事件处理程序,它将更新音量和静音状态,任何音量变化从应用程序内或从 Windows 混音器。
注意,它需要改进来处理会话更改,例如,当您切换物理音频设备、重新分配到另一个音频设备等时。
现在,使用全局变量来处理音频会话和相关查询。
加载 Bass.dll 后我们进行初始化。
提示:这甚至可能包含在我们之前的自定义界面中,以实现更清晰的代码。
修改我们的应用程序音量:
与切换静音类似,事件处理程序将在视觉上更新,我们只需切换它即可。
就是这样,由你来改进它。我知道,这是一团糟的代码,当然它需要清理和处理安全释放接口等。
最后,这是所需的接口:
我猜 MfPack 和其他库包括 MMDeviceAPI.pas ,它拥有所有这些接口。
来源:https://learn.microsoft.com/en-us/windows/win32/coreaudio/audio-events-for-legacy-audio-applications
如果您想修改其他应用程序的音频会话并找到其图标、可执行文件等。最好使用 IAudioSessionManager2 (Windows 7+)
这是我的实现 https://github.com/vhanla/snotify/blob/ 596d22f5bd89e58297d15ffff6df2d0f69bd0351/AudioSessionService.pas
What a coincidence, I'm also writing my personal radio stream client using bass.dll, which is a great library BTW. However, I still wanted to integrate with Windows' mixer, so modifying volume from external applications (like EarTrumpet or Windows Mixer itself) would reflect in my application's volume slider too automatically.
As comments mentioned, there are some disadvantages with Windows XP, since IAudioSession was introduced from Vista onwards, and Windows 7 and newer included improvementes like IAudioSessionManager2, IAudioVolumeDuckNotification, etc).
Still for your own application, IAudioSessionManager will work well, specially using IAudioSimpleVolume. Gladly, that's supported in Vista+.
You can get a variety of MMDeviceAPI implementations at GitHub and many other forums, but here I will strip the necessary interfaces to achieve what we need.
You will need IAudioSessionEvents, IAudioSessionControl, ISimpleAudioVolume, IAudioSessionManager, IMMDevice, IMMDeviceCollection, IMMNotificationClient, and IMMDeviceEnumerator interfaces.
To respond to external audio events, we need to implement our interface extending IAudioSessionsEvents as follows:
That's the event handler, it will update volume and mute status as well, any volume changes from within the application or from Windows mixer.
NOTICE, it needs improvements to handle session changes, e.g. when you switch physical audio device, reassign to another audio device, etc.
Now, use a global variables to handle the audio sessions and related queries.
Let's initialize after loading Bass.dll.
Hint: this might even be included in our previous custom interface, for cleaner code.
To modify our application volume:
Similarly to toggle mute, the event handler will update visually, we just need to toggle it.
And that's it, it is up to you improving it. I know, this was a mess of a code, of course it needs cleaning and handling safe releasing interfaces, etc.
Finally, here are the interfaces required:
I guess MfPack and other libraries include MMDeviceAPI.pas which has all of them.
Source: https://learn.microsoft.com/en-us/windows/win32/coreaudio/audio-events-for-legacy-audio-applications
If you want to modify other applications' audio sessions and also find its icon, executable, etc. It is better to use IAudioSessionManager2 (Windows 7+)
here is my implementation https://github.com/vhanla/snotify/blob/596d22f5bd89e58297d15ffff6df2d0f69bd0351/AudioSessionService.pas