macOS – Disable microphone while typing

A simple application, written in Swift and Apple Script to disable the macOS global microphone (specially during a Zoom/Teams/Skype/whatever call).

The idea is to avoid sending the “chunky” sound to the others, during a call…

How it works

Basically is a keylogger, of course, a safe keylogger (this depends on what you want to develop…).

To make it works we need to create a new macOS Application and implement the NSEvent.addGlobalMonitorForEvents:

NSEvent.addGlobalMonitorForEvents(matching: .keyDown) { event in
    print( event )
}

You can print the keyCode or the other methods in the event var to optimize the check:

print( event.keyCode )

Disable (or enable) the global microphone volume

Instead going crazy, you can enable or disable the global macOS microphone volume using Apple Script,

To do this, open “Script Editor” app and copy/paste this script:

set volume input volume 0

that of course DISABLE the volume, AKA set the microphone (input) volume to 0.

You can verify that works opening Preferences -> Audio -> Input:

Of course, the opposite is:

set volume input volume 100


Call Applescript from Swift

Now, save these script in a file or two and import in your XCode project.

Prepare a function like this:

func muteMicrophone( _ status: Bool ) {
    let enableScriptPath = Bundle.main.path(forResource: "global-enable-mic", ofType: "scpt")!
    let disableScriptPath = Bundle.main.path(forResource: "global-disable-mic", ofType: "scpt")!

    let task = Process()
    task.launchPath = "/usr/bin/osascript"
    task.arguments = [ !status ? enableScriptPath : disableScriptPath ]
    task.launch()
}

That easily run the two .scpt files if the status is true or false.

Or you can integrate the Applescript directly in Swift if you prefer…


Wrap all

You can decide your own mutation/unmutation logic, here, but what you need is this piece of code:

private var monitor: Any?
private var muteTimer: Timer?

func applicationDidFinishLaunching(_ aNotification: Notification) {
    monitor = NSEvent.addGlobalMonitorForEvents(matching: .keyDown) { event in
        if event.keyCode == 48 { return } // skip TAB for instance

        self.muteMicrophone(true)

        self.muteTimer?.invalidate()
        self.muteTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { t in
            self.muteMicrophone(false)
        })
    }
}

this piece of code, start a timer during key pressed, and if there is nothing to listen (after 1 sec), start again the microphone.


You can create now a simple status-bar (agent) application for your Mac, to put near the clock (top-right of the screen) that change icon (or color) if the microphone is disabled or not, or make it cool and sell to App-Store:

Have fun!

 

Alberto Pasca

Software engineer @ Pirelli & C. S.p.A. with a strong passion for mobile  development, security, and connected things.