Skip to content

Instantly share code, notes, and snippets.

@rgov
Created November 28, 2020 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgov/737a8388747d44f81e5792d89188859f to your computer and use it in GitHub Desktop.
Save rgov/737a8388747d44f81e5792d89188859f to your computer and use it in GitHub Desktop.
'''
This module provides a function to enable video capture from screen devices such
as attached iPhones. Only macOS hosts are supported.
enable_screen_capture_devices()
You may need QuickTime running to see the devices:
https://stackoverflow.com/questions/48166748/coremediaio-doesnt-list-iphone-camera-unless-quicktime-is-open
'''
import ctypes
# On newer macOS, this path does not actually exist on the filesystem, but the
# underlying dlopen() call should get it from the shared cache for us.
CoreMediaIO = ctypes.cdll.LoadLibrary(
'/System/Library/Frameworks/CoreMediaIO.framework/CoreMediaIO')
# From MacTypes.h
OSStatus = ctypes.c_int32
noErr = 0
# From CoreMediaIO.framework/CMIOHardwareSystem.h
kCMIOHardwarePropertyAllowScreenCaptureDevices = 0x79657320 # 'yes '
kCMIOObjectSystemObject = 1
# From CoreMediaIO.framework/CMIOHardwareObject.h
kCMIOObjectPropertyElementMaster = 0
kCMIOObjectPropertyScopeGlobal = 0x676c6f62 # 'glob'
CMIOObjectID = ctypes.c_uint32
CMIOObjectPropertySelector = ctypes.c_uint32
CMIOObjectPropertyScope = ctypes.c_uint32
CMIOObjectPropertyElement = ctypes.c_uint32
class CMIOObjectPropertyAddress(ctypes.Structure):
_fields_ = [
('mSelector', CMIOObjectPropertySelector),
('mScope', CMIOObjectPropertyScope),
('mElement', CMIOObjectPropertyElement),
]
CMIOObjectSetPropertyData = CoreMediaIO.CMIOObjectSetPropertyData
CMIOObjectSetPropertyData.argtypes = [
CMIOObjectID, # objectID
ctypes.POINTER(CMIOObjectPropertyAddress), # address
ctypes.c_uint32, # qualifierDataSize
ctypes.c_void_p, # qualifierData
ctypes.c_uint32, # dataSize
ctypes.c_void_p, # data
]
CMIOObjectSetPropertyData.restype = OSStatus
def enable_screen_capture_devices():
# Call API to allow screen capture devices
addr = CMIOObjectPropertyAddress()
addr.mSelector = kCMIOHardwarePropertyAllowScreenCaptureDevices
addr.mScope = kCMIOObjectPropertyScopeGlobal
addr.mElement = kCMIOObjectPropertyElementMaster
allow = ctypes.c_uint32(1)
err = CMIOObjectSetPropertyData(
kCMIOObjectSystemObject,
ctypes.byref(addr),
0, None,
ctypes.sizeof(allow), ctypes.byref(allow)
)
assert err == noErr
__all__ = [ enable_screen_capture_devices ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment