Configuring Exporting¶
RT Server can export two different things from a running instance:
- Processed video - an RTSP re-stream or an HLS stream, optionally with analytics overlays burned in.
- Events and metadata - structured detections and analytics events pushed to MQTT (and other output handlers).
This tutorial covers both. Video outputs use dedicated endpoints; event outputs are configured through the instance configuration tree. All examples assume an existing instance — see Managing Instances for how to create one.
Exporting processed video¶
RTSP output¶
Enable an RTSP re-stream with POST /v1/core/instance/{instanceId}/output/rtsp:
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/output/rtsp" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"uri": "rtsp://127.0.0.1:8554/stream1"
}'
enabled-trueto start the stream,falseto stop it.uri- the RTSP URI to publish to.
Returns 204 No Content. To disable, send the same call with "enabled": false.
HLS output¶
Enable HLS with POST /v1/core/instance/{instanceId}/output/hls:
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/output/hls" \
-H "Content-Type: application/json" \
-d '{ "enabled": true }'
When enabling, the response is 200 OK and the playlist becomes available at:
http://<server-ip>:3546/hls/<instanceId>.m3u8
When disabling ("enabled": false), the response is 204 No Content.
Burning analytics overlays into the video¶
By default the exported video is the clean source. To render analytics overlays (bounding boxes, areas, tripwires) into the RTSP/HLS output, set the Output/render_preset configuration value to Default using the config pattern:
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/config" \
-H "Content-Type: application/json" \
-d '{
"path": "Output/render_preset",
"jsonValue": "\"Default\""
}'
Set jsonValue to "\"\"" (an empty string) to go back to the clean stream.
Exporting events to MQTT¶
Event export is configured by writing an output handler into the instance configuration at Output/handlers/Mqtt. The handler describes the broker connection and which event types to publish.
The handler object¶
{
"enabled": true,
"uri": "mqtt://127.0.0.1:1883/cvedia/events",
"sink": "",
"config": {
"username": "",
"password": "",
"certificate_path": "",
"encode_buffers": true,
"schema_events": [
"event-intrusion:1",
"event-line-crossing:1"
]
}
}
| Field | Description |
|---|---|
enabled |
Whether the handler is active. |
uri |
mqtt://<host>:<port>/<topic> — broker address and the topic to publish to. |
config.username / config.password |
Broker credentials (leave empty for anonymous brokers). |
config.certificate_path |
Path to a CA/client certificate for TLS connections (empty for plain MQTT). |
config.encode_buffers |
When true, image buffers such as object crops are JPEG-encoded and included (base64) in the payload. |
config.schema_events |
The list of event types to publish, each as <event-name>:<schema-version> (for example event-intrusion:1). |
Writing the handler¶
Because jsonValue must be a JSON-encoded string, the handler object is serialized before sending. This is easiest from a real language; here it is with a small Python helper:
import json, requests
BASE = "http://localhost:3546"
instance_id = "<instanceId>"
handler = {
"enabled": True,
"uri": "mqtt://127.0.0.1:1883/cvedia/events",
"sink": "",
"config": {
"username": "",
"password": "",
"certificate_path": "",
"encode_buffers": True,
"schema_events": ["event-intrusion:1", "event-line-crossing:1"],
},
}
resp = requests.post(
f"{BASE}/v1/core/instance/{instance_id}/config",
json={"path": "Output/handlers/Mqtt", "jsonValue": json.dumps(handler)},
)
print(resp.status_code) # 204
The same call with curl (note the escaped inner JSON):
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/config" \
-H "Content-Type: application/json" \
-d '{
"path": "Output/handlers/Mqtt",
"jsonValue": "{\"enabled\":true,\"uri\":\"mqtt://127.0.0.1:1883/cvedia/events\",\"sink\":\"\",\"config\":{\"username\":\"\",\"password\":\"\",\"certificate_path\":\"\",\"encode_buffers\":true,\"schema_events\":[\"event-intrusion:1\"]}}"
}'
Returns 204 No Content.
Restart the instance to apply
Output configuration is applied when the instance starts. If the instance is already running, stop and start it (or restart it) for the new handler to take effect.
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/stop"
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/start"
Available event types¶
schema_events entries are <event-name>:<version>. The current schemas (version 1) include:
- Analytics events:
event-intrusion,event-intrusion-end,event-line-crossing,event-area-enter,event-area-exit,event-loitering,event-loitering-end,event-crowd-detection,event-dwelling,event-tailgating,event-object-left-removed,event-armed-person,event-armed-person-end,event-fallen-person,event-fallen-person-end,event-count-changed,event-status-changed. - Per-object data:
track,crop,attribute.
The full set and exact field definitions for every event are published at https://bin.cvedia.com/schema/. See Reading Events with SSE for the meaning of each event and its fields.
What gets published¶
Each MQTT message on the configured topic is a JSON array of event objects. Every object carries its schema identity in $id and $version. For example, a published event-intrusion message looks like:
[
{
"$id": "event-intrusion",
"$version": 1,
"area_id": "cac021c0-8de2-4ede-905b-c5c3dca8aadb",
"area_name": "Front gate",
"event_id": "1c9cfc34-0175-4d42-bd5d-eee874a5533e",
"event_timestamp_ms": 12851,
"instance_id": "718ce082-306b-950f-af7a-9a6ba9a9de4b",
"location": { "x": 0.159, "y": 0.720, "width": 0.071, "height": 0.157 },
"object_class": "Person",
"ref_tracking_id": "14e160b3-1ab7-4def-a9a9-a75a2b8668bb",
"system_datetime": "2026-06-19T17:20:56Z",
"system_timestamp": 1781889656376
}
]
You can verify the stream with any MQTT client. Using the Mosquitto CLI:
mosquitto_sub -h 127.0.0.1 -p 1883 -t "cvedia/events" -v
Other output handlers¶
MQTT is one of several output handlers. They all follow the same Output/handlers/<Name> configuration model, where each handler has enabled, uri, sink, and a handler-specific config. The URI scheme selects the handler type (mqtt://, rtsp://, hls://, and so on). For the full list of output plugins and their options, see the Output plugins reference — in particular MQTT, REST, and WriteData.
Next steps¶
- Configuring Analytics - define the areas and tripwires that generate these events.
- Reading Events with SSE - consume events live without an external broker.
- Querying Stored Data - query exported events and analytics from the database.