Virtual Camera Output
Stream AI output into Meet, Teams, and OBS
- image
- IMAGE
The name is the whole pitch: this node makes whatever image you feed it appear as a webcam in any app that reads one. Google Meet, Teams, Zoom, Discord, even OBS itself will show an "OBS Virtual Camera" device, and what they see is whatever your ComfyUI graph just spat out. So yes - you can absolutely join a meeting as a slowly-rendering alien. That's not a hypothetical; the pack's example workflow does exactly that with an LCM LoRA for speed.
It's the final brick in a real-time-ish pipeline. Upstream you'd have ComfyUI's built-in WebcamCapture node grabbing your actual camera, then a fast sampler (the shipped workflow pairs an LCM SD1.5 LoRA with 1 step) to restyle the frame, then VAEDecode → this node. SBCODE (Sean Bradley, the tutorial author behind sbcode.net) published it back in late 2023 specifically because people kept asking how to get ComfyUI output out to a virtual camera rather than just a preview window.
How it works
It's a thin wrapper around pyvirtualcam. Your IMAGE tensor gets pulled off the GPU, converted to a numpy uint8 frame, and handed to pyvirtualcam.Camera(width, height, fps). On Windows - which is what the README targets - pyvirtualcam writes into the OBS Virtual Camera driver, so OBS has to be installed for the driver to exist at all. The node runs a background thread that keeps pushing the latest frame at your chosen fps, and every time you re-run the workflow it just updates the stored frame. Neat trick: the node is also a transparent pass-through, so your IMAGE flows through to a PreviewImage unchanged.
The inputs that matter
Only four, all required, and you'll touch two of them:
image(IMAGE) - the frame to broadcast. Feed it a single frame; the code only usesimage[0], and it quietly drops an alpha channel if one's there.fps(INT, default 30, range 1–60) - the virtual camera's frame rate. Only really matters when the stream starts.continuous(BOOLEAN, default true) - keep the stream alive in the background thread instead of sending one frame and closing the camera. Leave it on.stop_stream(BOOLEAN, default false) - flip this to true to kill the stream.
Output is a single IMAGE - the same image you put in, so you can keep previewing.
Installing it
ComfyUI Manager (search "ComfyUI Virtual Webcam"), or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/Sean-Bradley/ComfyUI-Virtual-Webcam.git
# restart ComfyUI
There are no model downloads. The one dependency, pyvirtualcam>=0.14.0, auto-installs via pip the first time the node loads - convenient, but it does mean your first launch prints a "Installing missing package" line and may take a moment. After restart it shows up under SBCODE in the node menu, or just double-click and search "virtual".
Where people get burned
- OBS must be installed on Windows or there's no driver to write to. This is the #1 "it did nothing" failure.
- Don't pick "OBS Virtual Camera" as your input in
WebcamCapture- that device is reserved as the output. Select your real USB cam (or NVIDIA Broadcast). - It only updates when the graph runs. There's no continuous capture loop; you run the workflow (Run Instant) to refresh the frame, which is why the example leans on 1-step LCM. Expect a slideshow, not a fluid 30fps feed.
- Platform reality check: the README is Windows-first. On Linux, pyvirtualcam needs a
v4l2loopbackdevice instead; on macOS it needs the CoreMediaIO DAL plugin installed. Both work, but neither is plug-and-play the way the Windows/OBS path is.
For a virtual-camera stream with actual live, always-updating frames, you'll end up pairing this with something that re-triggers your graph continuously - but as a dead-simple way to get AI output into a meeting or broadcast, this is the one to grab.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| fps | INT | 301–60 | — |
| continuous | BOOLEAN | true | — |
| stop_stream | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |