Skip to content

Instantly share code, notes, and snippets.

@shoover
Last active January 27, 2025 23:49
Show Gist options
  • Select an option

  • Save shoover/e3350400f758fb38891d539d13b3c730 to your computer and use it in GitHub Desktop.

Select an option

Save shoover/e3350400f758fb38891d539d13b3c730 to your computer and use it in GitHub Desktop.
Mic check
#!/usr/bin/env python3
import time
from Foundation import NSObject, NSLog
import objc
import sys
# Load CoreAudio framework
objc.loadFramework('CoreAudio')
# Load Audio Toolbox framework for additional audio session info
objc.loadFramework('AudioToolbox')
def get_mic_permissions():
# Load AVFoundation framework for permission check
objc.loadFramework('AVFoundation')
from AVFoundation import AVCaptureDevice, AVAuthorizationStatusAuthorized
auth_status = AVCaptureDevice.authorizationStatusForMediaType_('vide')
return auth_status == AVAuthorizationStatusAuthorized
class AudioDeviceListener(NSObject):
def init(self):
self = super(AudioDeviceListener, self).init()
if self is None:
return None
return self
def get_input_devices(self):
from CoreAudio import (
AudioObjectGetPropertyData,
AudioObjectGetPropertyDataSize,
AudioObjectPropertyScope,
AudioObjectPropertyElement,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMain,
kAudioHardwarePropertyDevices,
kAudioDevicePropertyDeviceName,
kAudioDevicePropertyStreamConfiguration,
kAudioDevicePropertyDeviceIsAlive,
kAudioDevicePropertyDeviceIsRunning,
AudioObjectID,
)
# Get all audio devices
property_address = objc.malloc(16, tags="rv") # Allocate memory for property address
property_address.mSelector = kAudioHardwarePropertyDevices
property_address.mScope = kAudioObjectPropertyScopeGlobal
property_address.mElement = kAudioObjectPropertyElementElement
dataSize = objc.sizeof_void_p
status, dataSize = AudioObjectGetPropertyDataSize(
AudioObjectID(1),
property_address,
0,
None,
dataSize,
)
if status:
NSLog("Error getting devices size: %d", status)
return []
num_devices = dataSize // 4
devices_array = objc.malloc(dataSize, tags="rv")
status, _ = AudioObjectGetPropertyData(
AudioObjectID(1),
property_address,
0,
None,
dataSize,
devices_array,
)
if status:
NSLog("Error getting devices: %d", status)
return []
input_devices = []
devices = devices_array[:num_devices]
for device in devices:
# Get device name
property_address.mSelector = kAudioDevicePropertyDeviceName
dataSize = 128
device_name = objc.malloc(dataSize, tags="rv")
status, _ = AudioObjectGetPropertyData(
AudioObjectID(device),
property_address,
0,
None,
dataSize,
device_name,
)
if status:
continue
# Check if device is an input device
property_address.mSelector = kAudioDevicePropertyStreamConfiguration
property_address.mScope = 1 # Input scope
dataSize = objc.sizeof_void_p
status, dataSize = AudioObjectGetPropertyDataSize(
AudioObjectID(device),
property_address,
0,
None,
dataSize,
)
if status:
continue
buffer = objc.malloc(dataSize, tags="rv")
status, _ = AudioObjectGetPropertyData(
AudioObjectID(device),
property_address,
0,
None,
dataSize,
buffer,
)
if status:
continue
# Check if device is running
property_address.mSelector = kAudioDevicePropertyDeviceIsRunning
is_running = objc.malloc(4, tags="rv")
status, _ = AudioObjectGetPropertyData(
AudioObjectID(device),
property_address,
0,
None,
4,
is_running,
)
if status:
continue
if is_running[0]:
input_devices.append({
'id': device,
'name': device_name.decode('utf-8').strip('\x00'),
'is_running': bool(is_running[0])
})
return input_devices
def main():
print("Checking microphone usage...")
# Check microphone permissions
if not get_mic_permissions():
print("Warning: Microphone permissions not granted")
print("Please grant microphone permissions in System Preferences > Security & Privacy > Privacy > Microphone")
return
listener = AudioDeviceListener.alloc().init()
try:
while True:
active_devices = listener.get_input_devices()
if not active_devices:
print("\nNo active input devices found")
else:
print("\nActive input devices:")
print("-" * 50)
for device in active_devices:
print(f"Device: {device['name']}")
print(f"ID: {device['id']}")
print(f"Status: {'Active' if device['is_running'] else 'Inactive'}")
print("-" * 50)
time.sleep(1) # Update every second
except KeyboardInterrupt:
print("\nMonitoring stopped")
if __name__ == '__main__':
main()
tell application "Microsoft Teams"
activate
delay 1 -- Give Teams time to come to foreground
end tell
-- Main logging function with generic recursion
on logElement(element, indentLevel)
set indent to ""
repeat indentLevel times
set indent to indent & " "
end repeat
try
set elementRole to role of element
on error
set elementRole to "unknown role"
end try
try
set elementName to name of element
on error
set elementName to "unnamed"
end try
-- Log basic element info
log indent & "Name: " & elementName & ", Role: " & elementRole
-- Try to get any additional properties that might be interesting
try
if value of element exists then
log indent & " Value: " & value of element
end if
end try
try
if description of element exists then
log indent & " Description: " & description of element
end if
end try
try
if help of element exists then
log indent & " Help: " & help of element
end if
end try
-- Generic child element recursion
try
-- Get all UI elements regardless of container type
set childElements to UI elements of element
if length of childElements is greater than 0 then
repeat with childElement in childElements
my logElement(childElement, indentLevel + 1)
end repeat
end if
on error errorMessage
-- Silently ignore errors for elements that can't have children
end try
end logElement
tell application "System Events"
tell process "Microsoft Teams"
-- Log process info
log "=== Starting UI Element Logging for Microsoft Teams ==="
log "Process name: " & name
-- Get and log info for all windows
try
set windowList to windows
log "Number of windows: " & (count of windowList)
repeat with windowIndex from 1 to count of windowList
set currentWindow to item windowIndex of windowList
-- Log window info
log "=== Window " & windowIndex & " ==="
log "Window name: " & name of currentWindow
try
log "Window size: " & size of currentWindow
log "Window position: " & position of currentWindow
end try
-- Log all elements in the window
try
set topLevelElements to UI elements of currentWindow
repeat with element in topLevelElements
my logElement(element, 1)
end repeat
on error windowElementError
log "Error accessing elements in window " & windowIndex & ": " & windowElementError
end try
log "=== End of Window " & windowIndex & " ==="
end repeat
on error windowError
log "Error accessing windows: " & windowError
end try
log "=== UI Element Logging Complete ==="
end tell
end tell
pip install pyobjc-framework-CoreAudio pyobjc-framework-AudioToolbox pyobjc-framework-AVFoundation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment