HLS Streaming & Recording

HLS Streaming allows for scaling to millions of viewers in near real time. You can give a link of your web-app which will be converted to a HLS feed by our server and can be played across devices for consumption.

Behind the scenes, this will be achieved by having a bot join your room and stream what it sees and hears. Once the feed is ready, the server will give a URL which can be played using any HLS Player.

Note that the media server serving the content in this case is owned by 100ms. If you're looking for a way to stream on YouTube, Twitch, etc. then please have a look at our RTMP streaming docs here.

Permissions

Can't let just anyone stream and record using HLS. First, you need to create a role with the "HLS livestream" and "Beam Recording" permissions.

You can check if you (local peer) have permission to HLS stream as follows -

const localPeer = await hmsInstance.getLocalPeer(); // Permissions are available on `HMSRole` object of Local Peer const localPeerPermissions: HMSPermissions = localPeer.role?.permissions; // Check if Local Peer has HLS Live stream permission const canHLSStream: boolean = localPeerPermissions?.hlsStreaming;

Starting HLS Stream

HLS can be started in two ways depending on the level of customization you need -

  1. Default View: The simplest view to just begin a stream with default UI and parameters.
  2. Custom Views: To use your own UI for HLS streaming, you need to provide your own web-app URL for our bot to join and stream. Also, we can record the stream.

Default View

Begins a stream with default parameters.

You can use startHLSStreaming method available on HMSSDK instance to start the HLS Stream with default parameters as follows -

try { await hmsInstance.startHLSStreaming(); console.log('HLS Stream Start Success'); } catch (error) { console.log('HLS Stream Start Error: ', error); }

Custom View

To use our own browser UI for HLS, you'll need to pass in a meeting URL. The 100ms bot will open this URL to join your room, so it must allow access without any user level interaction.

Let's understand this by following steps:

Create an HMSHLSConfig instance

HMSHLSConfig object will be used to start the HLS Stream with customizations.

import { HMSHLSConfig, HMSHLSRecordingConfig, HMSHLSMeetingURLVariant } from '@100mslive/react-native-hms'; const hlsURLVariant = new HMSHLSMeetingURLVariant({ meetingUrl: 'https://...app.100ms.live/streaming/meeting...', metadata: '' }); const hlsRecordingConfig = new HMSHLSRecordingConfig({ singleFilePerLayer: false, videoOnDemand: false }); const hlsConfig = new HMSHLSConfig({ hlsRecordingConfig: hlsRecordingConfig, meetingURLVariants: [hlsURLVariant] });

Let's look at how HMSHLSConfig object looks like -

interface HMSHLSConfig { hlsRecordingConfig?: HMSHLSRecordingConfig; meetingURLVariants?: HMSHLSMeetingURLVariant[]; }

Now, Let's look at its properties one by one:

  • hlsRecordingConfig

    To record the HLS stream you may specify an HMSHLSRecordingConfig object within the HMSHLSConfig config object.

    Here's what the HMSHLSRecordingConfig looks like -

    interface HMSHLSRecordingConfig { singleFilePerLayer: boolean; videoOnDemand: boolean; }
    1. singleFilePerLayer if the desired end result is a mp4 file per HLS layer. false by default.
    2. videoOnDemand if the desired end result is a zip of m3u8 and all the chunks, false by default.
  • meetingURLVariants

    This is a list of HMSHLSMeetingURLVariant objects. In the future, it'll be possible to start HLS Stream for multiple such URLs for the same room. So it's a list but currently only the first element of the list is used. To distinguish between multiple URLs an additional field metadata can be passed.

    Here's what the HMSHLSMeetingURLVariant looks like -

    interface HMSHLSMeetingURLVariant { meetingUrl: string; metadata: string; }
    1. meetingUrl URL of the meeting you wish to record
    2. metadata meta-data (any extra info to identify the URL) you wish to pass with the URL.

Call startHLSStreaming method on HMSSDK instance

After creating config (HMSHLSConfig) object, You can use startHLSStreaming method available on HMSSDK instance with HMSHLSConfig object to start the HLS Stream as follows -

Make sure you have above mentioned permissions for starting HLS Stream.

try { // Calling `startHLSStreaming` with config created in above step await hmsInstance.startHLSStreaming(hlsConfig); console.log('Start Hls Success'); } catch (error) { console.log('Start Hls Error: ', error); }

Stopping HLS Stream

You can use stopHLSStreaming method available on HMSSDK instance to stop HLS Streaming. This will stop all the streaming variants.

try { await hmsInstance.stopHLSStreaming(); console.log('Stop Hls Success'); } catch (error) { console.log('Stop Hls Error: ', error); }

Want to see how this works in a live project? Take a look at our Advanced Example App.

Current Room Status

The current status for the room is always reflected in the HMSRoom object.

This can be used to show the live stream status on UI something similar to this:

stream-state

hlsStreamingState is the property inside the HMSRoom object which you can read to get the current HLS streaming status of the room.

This object contains a boolean running which lets you know if HLS is running in the room right now. Also, It contains a list of m3u8 URLs variants, which you can use along with react-native-video library to display HLS Stream on the screen.

hlsStreamingState is an instance of HMSHLSStreamingState, which looks like:

interface HMSHLSStreamingState { running: boolean; variants: HMSHLSVariant[]; startedAt?: Date; error?: HMSException; state: HMSStreamingState; }
  1. running - true indicates that HLS streaming is running

  2. variants - This represents a live stream to one or more HLS URLs in the container of HMSHLSVariant. Which looks like:

interface HMSHLSVariant { hlsStreamUrl?: string; // It contains m3u8 URL which we will use to show the stream meetingUrl?: string; // URL of the room which is getting streamed metadata?: string; // Extra info about the room corresponding to meetingUrl which is passed in `HMSHLSMeetingURLVariant` while starting HLS startedAt?: Date; // time at which HLS Stream was started playlistType?: HMSHLSPlaylistType; // Enum to differentiate whether a stream is seekable or non-seekable. For seekabable it is set to `HMSHLSPlaylistType.DVR` and for non-seekable it's set to `HMSHLSPlaylistType.noDVR`. }

HMSStreamingState is a enum which can have the following values:

enum HMSStreamingState { NONE, STARTING, STARTED, STOPPED, FAILED, }

When to check for room status

The room status should be checked in following two places -

  1. Inside onJoinListener function which is subscribed to HMSUpdateListenerActions.ON_JOIN event

  2. Inside onRoomListener function which is subscribed to HMSUpdateListenerActions.ON_ROOM_UPDATE event. The type property will be HMSRoomUpdate.HLS_STREAMING_STATE_UPDATED.

Key Tips

  • If you're using the dashboard web app from 100ms, please make sure to use a role which doesn't have publish permissions, for beam tile to not show up.

  • If using your own web app, do put in place retries for API calls like tokens etc. just in case any call fails. As human users, we're used to reloading the page in these scenarios which is difficult to achieve in the automated case.

  • Make sure to not disable the logs for the passed-in meeting URL. This will allow for us to have more visibility into the room, refreshing the page if join doesn't happen within a time interval.


Have a suggestion? Recommend changes ->

Was this helpful?

1234