Streaming with HLS

Developers can start live streaming sessions with HLS (HTTP Live Streaming) with Daily. HLS is a multi-bitrate network adaptive streaming protocol. It means that the audience watching your stream receives fair-quality video playback over a cellular network while also supporting the best-quality playback on a high-speed connection. The downside is latency; there is roughly a 12-to-20 second delay between what is happening "live". If you are hosting your own streams and want control on where that video output is stored on the Internet, then this guide to HLS is for you.

If you want your audience to watch your streams on Twitch, YouTube, and other providers, then you'll want to take advantage of Daily's RTMP support.

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.

The HLS architecture at Daily

HLS architecture

How to configure HLS

HLS support is configured through a room property called streaming_endpoints:

In this example, we are creating an HLS live streaming configuration named hls_s3.

Each object inside the streaming_endpoints array represents a live streaming configuration:

  • name: the label that will be used in daily-js to reference a specific configuration
  • type: either rtmp or hls for an RTMP and HLS configuration
  • rtmp_config: the RTMP configuration details (when type is rtmp)
    • url: the RTMP url
  • hls_config: the HLS configuration details (when type is hls)
    • save_hls_recording: true when you want to save the output of the live stream once the stream is finished; otherwise, false. This can be used as a replacement for cloud recording.
    • variants: specifies all the HLS variants to generate. Specified as array with following properties.
      • width: output width.
      • height: output height.
      • fps: output FPS.
      • bitrate: output bitrate in kilobits per second (kbps).
      • iframe_only: whether this is iframe-only variant.
    • storage: the storage details when save_hls_recording is set to true
      • bucket_name: the name of the S3 bucket where the HLS output will be stored
      • bucket_region: the AWS region of the S3 bucket (this is an S3 bucket that you own)
      • assume_role_arn: The Amazon Resource Name to assume in order to write to the S3 bucket
      • path: (deprecated, use path_template) the S3 key path prefix for where to store the output HLS. The final master.m3u8 path template is <bucket_name>/<path>/<mtgSessionId>/master.m3u8.
      • path_template: define the template to derive the S3 key path prefix where HLS is stored.

For a complete list of the properties available on streaming_endpoints, check out the rooms configuration.

Daily only supports sending HLS output to your AWS S3 bucket. There is no support for storing HLS video within the Daily infrastructure. Check out our guide on storing call recordings in a custom Amazon S3 bucket.

Use the /rooms API to configure the streaming_endpoints for your room:

save_hls_recording parameter

HLS is a livestream, i.e. it is available for consumption soon after startLiveStreaming() call. This livestream can also be saved for later viewing with save_hls_recording.

save_hls_recording: true: During the livestream, the m3u8 playlist is [EVENT type playlist] and segments are not deleted. At the end of streaming, the playlist is converted to [VOD type playlist].

save_hls_recording: false: During the livestream, new segments are appended to the m3u8 playlist and old segments are deleted from the playlist (as well as from S3). This keeps only the most recent 5 segments in the playlist at any point of time.

Starting an HLS live stream

These examples will work with daily-js or react-native-daily-js.

In the code example below, we use startLiveStreaming() on call to start the HLS stream, after completing the streaming_endpoints configuration. call represents a DailyCall client, which is initiated in projects utilizing either call object or Daily Prebuilt projects.

In this example, hls_s3 is the name of endpoint that we defined as a streaming_endpoints object.

Note that if your use case requires both HLS and cloud recording or HLS and RTMP in the same meeting session, then multiple instances are required, each with a unique instanceId. HLS cannot run with same instanceId as RTMP or cloud recording.

Enabling HLS playback for your audience

We recommend that the HLS video be served from a CDN (like CloudFront). We advise you to not serve it directly from an S3 bucket. In order to reduce security risk, your S3 resources should implement a "least privilege access" model. From a geographical perspective, serving the HLS video through a CDN ensures that the video is served closest to where your audience is located on the planet.

CDN setup is outside the scope of this guide. We have an example project that creates the necessary AWS infrastructure to serve HLS video through CloudFront.

Current limitations for HLS with Daily

Daily does not store HLS output

Output is stored in one of your AWS S3 buckets. This allows you to have more control over your data and its storage and access.

Daily supports 4 bitrates out-of-the-box

WidthHeightFrames per SecondBitrate(kbps)
19201080302500
1280720301500
64036024700
32018024200

Daily also generates an i-frames-only-stream of 640x480, used for trick play features. These bitrates cover most use cases and content types (eg. screenshares and talking heads). These default bitrates can be changed via streaming-endpoint-config.

HLS configuration is only available as a room property

HLS configuration (streaming_endpoints) is only available as a room property, not a domain property. This means it cannot currently be set as a default at the domain level, but can be used by any room under your domain.

There is a maximum of 20 streaming_endpoints

You can store up to 20 streaming_endpoints configuration objects per room.