Skip to main content

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:

await client.video.updateCallType("livestream", {
settings: {
broadcasting: {
enabled: true,
rtmp: {
enabled: true,
quality: VideoRTMPSettingsRequestQualityEnum._1080P,
layout: {
name: VideoLayoutSettingsRequestNameEnum.SPOTLIGHT,
}
}
}
},
});

Model

RTMPSettingsRequest

NameTypeDescriptionConstraints
enabledboolean--
layoutLayoutSettingsRequestLayout for the composed RTMP stream-
qualitystring (360p, 480p, 720p, 1080p, 1440p, portrait-360x640, portrait-480x854, portrait-720x1280, portrait-1080x1920, portrait-1440x2560)Resolution to set for the RTMP stream-

LayoutSettingsRequest

NameTypeDescriptionConstraints
external_app_urlstring--
external_css_urlstring--
namestring (spotlight, grid, single-participant, mobile, custom)-Required
optionsobject--

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"
}]
});

Model

StartRTMPBroadcastsRequest

NameTypeDescriptionConstraints
broadcastsRTMPBroadcastRequest[]List of broadcasts to startRequired, Minimum: 1, Maximum: 1

RTMPBroadcastRequest

NameTypeDescriptionConstraints
layoutLayoutSettingsRequestIf provided, will override the call's RTMP settings layout-
namestringName identifier for RTMP broadcast, must be unique in callRequired
qualitystring (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_keystringIf provided, will be appended at the end of stream_url-
stream_urlstringURL for the RTMP server to send the call toRequired

LayoutSettingsRequest

NameTypeDescriptionConstraints
external_app_urlstring--
external_css_urlstring--
namestring (spotlight, grid, single-participant, mobile, custom)-Required
optionsobject--

Stopping an RTMP broadcast by name

call.stopRTMPBroadcast("youtube_channel");

Stopping all RTMP broadcasts for a call

call.stopAllRTMPBroadcasts();

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

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

Did you find this page helpful?