MacOS - detect when camera is turned on/off

Viewed 2633

I want to automate a personal workflow that is based on camera usage on my MBP.

Basically I want to know if any of the cameras (built-in or USB) has been turned on or off, so I can run a program or script I'll create.

I think it's OK if I need to poll for the cameras statuses but an event or callback based solution would be ideal

3 Answers

This seems to work.

❯  log stream | grep "Post event kCameraStream"
2020-12-01 14:58:53.137796-0500 0xXXXXXX   Default     0x0                  XXX    0    VDCAssistant: [com.apple.VDCAssistant:device] [guid:0xXXXXXXXXXXXXXXXX] Post event kCameraStreamStart
2020-12-01 14:58:56.431147-0500 0xXXXXXX   Default     0x0                  XXX    0    VDCAssistant: [com.apple.VDCAssistant:device] [guid:0xXXXXXXXXXXXXXXXX] Post event kCameraStreamStop
2020-12-01 14:58:56.668970-0500 0xXXXXXX   Default     0x0                  XXX    0    VDCAssistant: [com.apple.VDCAssistant:device] [guid:0xXXXXXXXXXXXXXXXX] Post event kCameraStreamStart

Some of the numbers in the output are redacted with Xs because I don't know what they mean. :)

log stream --predicate 'eventMessage contains "Post event kCameraStream"' works up to macOS Big Sur, but not in macOS Monterey. You'll have to use a slightly different predicate:

$ log stream --predicate 'subsystem contains "com.apple.UVCExtension" and composedMessage contains "Post PowerLog"'
Filtering the log data using "subsystem CONTAINS "com.apple.UVCExtension" AND composedMessage CONTAINS "Post PowerLog""
Timestamp                       Thread     Type        Activity             PID    TTL  
2021-10-27 12:21:13.366628+0200 0x147c5    Default     0x0                  353    0    UVCAssistant: (UVCExtension) [com.apple.UVCExtension:device] UVCExtensionDevice:0x1234005d7 [0x7fe3ce008ca0] Post PowerLog {
    "VDCAssistant_Device_GUID" = "00000000-1432-0000-1234-000022470000";
    "VDCAssistant_Power_State" = On;
}
2021-10-27 12:21:16.946379+0200 0x13dac    Default     0x0                  353    0    UVCAssistant: (UVCExtension) [com.apple.UVCExtension:device] UVCExtensionDevice:0x1234005d7 [0x7fe3ce008ca0] Post PowerLog {
    "VDCAssistant_Device_GUID" = "00000000-1432-0000-1234-000022470000";
    "VDCAssistant_Power_State" = Off;
}

As far as I know, you can poll for the camera usage with:

$ lsof -n | grep "AppleCamera"

or change "AppleCamera" with the driver name of an external camera. Other relevant names to try are: "USBVDC" or "VDCAssistant" or "FaceTime" (or "iSight" in older Macs).

You should get one line with the name and pid of the process using the webcam or nothing, which means that it is not in use.

You could check for all of the keywords and decide that the camera is in use if any of these keywords give you something back.

The -n option is to skip resolving DNS names of IP connections and this speeds the command a lot.

As a side note, I use this app to know when any app is using the microphone and/or webcam: OverSight

Related