Live streaming with Daily

Video stream with a Live red indicator indicating that the call is being live streamed

Daily live streaming lets you broadcast a real-time, multi-participant video call to the streaming platform of your choice.

Live streaming sends RTMP streams, real-time data like call participants' video and audio, to a specific location over the internet where interested people can tune into the broadcast.

Webinars, conference panels, classes, concerts, all hands meetings at large companies, and many other live events are all good candidates for live streaming.

This guide covers:

Receive a $15 credit for free

Try Daily pay-as-you-go features for free! New accounts have a $15 credit automatically applied when you add a credit card to the account. Learn more about pay-as-you-go features on our pricing page.

Key live streaming terms

These definitions reflect how we use the key terms in this guide, and how we use them at Daily. We know folks often have opinions when it comes to this kind of lexicon, though, so consider this our caveat!


An encoder is a piece of software (or potentially hardware) that encodes, meaning compresses, the RTMP stream. Daily is an encoder.


A transcoder is a piece of software that ingests the RTMP stream and transcodes it into an HLS stream. You might be familiar with transcoders like YouTube Live, Mux, AWS IVS, or others.

HLS stream

HLS, or HTTP live streaming, is an HTTP-based adaptive bitrate streaming communications protocol developed by Apple Inc.

How a live stream works at a high level

  1. A person with live streaming permissions joins a video call.
  2. That person starts a live stream.
  3. The encoder encodes an RTMP stream.
  4. The encoder starts to send the RTMP stream to the transcoder.
  5. The transcoder begins transcoding the RTMP stream into an HLS stream.
  6. Viewers around the world watch the stream live.*

*Live in this case means a delay of 3-20 seconds, depending on the transcoder.

Daily live streaming

Daily manages audio, video, and screen share streams for calls of up to 100,000 participants. (Read our interactive live streaming guide for more information.) Daily live streaming encodes the collective call stream to a transcoder of your choice, and provides options to customize the stream layout. No external dependencies or multimedia streaming libraries are required.

By default, Daily live streaming outputs video at 1920x1080, 30 fps encoded as H.264 at 5 Mbps. The currently set maximum is 3840x2160 (4K UHD), but please reach out if you have other requirements.

Daily live streaming outputs audio encoded as AAC at 96 Kbps. Contact us if you have additional needs.

All live streams must occur over an SFU network connection.

There are two parts to using Daily live streaming: setting up prerequisite accounts and values, and using those values in an application to create a Daily live stream.

Prerequisite accounts and values to use Daily live streaming

