await client.video.updateCallType("livestream", {
settings: {
broadcasting: {
enabled: true,
rtmp: {
enabled: true,
quality: VideoRTMPSettingsRequestQualityEnum._1080P,
layout: {
name: VideoLayoutSettingsRequestNameEnum.SPOTLIGHT,
}
}
}
},
});
RTMP broadcasts
RTMP broadcasting allows you to forward a call to any external streaming service that supports RTMP(s) as input. All major platforms like Twitch, Youtube, Facebook, … support it. Multiple broadcasts can be added for the same call, allowing it to send a live call to multiple providers at the same time.
Understanding RTMP broadcasting
RTMP is a protocol initially developed by Adobe for streaming audio, video, and data over the internet. Although RTMP is no longer the dominant streaming protocol, it’s still widely used for live streaming because of its low latency and compatibility with platforms.
RTMP broadcasting refers to the process of sending a live video stream from a source (like Stream server) to an external streaming platform (like Youtube).
How It Works
- Stream API gets the media streams from your call and composes them into a single stream.
- Stream API encodes and packages the stream into RTMP with settings suitable for live streaming.
- The target platform takes this RTMP stream, and processes it. Typically, services like Youtube re-encode it (if necessary) and broadcast the stream to viewers in various formats and resolutions, using protocols like HLS or DASH.
Pre-requisites
Getting a stream url and key
Platforms that support RTMP ingestion provide a stream url (the server where the stream will be sent) and a stream key (unique identifier for your stream).
Configuring the layout for your rtmp broadcast
As previously mentioned, the call will be composed into a single stream following a layout:
- You can choose from one of our pre-defined layouts.
- Theming/branding is possible by changing layout parameters (colors, logos, positioning or elements, …)
- For more advanced / complex theming customization, you can build your own webapp and use it as the layout of the call.
You can set the desired RTMP broadcast quality and layout for a call type (ex. ‘livestream’) with:
client.video.update_call_type(
name='livestream',
settings=CallSettingsRequest(
broadcasting=BroadcastSettingsRequest(
enabled=True,
rtmp=RtmpSettingsRequest(
enabled=True
quality="1080p",
layout=LayoutSettingsRequest(
name="spotlight",
),
)
)
),
)
response, err := client.Video().UpdateCallType(ctx, callTypeName, &getstream.UpdateCallTypeRequest{
Settings: &getstream.CallSettingsRequest{
Broadcasting: &getstream.BroadcastSettingsRequest{
Enabled: getstream.PtrTo(true),
Rtmp: &getstream.RTMPSettingsRequest{
Enabled: getstream.PtrTo(true),
Quality: getstream.PtrTo("1080p"),
Layout: &getstream.LayoutSettingsRequest{
Name: "spotlight",
},
},
},
},
})
curl -X PUT "https://video.stream-io-api.com/api/v2/video/calltypes/livestream?api_key=${API_KEY}" \
-H "Authorization: ${TOKEN}" \
-H "stream-auth-type: jwt" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"broadcasting": {
"enabled": true,
"rtmp": {
"enabled": true,
"quality": "1080p",
"layout": {
"name": "spotlight"
}
}
}
}
}'
Model
RTMPSettingsRequest
Name | Type | Description | Constraints |
---|---|---|---|
enabled | boolean | - | - |
layout | LayoutSettingsRequest | Layout for the composed RTMP stream | - |
quality | string (360p, 480p, 720p, 1080p, 1440p, portrait-360x640, portrait-480x854, portrait-720x1280, portrait-1080x1920, portrait-1440x2560) | Resolution to set for the RTMP stream | - |
LayoutSettingsRequest
Name | Type | Description | Constraints |
---|---|---|---|
external_app_url | string | - | - |
external_css_url | string | - | - |
name | string (spotlight, grid, single-participant, mobile, custom) | - | Required |
options | object | - | - |
All calls created with that call type will have those Settings. You can also update the call and override these settings before starting the RTMP broadcast. It’s also possible to just pass them as optional parameters when starting it.
User permissions
To start and stop an RTMP broadcast, users need the following capabilities:
start-broadcast-call
stop-broadcast-call
Starting an RTMP broadcast
call.startRTMPBroadcasts({
broadcasts: [{
name: "youtube_channel",
stream_url: "rtmps://x.rtmps.youtube.com/live2",
stream_key: "your_stream_key"
}]
});
call.start_rtmp_broadcasts(
broadcasts=[
RTMPBroadcastRequest(
name='youtube_channel', stream_url='rtmps://x.rtmps.youtube.com/live2', stream_key='your_stream_key'
)
],
)
call.StartRTMPBroadcasts(ctx, &getstream.StartRTMPBroadcastsRequest{
Broadcasts: []getstream.RTMPBroadcastRequest{
{
Name: "youtube_channel",
StreamUrl: "rtmps://x.rtmps.youtube.com/live2",
StreamKey: getstream.PtrTo("your_stream_key"),
},
},
})
curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/rtmp_broadcasts?api_key=${API_KEY}" \
-H "Authorization: ${TOKEN}" \
-H "stream-auth-type: jwt" \
-H 'content-type: application/json' \
-d '{
"broadcasts": [
{
"name": "youtube_channel",
"stream_url": "rtmps://x.rtmps.youtube.com/live2",
"stream_key": "your_stream_key"
}
]
}'
Model
StartRTMPBroadcastsRequest
Name | Type | Description | Constraints |
---|---|---|---|
broadcasts | RTMPBroadcastRequest[] | List of broadcasts to start | Required, Minimum: 1, Maximum: 1 |
RTMPBroadcastRequest
Name | Type | Description | Constraints |
---|---|---|---|
layout | LayoutSettingsRequest | If provided, will override the call's RTMP settings layout | - |
name | string | Name identifier for RTMP broadcast, must be unique in call | Required |
quality | string (360p, 480p, 720p, 1080p, 1440p, portrait-360x640, portrait-480x854, portrait-720x1280, portrait-1080x1920, portrait-1440x2560) | If provided, will override the call's RTMP settings quality | - |
stream_key | string | If provided, will be appended at the end of stream_url | - |
stream_url | string | URL for the RTMP server to send the call to | Required |
LayoutSettingsRequest
Name | Type | Description | Constraints |
---|---|---|---|
external_app_url | string | - | - |
external_css_url | string | - | - |
name | string (spotlight, grid, single-participant, mobile, custom) | - | Required |
options | object | - | - |
Stopping an RTMP broadcast by name
call.stopRTMPBroadcast("youtube_channel");
call.stop_rtmp_broadcast(name='youtube_channel')
call.StopRTMPBroadcast(ctx, "youtube_channel", &getstream.StopRTMPBroadcastsRequest{})
curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/rtmp_broadcasts/youtube_channel/stop?api_key=${API_KEY}" \
-H "Authorization: ${TOKEN}" \
-H "stream-auth-type: jwt" \
-H 'content-type: application/json' \
-d '{}'
Stopping all RTMP broadcasts for a call
call.stopAllRTMPBroadcasts();
call.stop_all_rtmp_broadcasts()
call.StopAllRTMPBroadcasts(ctx, &getstream.StopAllRTMPBroadcastsRequest{})
curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/rtmp_broadcasts/stop?api_key=${API_KEY}" \
-H "Authorization: ${TOKEN}" \
-H "stream-auth-type: jwt" \
-H 'content-type: application/json' \
-d '{}'
RTMP broadcast state
You can check if the call is being broadcasted like this:
const resp = await call.getOrCreate();
// If HLS or any RTMP broadcast active
const isBroadcasting = resp.call.egress.broadcasting;
// Only check for RTMP broadcasts
const rtmpBroadcasts = resp.call.egress.rtmps
const isRtmpBroadcasting = rtmpBroadcasts.length > 0
response = call.get()
# If HLS or any RTMP broadcast active
print(f"broadcasting: {response.data.call.egress.broadcasting}")
# Only check for RTMP broadcasts
rtmp_broadcasts = response.data.call.egress.rtmp_s
is_rtmp_broadcasting = len(rtmp_broadcasts) > 0
print(f"rtmp broadcasting: {is_rtmp_broadcasting}")
response, err := call.Get(ctx, &getstream.GetCallRequest{})
// If HLS or any RTMP broadcast active
fmt.Printf("broadcasting: %v", response.Data.Call.Egress.Broadcasting)
// Only check for RTMP broadcasts
rtmp_broadcasts := response.Data.Call.Egress.Rtmps
is_rtmp_broadcasting := len(rtmp_broadcasts) > 0
fmt.Printf("rtmp broadcasting: %v", is_rtmp_broadcasting)
# Check RTMP state: resp.call.egress.rtmps
curl -X GET "https://video.stream-io-api.com/api/v2/video/call/livestream/${CALL_ID}?api_key=${API_KEY}" \
-H "Authorization: ${TOKEN}" \
-H "stream-auth-type: jwt"
Events
These events are sent to users connected to the call and your webhook/SQS:
Consuming the broadcast
The consuming part depends on the service being used, but a mapping can be done on your app’s server-side between the name of the broadcast and the specifics of the platform.
Quickstart examples
Livestream your call to your YouTube channel
To use your Stream call as a video source for YouTube, you first need to set up a live stream in YouTube Studio. Follow this link to your Livestreaming Dashboard, enable it if needed.
On that page you’ll find your Stream key and the suggested Stream URL. Copy both and add them to the start request.
On YouTube side, check the status of the stream from the Livestreaming Dashboard, you should see that your call is live!
To stop it then at any given point in time, use the stop by name or stop all endpoints.
Note: YouTube also provides a way to stop it from their end, although it will stop the broadcast it won’t stop the RTMP connection from Stream to Youtube, so you should call always stop, or end the call.
FAQ
How much latency does RTMP broadcast add?
- RTMP itself doesn’t add much latency, as it is a 1-1 protocol. Another thing then is how is the livestream content processed, for example, in the case of platforms like Youtube the latency is increased when the content is broadcasted through HLS/DASH protocol. Check Youtube’s options
- Understanding RTMP broadcasting
- Pre-requisites
- RTMPSettingsRequest
- LayoutSettingsRequest
- Starting an RTMP broadcast
- StartRTMPBroadcastsRequest
- RTMPBroadcastRequest
- LayoutSettingsRequest
- Stopping an RTMP broadcast by name
- Stopping all RTMP broadcasts for a call
- RTMP broadcast state
- Events
- Consuming the broadcast
- Quickstart examples
- FAQ