Nodes/comfyui_live_input_stream/MJPEG Stream Live Input Stream
ComfyUI Node

MJPEG Stream Live Input Stream

Feed an IP Camera (or Any MJPEG Stream) Straight Into ComfyUI

By wouterverweirder·Created 11 months ago·Updated 9 days ago· 7
MJPEG Stream Live Input Stream
  • image
  • IMAGE
◄stream_url►
◄trim_left0►
◄trim_right0►
◄trim_top0►
◄trim_bottom0►

This is the node for everything that speaks MJPEG: IP and security cameras, video servers, and the newer crop of depth cams like the OAK 4D Pro that push MJPEG streams over the network. You type in a URL, and the feed shows up in a live preview and comes out the other end as a plain IMAGE you can wire into a monitoring, detection, or enhancement pipeline.

The name undersells it. "Live input stream" is technically accurate, but the genuinely clever part is hiding underneath: the MJPEG URL you paste is fetched by a proxy running inside ComfyUI itself, not by your browser. That proxy exists for one reason - CORS. Browsers refuse to render multipart/x-mixed-replace streams from random origins, which is exactly what every cheap IP camera sends. So the pack registers a small server route, GET /live_input_stream/mjpeg_proxy?url=..., that fetches the stream server-side with aiohttp and relays it back with permissive CORS headers. Your browser happily draws each frame into a canvas, applies the trims, uploads the result as a PNG, and the thin LoadImage-based Python node turns it into a tensor. The other two nodes in this pack don't need this trick; it's the MJPEG node's whole reason for existing.

The inputs that matter

Only a few, and they're friendly:

  • stream_url - paste the MJPEG endpoint here. It's a plain single-line string (the field is explicitly not multiline). You'll typically grab this from your camera's docs or its ONVIF/HTTP page.
  • trim_left / trim_right / trim_top / trim_bottom - pixels cut from each edge, applied live in the preview. With a fixed camera this is how you drop a static area out of the frame before the model ever sees it.
  • image - the DOM widget hosting the live preview, plus the Load Stream and Stop Stream buttons. Load Stream is your "go"; Stop Stream tears the connection down without killing the node.

The output is a single IMAGE, so it feeds anything image-shaped: VAEEncode, a ControlNet preprocessor, an IP-Adapter reference slot, or a preview. A security-cam feed → canny → ControlNet setup that redraws your driveway in a chosen style is both a great demo and, depending on your sense of humor, a hobby.

Installing it

Same as its siblings in the pack:

cd ComfyUI/custom_nodes
git clone https://github.com/wouterverweirder/comfyui_live_input_stream

...then restart ComfyUI, or search "ComfyUI Live Input Stream" in ComfyUI Manager. Zero extra Python dependencies (the pack's pyproject.toml dependency list is empty - aiohttp, which the proxy uses, comes with ComfyUI) and no model files. The whole install is one clone and a restart.

Where people get burned

  • The stream must be reachable from the server. The proxy fetches the URL from the machine running ComfyUI. A camera on your local network is fine if ComfyUI is on that same network; it will not work if the camera is only reachable from your laptop's browser while ComfyUI sits somewhere else.
  • Auth-protected cameras can frustrate. Many IP cams want a username and password. The node passes the URL through as-is - if your camera needs credentials, you'll usually have to bake user:pass@host into the URL, and cameras that use cookie or digest auth may simply not connect. You get a red "Unable to load MJPEG stream" message either way.
  • Streams drop. Cameras disconnect, feeds stutter, and the node reacts with "Stream error: Connection lost." There's no auto-reconnect - hit Load Stream and it's back. There's also a 10-second timeout on the initial load, so a slow-to-respond camera will look dead before it isn't.
  • It's MJPEG-only. This node will not parse RTSP, RTMP, or HLS - those are different beasts entirely. If your camera only does RTSP, you'll need to republish it as MJPEG (FFmpeg makes this easy) or use a different approach. Check your camera's HTTP page for a /stream/video.mjpeg-style endpoint before you blame the node.
  • Same browser/throughput caveats as the rest of the pack. The node has to be visible in the UI for capture to run, every frame is a PNG upload plus your pipeline, and temp files accumulate. "Live" here means "however fast your graph can chew," not real-time.

If you own a security camera, an OAK, or any MJPEG source, this is the simplest on-ramp into a ComfyUI graph there is - paste the URL, press Load Stream, and wire the output wherever your imagination runs out.

CategoryLive Input Stream

Inputs (6)

NameTypeDefaultDescription
stream_urlSTRING—
imageMJPEG_STREAM_ADVANCED—
trim_leftINT00–16384—
trim_rightINT00–16384—
trim_topINT00–16384—
trim_bottomINT00–16384—

Outputs (1)

NameTypeDescription
IMAGEIMAGE—