Nodes/ComfyUI-Frame-Step/Camera Capture
ComfyUI Node

Camera Capture

Grab a Camera Frame Straight From the Server — No Browser Permission Popup

By NobutakaKuroki·Created about a month ago·Updated about a month ago· 1
Camera Capture
    • image
    device_index0
    width0
    height0

    Camera Capture grabs a single frame from a camera and hands you a plain IMAGE. That's the whole pitch, and the point is in the where: it opens the camera on the machine running the ComfyUI server using OpenCV, not on your browser like core's Webcam Capture does.

    Why does that distinction matter? Core's Webcam Capture asks the browser for camera access (navigator.mediaDevices.getUserMedia) and builds a tall widget stack - live preview plus a captured-image slot - right inside the node. This one skips all of that: no browser permission popup, no stacked widgets, just a IMAGE output that drops straight into any workflow. If core's webcam node has been fighting you, this is the clean alternative.

    How it works

    Under the hood it's cv2.VideoCapture(device_index) with a few thoughtful touches:

    • The capture device stays open across runs and is only reopened if you change device_index - so a loop of queues doesn't pay the camera-open cost every time.
    • Right after opening, it reads and discards five warmup frames. Most webcams' auto-exposure and auto-white-balance haven't settled on the very first frame, and the author didn't want you capturing that garbage.
    • Frames come back as BGR from OpenCV, so it converts to RGB and normalizes to the float tensor ComfyUI expects.
    • If width or height is set above 0, it resizes to that; 0 means "keep the camera's native resolution."

    It also uses the IS_CHANGED = NaN trick, so every run grabs a fresh frame instead of replaying the first cached result - which is exactly what you want from a live source, though it does mean this node is always "dirty" in ComfyUI's cache. That's the price of liveness, and it's correct.

    The inputs

    Three integer inputs, and honestly only one you'll change:

    • device_index - which camera. Default 0, which is the built-in webcam on most machines. Have more than one camera? Try 1, then 2.
    • width / height - target size, default 0 = keep native resolution. Set either (or both) to resize. Set to 0 to leave that dimension alone.

    The output is image (IMAGE), one frame, ready to feed downstream.

    Where people get burned - read this before wiring it up

    The server-vs-browser difference cuts both ways. On a normal local install, the server and the browser are the same machine, so it doesn't matter. But on a remote setup - ComfyUI running on a cloud box or a different machine on your network - this node captures the camera attached to that machine, not your laptop's. Core's Webcam Capture does the opposite. If you're doing live video-to-video and wondering why you're looking at a server rack instead of your face, that's why.

    If the camera can't be opened at all, you get a clear RuntimeError and a red node - usually means the device_index is wrong or the camera's in use by another app. And note the pack depends on opencv-python-headless; that's fine for server-side capture, there's no GUI to worry about.

    Installing it

    It's one of four nodes in comfyui-frame-step - install the pack once. Via ComfyUI Manager, search "comfyui-frame-step", or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/NobutakaKuroki/comfyui-frame-step
    cd comfyui-frame-step && pip install -r requirements.txt
    

    Then restart ComfyUI. Dependencies are av and opencv-python-headless; no models, no downloads. It's MIT-licensed teaching code from Dr. Nobutaka Kuroki at Kobe University, and the README's whole point is that Camera Capture is a drop-in swap for Video Frame Reader in every lesson - same IMAGE output, so every workflow that consumes the reader's frame accepts a live camera instead. If a sample video is boring you, that's a genuinely fun substitution.

    CategoryKULab/Video

    Inputs (3)

    NameTypeDefaultDescription
    device_indexINT00–10
    widthINT00–8192
    heightINT00–8192

    Outputs (1)

    NameTypeDescription
    imageIMAGE