Webcam Capture CV2 (Swwan)
Live frames for realtime diffusion
- image
Point a camera feed into a ComfyUI graph and let it run. The author's own one-liner is the pitch - "Captures a frame from a webcam using CV2. Can be used for realtime diffusion with autoqueue" - and that's the entire use case: webcam → img2img or ControlNet → preview, cycling as fast as your GPU allows. Pair it with the frontend's Auto Queue and you have a live filter, a pose-driven render, or a very expensive mirror.
It sits in the pack's Experimental group, and that's fair. This is the one node in the batch whose behaviour depends on your machine, your drivers, and whether Zoom is open.
How it works
It's a thin wrapper over cv2.VideoCapture. On first run it opens the camera for cam_index, asks the driver for width×height, and stores the handle on the node instance - so between queues the camera stays open and grabs are instant. If you change cam_index, it releases and reopens. Then, per execution: read a frame, crop it to the rectangle at x, y, width, height, flip BGR to RGB (frame[..., [2, 1, 0]]), scale to 0–1 floats, and return it as a one-frame IMAGE batch.
That crop is worth reading twice, because it's the same width/height doing two jobs. The node asks the camera for that resolution and crops that rectangle out of the returned frame. Drivers are free to ignore the request - plenty of webcams hand back 640×480 or 1920×1080 no matter what you ask for - so your crop coordinates are relative to whatever actually came back, not to what you typed.
The node also declares an IS_CHANGED hook. That's the engine's escape hatch for nodes whose output can't be cached, and a live camera frame is the definition of not reusable. It's the same hook, from the other direction, that makes a node always re-run and quietly defeats caching behind it - here it's a feature, not a bug.
Inputs and outputs
x, y, width, height (INT, 0–4096), cam_index (INT, 0–255), release (BOOLEAN, default off). Output: image (IMAGE), one frame.
release is the polite switch: turn it on and the node closes the camera handle when it runs, which is how you hand the webcam back to another app without restarting ComfyUI. It costs you the open-handle speed on the next run.
Install
Part of aining2022/ComfyUI_Swwan, and the one dependency that actually matters for this node - OpenCV - is already in the pack's requirements:
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/aining2022/ComfyUI_Swwan.git
cd ComfyUI_Swwan
python -m pip install -r requirements.txt
Restart, hard-refresh, search Swwan under the Experimental category. There's no model to download; the work is all local camera I/O.
Where people get burned
"Could not open webcam" is almost always contention. Cameras are exclusive resources. A browser tab holding a preview, OBS, Teams, or a previous ComfyUI instance still holding the handle will all lock you out. Close everything else, then try again; release exists so you don't have to restart.
Windows camera privacy settings. The OS can block app access to the camera outright, and the error looks like a broken node rather than a permission toggle.
Wrong camera index. cam_index 0 is not always the one you think it is - laptops with an IR sensor or a virtual camera installed by OBS can shuffle the numbering. Try 1 and 2 before concluding the node is broken.
Frames change size between runs. If the driver ignores your resolution request, the crop can come back a different size than your latent expects, and downstream nodes complain about mismatched dimensions. Fix the size deliberately after the capture - a resize node - rather than trusting the driver.
It's a realtime loop, so the graph budget is the frame rate. Steps, resolution and how many control nodes sit in the chain decide how fast the loop actually turns. Nobody gets 30fps out of a full-resolution SDXL pipeline; expect a slide show and design around it.
Don't expect much validation. The pack's own hardware notes are candid that device-based features like webcam and screen capture are validated separately from its CPU image tests, and that registering successfully is not the same as capturing successfully. If your first live-diffusion attempt is a black rectangle, it's the environment, not your prompt.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| x | INT | 00–4096 | — |
| y | INT | 00–4096 | — |
| width | INT | 5120–4096 | — |
| height | INT | 5120–4096 | — |
| cam_index | INT | 00–255 | — |
| release | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |