在 macOS 上,一个应用程序可以 disable/suppress 所有系统音频输出不是由它自己发出的吗?

on macOS, can an app disable/suppress all system audio output which is not emitted by itself?

在应用程序中,我正在使用 mac 上连接的 USB 音频接口驱动激光投影设备OS。

激光设备以模拟音频作为输入。

作为一项安全功能,如果我可以将我的应用程序的音频输出设为独占输出,那就太好了,因为来自其他应用程序或来自 OS 本身的任何其他音频都被路由到 USB音频接口与我的激光控制音频混合在一起,是不需要的并且存在安全隐患。

是否可以在 mac 上OS 使我的应用程序的音频输出独占?我知道你可以在 iOS 上配置 AVAudioSession 来实现这个(有点 - 你可以隐藏其他应用程序的音频,但通知声音会依次隐藏你的应用程序),但是在 Mac ?它不需要与 AppStore 兼容。

是的,您可以请求 CoreAudio 授予您对音频输出设备的独占访问权。这称为占用设备。如果你霸占了所有设备,其他应用程序(包括系统)将无法发出任何声音。

像这样的东西可以对单个设备起作用:

AudioObjectPropertyAddress HOG_MODE_PROPERTY = { kAudioDevicePropertyHogMode, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
AudioDeviceID deviceId = // your audio device ID
pid_t hoggingProcess = -1; // -1 means attempt to acquire exclusive access
UInt32 size = sizeof(pid_t);

AudioObjectSetPropertyData(deviceId, &HOG_MODE_PROPERTY, 0, NULL, size, &hoggingProcess);
assert(hoggingProcess == getpid()); // check that you have exclusive access

Hog 模式通过设置一个名为 kAudioDevicePropertyHogModeAudioObject 属性 来工作。如果设备未被占用,属性 的值为 -1。如果它被占用,则该值为占用进程的进程 ID。

如果您在 XcodekAudioDevicePropertyHogModejump to definition,您可以阅读 header 猪模式 属性 的文档。这是了解此 属性(以及 CoreAudio 中的几乎所有内容)如何工作的最佳方式。

为了完整起见,这里是 header 文档:

                    A pid_t indicating the process that currently owns exclusive access to the
                    AudioDevice or a value of -1 indicating that the device is currently
                    available to all processes. If the AudioDevice is in a non-mixable mode,
                    the HAL will automatically take hog mode on behalf of the first process to
                    start an IOProc.
                    Note that when setting this property, the value passed in is ignored. If
                    another process owns exclusive access, that remains unchanged. If the
                    current process owns exclusive access, it is released and made available to
                    all processes again. If no process has exclusive access (meaning the current
                    value is -1), this process gains ownership of exclusive access.  On return,
                    the pid_t pointed to by inPropertyData will contain the new value of the
                    property.