Using Daily live streaming requires the following:

  1. A pay-as-you-go Daily account (i.e. you've added your credit card information to your account)
  2. A Daily room
  3. A meeting token that makes its user a meeting owner or streaming admin
  4. An account with a transcoding provider
  5. An rtmpUrl value

1. Pay-as-you-go Daily account

Accessing live streaming is as simple as adding a credit card to your account. Live streaming is a pay-as-you-go service. See our pricing page for more details.

2. Daily room

You can either create a room from the dashboard or from the command line using the Daily API /rooms endpoint:

3. Appropriate meeting token for the room

Only a meeting owner or a streaming admin can start a live stream. Use the Daily /meeting-tokens endpoint to create a meeting token that makes its user a meeting owner or a streaming admin:


4. An account with a transcoder to set up a destination for the stream

Some popular transcoders include Amazon IVS, Mux, YouTube Live, LivePeer, Azure, and Cloudflare. These are not the only options, but they're the ones we most frequently hear about. Please reference each provider's site for individual pricing and documentation details.

5. rtmpUrl value, made from the transcoder's ingest URL and stream key

A transcoder's ingest URL and stream key are typically available in the account dashboard. Combine the two into an rtmpUrl value. The rtmpUrl will be passed to the Daily startLiveStreaming() method, and tell Daily where to send the stream.

The rtmpUrl will vary depending on the provider. For example, some ingest URLs specify a string as a part or multiple parts of the domain. In the table below, those strings are represented as DOMAIN.

ProviderTemplate rtmpUrl
Amazon IVSrtmp(s)://
YouTube Livertmp://

Azure does not provide a stream key. If you're using Azure and Daily, please use an arbitrary stream key (like the foo placeholder in this template).

If you're using a transcoder not listed here, a generic template is:


Contact us if you run into any trouble.

How to create a Daily live streaming app

1. Initialize a Daily call

Call createFrame() to embed Daily Prebuilt.

Or, to build a custom video chat interface, use createCallObject().

2. Pass your owner or streaming admin token to the call on join()

Make sure the application knows when an owner or streaming admin has joined the call. Only they can start the live stream.

3. Pass the rtmpUrl to the startLiveStreaming() method

Connect this function to a UI element like a button.

4. Call stopLiveStreaming() to stop the live stream

Wire this function to a UI element like button.

Listening for live streaming events

The Daily API fires events corresponding to things that happen on a call. Those events can be responded to with event listeners.

Current live streaming related events include:

This snippet, for example, displays a console message when the live stream starts:

The event object describes the action:

Check out our live streaming events documentation for more details on each event.

Live streaming layout options

You can pass configuration properties to either startLiveStreaming() or updateLiveStreaming() to control the look and feel of the stream.

The available configuration properties currently include:

  • height, width: Controls the resolution of the stream. This can only be set once via startLiveStreaming().
  • backgroundColor: Specifies the background color of the stream, formatted as #rrggbb or #aarrggbb string. This can only be set once via startLiveStreaming().
  • layout: an object specifying the way participants’ videos are laid out in the stream. A preset key with one of the following values must be provided:
    • "default": This is the default grid layout, which renders participants in a grid, or in a single column vertical grid to the right, if a screen share is enabled. Optionally, a max_cam_streams integer key can be provided to specify how many cameras to include in the grid. The default value is 20, which is also the maximum number of cameras in a grid. The maximum may be increased at a later date.

Example "default" layout:

Grid of nine participants on a video call

Example screenshare "default" layout:

A screenshare takes up the main video call screen with participant videos to the right vertically

  • "single-participant": Use this layout to stream only a single participant's audio and video. The selected participant’s session ID must be specified via a session_id key.

Example "single-participant" layout:

One participant video screen takes up the entire video call

  • "active-participant": This layout focuses on the current speaker, and places up to 9 other cameras to the right in a single column vertical grid in the order in which they last spoke.

Example "active-participant" layout:

One participant video screen takes up the majority of space on a call with two others to the right in a small vertical bar

  • "portrait": Allows for mobile-friendly layouts. The video will be forced into portrait mode, where up to two participants will be shown. An additional variant key may be specified. Valid values are "vertical" for a vertical grid layout (the default), and "inset" for having one participant's video take up the entire screen and the other inset in a smaller rectangle. Participants' videos are scaled and cropped to fit the entire available space. Participants with the is_owner flag are shown lower in the grid (vertical variant), or full screen (inset variant).

Example "portrait" layout with "vertical" variant:

Two participant screens on a mobile vertical video call

Example "portrait" layout with "inset" variant:

Two participant screens on a mobile vertical video call

  • "custom": Allows for a custom layout, including text overlay, image overlay, and more. This option provides access to Daily's Video Component System, which allows you to pass composition_params and session_assets to customize the appearance of your recording. It is available for live streaming and "cloud" recordings. A full list of available parameters is available in the reference docs. You can also test available options with the VCS Simulator.

Example "custom" layout with a text overlay:

Text overlay and dominant video layout example

Multiple live streaming instances

Daily allows multiple recordings/streaming instances per room. This can be useful for generating independent layouts for different types of users. For example, one can live stream in portrait mode for mobile participants and landscape for those on desktop.

An instanceId can be passed to the startLiveStreaming() or startRecording() methods. By passing unique instance IDs, multiple live streams/recordings instances can be started. Each instance is independently controllable with the updateLiveStreaming()/updateRecording() methods and stopLiveStreaming()/stopRecording() methods.

All streaming and recording event objects include an instanceId, which applications can use to observe the status of individual instances of streaming/recording.

Daily uses the same underlying process for live streaming and recording. If the same instance ID is passed to startRecording() and startLiveStreaming(), both will use the same layout. Calls to updateLiveStreaming() and updateRecording() affect each other.

The number of allowed instances per room is controlled by the Daily domain configuration property max_streaming_instances_per_room. Contact us to configure this property for your domain.