How to detect microphone usage on OS X?

前端 未结 4 763
梦如初夏
梦如初夏 2021-01-18 04:11

Is there a way to detect when the microphone of my Mac is in use? Similar to what Mikro Snitch does? Can this be done in Cocoa?

相关标签:
4条回答
  • 2021-01-18 04:49

    Is there a way to detect when the microphone of my Mac is in use?

    Simple answer - Yes, but it's not going to be easy!

    Can this be done in Cocoa?

    As the documentation states: -

    The Cocoa application layer is primarily responsible for the appearance of apps and their responsiveness to user actions

    So this doesn't cover the microphone and if it did, it would be too high level for what you want.

    A detailed answer on how to do this is complex and too broad for Stack Overflow. However, to set you off in the right direction, you need to create an IOKit kernel extension driver (KEXT) and have a good understanding of the I/O Registry

    0 讨论(0)
  • 2021-01-18 04:53

    My previous answer no longer works and was rather brittle (it only applied to the internal device). This is a quick solution for PyObjC, which can be translated to Objective-C or Swift reasonably easily.

    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]))
    
    

    Note that this script will work once through, but if your app does not have a run loop, as observed in this question, repeated calls to AudioObjectGetPropertyData will always return the same result.

    0 讨论(0)
  • 2021-01-18 04:54

    This isn't really an Objective-C or Cocoa solution, but if you're willing to do a subprocess call, try this:

    ioreg -c AppleHDAEngineInput | grep IOAudioEngineState
    

    You will see "IOAudioEngineState" = 1 when audio input is active.

    Also, try searching for IOAudioEngineNumActiveUserClients which increases by one for each app taking in audio.

    0 讨论(0)
  • 2021-01-18 05:02

    I'm working on go module that detects camera/microphone state (using cgo) and here is my crafted Objective-C implementation for IsMicrophoneOn(): https://github.com/antonfisher/go-media-devices-state/blob/main/pkg/microphone/microphone_darwin.mm

    I used kAudioHardwarePropertyDevices to get all audio devices (microphones + speakers) and then [AVCaptureDevice deviceWithUniqueID:uid] to filter out only microphones by device UID.

    0 讨论(0)
提交回复
热议问题