Skip to main content

Publish camera frames to MQTT

Video Input opens a camera, network stream, or file on the broker host and publishes each frame as a JPEG data-URI. Dashboards and Coreflux HUB can drop that payload straight into an image tag. You start and stop capture with MQTT events.
Like a photo booth on a timer. You press start, and a new picture lands on the topic at the rate you chose — not a video file, a series of JPEGs.

When to use this

Use TYPE VIDEO_INPUT when a dashboard, barcode decode, or action needs still frames from a local camera, an RTSP or HTTP(S) camera, or a video file. FFmpeg must be on the broker host (or in the slim image). The connector does not talk to camera drivers itself.
Do not set WITH FORMAT. That keyword belongs to models. Every frame this connector publishes is a JPEG data-URI (data:image/jpeg;base64,…).

Pick the source that matches the camera. Each tab is a full connector: a config block plus start and stop events.

Quick Start

Store the RTSP URL in an environment variable so the password never sits in LoT:
Publish any payload to the start topic to begin. Frames then arrive on DESTINATION_TOPIC until you publish to the stop topic.

Configuration

string
required
Camera, URL, or file. webcam:N on macOS and Linux. video=Device Name on Windows. An rtsp://, http://, or https:// URL, or a file path, on any host. Prefer GET ENV or GET SECRET when the URL contains a password.
string
MQTT topic for JPEG frames. A START event uses this topic. A CAPTURE event can override it.
string
How many frames to publish per second, from 1 to 60. On a local camera this is the publish rate. Many cameras only capture at 15 or 30 fps in hardware; 5 still works as the rate on the topic.
string
Output width in pixels. Set it together with HEIGHT.
string
Output height in pixels. Set it together with WIDTH.
string
JPEG quantizer from 1 to 31. Lower numbers keep more detail and publish larger payloads. 5 is a balanced start. This is not a 1–100 percentage.
WIDTH, HEIGHT, and QUALITY apply to the JPEG on MQTT. They do not reconfigure the camera’s own encoder. Broker logs redact user:pass@ in RTSP and HTTP URLs. HTTP(S) sources use a 10 second timeout and the user-agent CorefluxVideoInput/1.0. RTSP uses TCP with the same timeout.

Capture sources

webcam:N is rejected on Windows. Device indexes are not stable in DirectShow, so use video= plus the exact name. A raw /dev/video0, or a Windows name without video=, is treated as a file path and skips the local-camera retries. On start, a local camera tries several input profiles until one stays open. Network URLs and files are a single attempt.

List devices on the broker host

If macOS capture fails immediately, allow Camera access for the process that started the broker.

Events

string
required
START, STOP, CAPTURE <N> FRAMES, CAPTURE <N> SECONDS, or CAPTURE <N> MINUTES. CAPTURE 1 and CAPTURE 1 FRAME take one picture.
string
required
Topic that runs the event. Keep control topics separate from the frame topic.
string
Override for a snapshot or a timed clip. Continuous START uses the topic on VIDEO_INPUT_CONFIG.
There is no motion or per-frame callback on the connector. Every decoded frame goes to DESTINATION_TOPIC. Failures show up in the broker log and on $SYS/Coreflux/Routes/{RouteName}/status. You can also publish -checkRouteConnection <RouteName> to $SYS/Coreflux/Command. An action can start a named event without a control publish:

Docker and FFmpeg

Install FFmpeg on the broker host and confirm ffmpeg -version there. The slim broker image includes FFmpeg on amd64 and arm64. The minimal image does not, and arm/v7 does not. RTSP and HTTP work in Docker with no camera hardware. A local camera needs the device node inside the container.

Payload size

JPEG on MQTT is much larger than sensor telemetry. Start at 5 fps, 640×480, and QUALITY 5. If subscribers or the HUB fall behind, lower FRAME_RATE or raise QUALITY (a larger quantizer) before you increase width and height. For a live camera, shed frames instead of blocking publishers:
See Connector overload.

Pair with Video Output

TYPE VIDEO_OUTPUT serves those JPEGs as an HTTP MJPEG stream. Set its source topic to this connector’s frame topic.
Operators open http://<broker-host>:8080/entrance. The same frame topic can feed a Barcode decode event. Audio Input is the microphone equivalent: raw PCM chunks instead of JPEGs, also through FFmpeg.

Best Practices

WITH SOURCE GET ENV "CAMERA_RTSP_URL" or GET SECRET. Do not paste rtsp://user:password@… into the connector.
webcam:N on macOS and Linux. video=Exact Name on Windows. A missing video= prefix is opened as a file.
Put START and STOP on …/control/… topics. Publishing START on the frame topic mixes commands with JPEG payloads.
USB cameras rarely appear inside macOS or Windows Docker Desktop. Use RTSP or HTTP unless the broker runs on Linux with a device mount.

Troubleshooting

ffmpeg -version on the broker host. Install FFmpeg there, or switch to the slim image.
Use webcam:0 on macOS and Linux. On Windows use video= plus the DirectShow name.
ls -l /dev/video*. Plug in the camera or pass --device /dev/video0 into the container.
List devices with ffmpeg -list_devices true -f dshow -i dummy and set WITH SOURCE "video=…".
Grant Camera access to the process that launched the broker. Close other apps using the camera. Try webcam:1 for a USB camera.
The timeout is 10 seconds. From the broker host, confirm the URL is reachable and that RTSP allows TCP. Put the full URL in GET ENV.
Lower FRAME_RATE, shrink WIDTH and HEIGHT, or raise QUALITY. Add ADD ROUTE_CONFIG with OVERLOAD_POLICY realtime.

Next Steps

Audio Input

Publish microphone PCM the same way, through FFmpeg on the broker host.

Barcode Connector

Decode a symbol from the JPEG topic.
Last modified on October 21, 2026