有没有办法检测我的 Mac 麦克风何时在使用?类似于 Mikro Snitch 所做的事情吗?这可以在 Cocoa 中完成吗?
这并不是真正的 Objective-C 或 Cocoa 解决方案,但如果您愿意进行子进程调用,请尝试以下操作:
ioreg -c AppleHDAEngineInput | grep IOAudioEngineState
当音频输入处于活动状态时,您将看到
"IOAudioEngineState" = 1
。
另外,尝试搜索
IOAudioEngineNumActiveUserClients
,每个应用程序接收音频,该值都会加一。
我之前的答案不再有效并且相当脆弱(它仅适用于内部设备)。这是 PyObjC 的快速解决方案,可以相当轻松地转换为 Objective-C 或 Swift。
import AVFoundation
import CoreAudio
import struct
mic_ids = {
mic.connectionID(): mic
for mic in AVFoundation.AVCaptureDevice.devicesWithMediaType_(
AVFoundation.AVMediaTypeAudio
)
}
opa = CoreAudio.AudioObjectPropertyAddress(
CoreAudio.kAudioDevicePropertyDeviceIsRunningSomewhere,
CoreAudio.kAudioObjectPropertyScopeGlobal,
CoreAudio.kAudioObjectPropertyElementMaster
)
for mic_id in mic_ids:
response = CoreAudio.AudioObjectGetPropertyData(mic_id, opa, 0, [], 4, None)
print('Mic', mic_ids[mic_id], 'active:', bool(struct.unpack('I', response[2])[0]))
请注意,此脚本将运行一次,但如果您的应用程序没有运行循环,如此问题中所示,重复调用
AudioObjectGetPropertyData
将始终返回相同的结果。
我正在开发用于检测相机/麦克风状态的 go 模块(使用
cgo
),这是我为 IsMicrophoneOn()
精心设计的 Objective-C 实现:https://github.com/antonfisher/go-media-devices -state/blob/main/pkg/microphone/microphone_darwin.mm
我使用
kAudioHardwarePropertyDevices
获取所有音频设备(麦克风 + 扬声器),然后使用 [AVCaptureDevice deviceWithUniqueID:uid]
按设备 UID 仅过滤掉麦克风。
基于@kgutwin的解决方案,我能够找到一种方法来获取MacOS Big Sur上麦克风的活动状态。 实际上只是将
-c
与-l
交换。所以所有的荣誉都归功于@kgutwin。
ioreg -l |grep IOAudioEngineState
我使用脚本和 HomeAssistant + hass-cli 做了类似的事情。 我的 LED 使用 ESPHome 被定义为开关,但如果你的是灯,请将开关替换为灯。
haToken="YOUR_TOKEN_HERE"
device_id="YOUR_LED_DEVICE_ID_HERE"
# Store a default status of 0 to initialize oldStatus
micStatus=0
#start a loop that should never end
while true ; do
oldStatus=${micStatus}
micStatus=$(ioreg -l | grep IOAudioEngineNumActiveUserClients | sed 's/.*\(.\)$/\1/')
if [[ "${micStatus}" == "1" ]]; then
#Recording in progress!
if [[ "${oldStatus}" == "0" ]]; then
#Recording switched on from being off
#Turn on the LED
/opt/homebrew/bin/hass-cli -x --token "${haToken}" service call switch.turn_on --arguments device_id=${device_id}
fi
else
#No recording
if [[ "${oldStatus}" == "1" ]]; then
#Recording switched off from being on
#Turn the LED off
/opt/homebrew/bin/hass-cli -x --token "${haToken}" service call switch.turn_off --arguments device_id=${device_id}
fi
fi
#Sleep 5 seconds to ensure we use as little CPU as possible
sleep 5
done
希望这对大家有帮助。