Media Gateway (RTMP Gateway / RTLS Ingress)
Stream keys, stream templates, online streams, mute/disconnect, appconfig and reconciliation.
Media Gateway (called rtls/ingress in the interface definition, product name "RTMP gateway") addresses bringing external RTMP pushes into an RTC channel: a broadcaster pushes with OBS or a similar tool to the address we hand out, and viewers in the channel see it exactly like a normal participant.
Three concepts need to be kept apart:
| Concept | Role | Lifecycle |
|---|---|---|
| streamkey | Push credential bound to a target (which channel, which uid, when it expires) | Single-use / short-lived; delete it when done |
| stream template | A template of push parameters (transcoding, jitter buffer) | Long-lived, reusable |
| online stream | One stream currently being pushed (a session); it can be queried, muted and disconnected | Created and ended with the push |
Global configuration
curl -s -X PUT "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/rtls/ingress/appconfig" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
-H 'Content-Type: application/json' \
-d '{"settings":{"defaultStreamTemplate":"standard-720p"}}'settings.defaultStreamTemplate points at a template id; pushes that do not carry a template use it.
Creating a streamkey (broadcaster-side push credential)
curl -s -X POST "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/rtls/ingress/streamkeys" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
-H 'Content-Type: application/json' \
-d '{"settings":{"channel":"weekly-sync","uid":"30001","expiresAfter":3600,"templateId":"standard-720p"}}'| Field | Type | Description | |
|---|---|---|---|
channel | string | Target channel | |
uid | string \ | number | Identity inside the channel (a string account name works) |
expiresAfter | integer | Validity in seconds | |
templateId | string | Template id to use |
data.streamKey in the response is the stream key. OBS setup: put rtmp://<your-gateway-domain>/live in Server and the streamKey in Stream Key.
Stream templates
# create / overwrite a template
curl -s -X PUT "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/rtls/ingress/stream-templates/standard-720p" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
-H 'Content-Type: application/json' \
-d '{"settings":{"transcoding":{"width":1280,"height":720,"frameRate":30,"bitrate":2000},"jitterBuffer":{"sizeMs":500}}}'
# partial update
curl -s -X PATCH "$NIMEET_API_BASE/cn-shanghai/v1/projects/$APP_ID/rtls/ingress/stream-templates/standard-720p" \
-H "Authorization: Basic $NIMEET_CUSTOMER_BASIC" \
-H 'Content-Type: application/json' \
-d '{"settings":{"jitterBuffer":{"sizeMs":300}}}'transcoding controls the transcoding parameters and jitterBuffer controls the jitter buffer: lower sizeMs when chasing low latency for live (the trade-off is higher sensitivity to stutter).
Online stream management
| Operation | Endpoint | Description |
|---|---|---|
| List | GET /{region}/v1/projects/{appId}/rtls/ingress/online-streams (optionally filtered by channel) | Returns the sessions that are currently pushing |
| Query one | GET /{region}/v1/projects/{appId}/rtls/ingress/online-streams/{sid} | Details and state of that stream |
| Mute | POST /{region}/{version}/projects/{appId}/rtls/ingress/online-streams/mute/{sid} | Server-side mute (does not kick the user) |
| Disconnect | DELETE /{region}/v1/projects/{appId}/rtls/ingress/online-streams/{sid} | Disconnects the push and ends the session |
Typical integration sequence
- The server creates a streamkey (binding channel + uid + template) and hands the
streamKeyto the broadcaster; - The broadcaster pushes from OBS, the gateway establishes a session, and that uid appears in the channel (other clients receive
user-published); - You can see the
sidinonline-streamsandmuteorDELETEit when needed; - When the push ends the session disappears; once the streamkey expires or is explicitly
DELETEd, it can no longer be used.
Difference from Media Push
| Media Gateway (ingress) | Media Push (egress) | |
|---|---|---|
| Direction | External stream → channel | Channel → RTMP address |
| Typical scenario | OBS pushing into a meeting or a live stream | Channel content pushed to a CDN |
| Resources | streamkey / template / online-stream | converter |
The two can be combined: OBS pushes into the channel (Gateway) → the mixed stream is then pushed to a CDN (Push).
Quotas and errors
| Scenario | Response |
|---|---|
| Service not enabled | 403 service_not_enabled |
| More than 10 stream templates | 429 streaming_quota_exceeded (at most 10 templates can exist under one app id) |
| Pushing after the streamkey expired | The gateway rejects the handshake (that sid never appears in online-streams) |
| The same uid pushing twice | Arbitrated by the media plane: the later connection replaces the earlier one and the old sid becomes invalid; the control plane only reflects real sessions |
| Invalid template dimension | 400 validation, with field-level errors in details |
End-to-end example
node run-all.mjs --only=2020-media-gateway-lifecycle.mjs: appconfig → create template → create streamkey → query streamkey → query online streams → delete streamkey → delete template (writes, so it needs --all).