CoreMediaIO Device Abstraction Layer (DAL) Minimal Example
This example project is intended to present the simplest possible implementation of a CoreMediaIO DAL plugin for creating a virtual webcam on macOS. Apple provides sample code (also modernized by @lvsti) but it's extremely painful to read and modify.
The plugin in this repo serves frames as a virtual webcam to host software (QuickTime, OBS, Chrome, etc)
๐ธ
Donating If this code is useful to you, feel free to send some cash my way to fund coffee for more late night endeavors like this! I definitely sacrificed sleep several nights to get this thing to work since Apple's docs & sample code are so bad for these APIs. Feel free to Buy Me a Coffee or PayPal me.
๐
Other Examples Other projects that have implemented a DAL plugin:
- lvsti/CoreMediaIO-DAL-Example - A direct copy of Apple's own sample code.
- webcamoid/webcamoid - An example that seems significantly different than the Apple sample code in its implementation.
Projects based on the code in this repo:
- johnboiles/obs-mac-virtualcam - This project was my motivation to build this example code. It was originally based on Apple's sample code but is now based on the code in this repo. Creates a virtual camera from the output of Open Broadcaster Software (OBS).
- Cascable Pro Webcam - Very cool piece of software that allows you to use your DSLR as a webcam.
If there are more examples to include here, please share by opening an issue!
๐
Developing To try this out:
- Build it in Xcode
- Find
CMIOMinimalSample.plugin
in Xcode's 'Products' folder - Right click
CMIOMinimalSample.plugin
and choose 'Show in Finder' - Copy the plugin bundle to
/Library/CoreMediaIO/Plug-Ins/DAL/
- Open QuickTime
- Watch the logs in Console.app for any logs prefixed with
CMIOMS
You may also need to change the codesigning to use your own personal developer identity.
Also take a look at Cameo by @lvsti. It allows you to inspect DAL plugins and see all their properties at a glance. It was very useful to me to take a known-working plugin (like lvsti/CoreMediaIO-DAL-Example and Snap Camera) and then use Cameo to understand the differences between those plugins and this plugin.
Before Shipping Code
Before you bundle this code into your software, you should change the class names to something unique! Objective-C doesn't have namespaces and so if you keep the classes named Stream
, Device
, ObjectStore
, PlugIn
etc your plugin may not work if you use it along with someone else's plugin who also didn't change the names. This can cause real bugs where your plugin won't work if someone else's plugin is installed. Typically in Objective-C you add a few letters to the front of your classes to make them unique (e.g. JBStream
, JBDevice
, JBObjectStore
, JBPlugin
).
You must also change the plugin UUID to something unique in the Info.plist. The sample uses 8457B77A-D0304458-B136-8BB5335F4512
which must be changed to a new UUID of your choosing, in both "Plug-in factory interfaces" and "Plug-in types" entries.
โ๏ธ
License This software is licensed as MIT. Do what you want with it! But please, if you find ways to improve this software, or you find bugs, please open a Pull Request so others can benefit from it! Also I'd love to see what you built with it, so please open an issue or hit me up on Twitter and show me what you've made!