Webhooks¶
Flex Video integrates with MediaMTX via webhooks to automatically create pipelines when streams are published.
Overview¶
When a stream is published to MediaMTX (via RTSP, RTMP, or WebRTC), MediaMTX triggers a webhook that:
- Creates an ephemeral pipeline
- Transcodes the incoming stream
- Outputs to the Flex Video RTSP server
- Cleans up when the stream ends
MediaMTX Configuration¶
MediaMTX is pre-configured to call Flex Video webhooks:
# mediamtx.yml (in flex-mtx container)
runOnPublish: >
curl -X PUT -H "X-API-Key: $FLEX_API_KEY"
"http://127.0.0.1:3539/flex/triggers/mediaMtx/publish?path=$MTX_PATH"
runOnUnpublish: >
curl -X DELETE -H "X-API-Key: $FLEX_API_KEY"
"http://127.0.0.1:3539/flex/triggers/mediaMtx/publish?path=$MTX_PATH"
Webhook Endpoints¶
Stream Published¶
PUT /flex/triggers/mediaMtx/publish
Called when a stream starts publishing to MediaMTX.
Query Parameters:
| Parameter | Description |
|---|---|
path | MediaMTX stream path |
pipelineId | Optional custom pipeline ID |
Headers:
Response:
Stream Unpublished¶
DELETE /flex/triggers/mediaMtx/publish
Called when a stream stops publishing.
Query Parameters:
| Parameter | Description |
|---|---|
path | MediaMTX stream path |
pipelineId | Optional custom pipeline ID |
Response:
Pipeline Creation¶
When the publish webhook is triggered:
- Pipeline ID is derived from the stream path (sanitized)
- Source is set to
rtsp://127.0.0.1:8554/{path} - Output is assigned a port in the 50000-55000 range
- KLV passthrough and extraction are enabled by default
- Pipeline is started automatically
Default Configuration¶
Triggered pipelines use these defaults:
{
"mode": "simple",
"on_demand": false,
"source": {
"uri": "rtsp://127.0.0.1:8554/<path>",
"latency_ms": 200
},
"encoding": {
"codec": "h264",
"bitrate": 2000,
"width": 1920,
"height": 1080,
"fps": 30,
"quality": 7
},
"output": {
"uri": "rtsp://0.0.0.0:<auto-port>/<pipeline-id>"
},
"klv_config": {
"pass_klv": true,
"auto_extract_geolocation": true
}
}
Pipeline ID Sanitization¶
Pipeline IDs are sanitized to remove illegal characters:
| Input Path | Pipeline ID |
|---|---|
live/camera-1 | livecamera-1 |
stream.test | streamtest |
cam@123 | cam123 |
Only alphanumeric, dashes, and underscores are allowed.
Authentication¶
Webhook endpoints require API key authentication:
curl -X PUT \
-H "X-API-Key: your-api-key" \
"http://localhost:3539/flex/triggers/mediaMtx/publish?path=live/stream"
The API key is shared between containers via the FLEX_API_KEY environment variable.
Use Cases¶
OBS Streaming¶
- Configure OBS to stream to
rtmp://server:1935/live/mystream - MediaMTX receives the stream
- Webhook creates a transcoding pipeline
- Output available at
rtsp://server:8731/mystream
RTSP Camera¶
- Configure camera to push to
rtsp://server:8554/camera1 - MediaMTX receives the stream
- Webhook creates a transcoding pipeline
- Output available at
rtsp://server:8731/camera1
WebRTC Ingest¶
- Use MediaMTX WebRTC API to publish
- Webhook creates a transcoding pipeline
- Output available as RTSP for broader compatibility
Manual Testing¶
Test webhooks without MediaMTX:
# Simulate publish
curl -X PUT \
-H "X-API-Key: $FLEX_API_KEY" \
"http://localhost:3539/flex/triggers/mediaMtx/publish?path=test-stream"
# Check pipeline created
curl http://localhost:3539/flex/pipeline/test-stream
# Simulate unpublish
curl -X DELETE \
-H "X-API-Key: $FLEX_API_KEY" \
"http://localhost:3539/flex/triggers/mediaMtx/publish?path=test-stream"
Troubleshooting¶
Pipeline Not Created¶
- Check MediaMTX logs:
docker logs flex-mtx - Verify
FLEX_API_KEYmatches in both containers - Check API logs:
docker logs flex-manager
Authentication Failed¶
Ensure X-API-Key header is set and matches FLEX_API_KEY.
Pipeline Cleanup Failed¶
If pipelines aren't cleaned up:
- Check if unpublish webhook fired
- Manually delete:
curl -X DELETE http://localhost:3539/flex/pipeline/<id>
Port Exhaustion¶
If ports 50000-55000 are exhausted:
- Stop unused pipelines
- Check for zombie pipelines
- Restart flex-manager to reset port allocation