RTMP Streaming / Recording

Want to preserve your video call for posterity in a recording? Or live stream it out to millions of viewers on Twitch or YouTube or whatever gives you an RTMP ingest URL?

Turn on RTMP Streaming or Recording!

In 100ms, recording and streaming are usually achieved by having a bot join your room and stream what it sees and hears to a file (recording) or an RTMP ingest URL (streaming).

Types of recordings

Apart from the RTMP stream and the browser recording, there is also a serverRecording, which can be turned on for the room for.

- Server Recording

This is used for archival purposes and cannot be stopped by method calls from SDK. This can only be enabled/disabled from the dashboard. This represents that the room was set to be recorded when it was created and all sessions within it will always be recorded for archival by the server.

- Browser Recording

This is a normal recording that can be enabled/disabled using HMSSDK method startRtmpOrRecording with toRecord as true

RTMP Streaming & Recording

The topics covered in this doc are:

  1. How to start stop streaming / recording.
  2. How to check the current status for streaming/recording.
  3. When to check the current status

Start/Stop Streaming / Recording

Let's look at the implementation for starting/stopping RTMP streaming and browser recording:

class Meeting implements HMSUpdateListener, HMSActionResultListener{ void startRtmpOrRecording({ String? meetingUrl, required bool toRecord,List<String>? rtmpUrls,double height,double width}) async { HMSResolution streamResolution = HMSResolution(height: height, width: width); HMSRecordingConfig hmsRecordingConfig = new HMSRecordingConfig( meetingUrl: meetingUrl, toRecord: toRecord, rtmpUrls: rtmpUrls,resolution: streamResolution); ///[hmsRecordingConfig]: the object of HMSRecordingConfig which we created above ///[hmsActionResultListener]: an instance of a class that implements HMSActionResultListener //Here this is an instance of a class that implements HMSActionResultListener, that is, Meeting hmsSDK.startRtmpOrRecording( hmsRecordingConfig: hmsRecordingConfig, hmsActionResultListener: this); } void stopRtmpAndRecording() { ///[hmsActionResultListener]: an instance of a class that implements HMSActionResultListener //Here this is an instance of a class that implements HMSActionResultListener, that is, Meeting hmsSDK.stopRtmpAndRecording( hmsActionResultListener: this); } void onSuccess( {HMSActionResultListenerMethod methodType = HMSActionResultListenerMethod.unknown, Map<String, dynamic>? arguments}) { switch (methodType) { ... case HMSActionResultListenerMethod.startRtmpOrRecording: //RTMP stream started successfully. We will get the update here break; case HMSActionResultListenerMethod.stopRtmpAndRecording: //RTMP stream stopped successfully break; } } void onException( {HMSActionResultListenerMethod methodType = HMSActionResultListenerMethod.unknown, Map<String, dynamic>? arguments, required HMSException hmsException}) { switch (methodType) { ... case HMSActionResultListenerMethod.startRtmpOrRecording: // Check the HMSException object for details about the error break; case HMSActionResultListenerMethod.stopRtmpAndRecording: // Check the HMSException object for details about the error break; } } }

Let's break down the implementation

To start recording, streaming or both, create an instance of HMSRecordingConfig.

HMSRecordingConfig hmsRecordingConfig = new HMSRecordingConfig( meetingUrl: "meeting_url", toRecord: "true for enabling recording", rtmpUrls: "List of URLs", resolution: "HMSResolution object for stream resolution");

Let's understand each parameter:

  1. meetingUrl: String?. The URL the 100ms bot user will open to join your room. It must allow access without any user-level interaction.

  2. rtmpUrls: List<String>. If streaming is required, this has to be one or more RTMP Ingest Urls with a max limit of 3 URLs where the stream should go. If only recording, this can be an empty list.

    • Format: rtmp://server.com/app/STREAM_KEY

    • Example: rtmp://a.rtmp.youtube.com/live2/k0jv-329m-1y7f-ktth-ck48

      • "rtmp://a.rtmp.youtube.com/live2/" - RTMP stream URL.
      • "k0jv-329m-1y7f-ktth-ck48" - RTMP stream key.
  3. toRecord: Boolean. If the recording is required, set it true. If the recording is not required, set false. This value does not affect streaming.

  4. resolution: HMSResolution. An optional value for the output resolution of the stream. For instance, the default is a landscape at 1280x720 but this could be set for a portrait mode to 720x1280 or smaller values like 480x80. The HMSResolution class takes Width and Height.

Key Notes

  • If both rtmpUrls and toRecord = true are provided, both streaming and recording will begin.
  • If only rtmpUrls are provided, only streaming will begin.
  • If only toRecord true is provided, only recording will begin.

If either one is started, the other can't be started without stopping whatever is running.

Eg: If only streaming is started then recording can't be started unless streaming is stopped first.

If both are required, they have to be started together by providing both rtmpUrls and toRecord = true.

Current Room Status

The current status for the room is always reflected in the HMSRoom object that is returned from the HMSUpdateListener.

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

stream-state

Room recording can be in one of the state at any given time:

enum HMSRecordingState { none, starting, started, paused, resumed, stopped, failed, }

Similarly, room streaming can be in one of the state at any given time:

enum HMSStreamingState { none, starting, started, stopped, failed, }

Here are the relevant properties inside the HMSRoom object which we can read to get the current recording/streaming status of the room namely:

  • hmsRtmpStreamingState - Contains info about RTMP Streaming, state attribute if set to HMSStreamingState.started indicates streaming is ON currently
  • hmsBrowserRecordingState - Contains info about Browser Recording, state attribute if set to HMSRecordingState.started indicates browser recording is ON currently
  • hmsServerRecordingState - Contains info about Server Recording, state attribute if set to HMSRecordingState.started indicates server recording is ON currently
  • hmshlsRecordingState - Contains info about HLS Recording, state attribute if set to HMSRecordingState.started indicates HLS recording is ON currently
  • hmshlsStreamingState - Contains info about HLS Streaming, state attribute if set to HMSStreamingState.started indicates HLS streaming is ON currently

Each of them is an object which contains a boolean state which lets you know the streaming or recording state in the room and error which lets you know if there was an error.

  1. HMSRtmpStreamingState an instance of HMSRtmpStreamingState, which looks like:
class HMSRtmpStreamingState { ///[error]: Gets populated if there is some error in starting the stream ///[running]: bool value `true` indicates that RTMP streaming is running ///[startedAt]: time at which RTMP streaming was started ///[state]: Contains info about current state of RTMP streaming final HMSException? error; final bool running; DateTime? startedAt; HMSStreamingState state; HMSRtmpStreamingState({required this.error, required this.running, this.startedAt, required this.state}); }
  1. browserRecordingState an instance of HMSBrowserRecordingState, which looks like:
class HMSBrowserRecordingState { ///[error]: Gets populated if there is some error in starting the browser recording ///[running]: bool value `true` indicates that browser recording is running ///[startedAt]: time at which browser recording was started ///[initialising]: flag to identify the recording initialisation status ///[state]: Contains info about current state of browser recording final HMSException? error; final bool running; final bool initialising; DateTime? startedAt; HMSRecordingState state; HMSBrowserRecordingState({required this.error, required this.running, this.startedAt, required this.state}); }
  1. serverRecordingState an instance of HMSServerRecordingState, which looks like:
class HMSServerRecordingState { ///[error]: Gets populated if there is some error in starting the server recording ///[running]: bool value `true` indicates that server recording is running ///[startedAt]: time at which server recording was started ///[state]: Contains info about current state of server recording final HMSException? error; final bool running; DateTime? startedAt; HMSRecordingState state; HMSServerRecordingState({required this.error,required this.running, this.startedAt, required this.state}); }
  1. hlsRecordingState an instance of HMSHlsRecordingState, which looks like:
class HMSHLSRecordingState { ///[error]: Gets populated if there is some error in starting the server recording ///[running]: bool value `true` indicates that hls recording is running ///[startedAt]: time at which server recording was started ///[state]: Contains info about current state of hls recording final HMSException? error; final bool running; DateTime? startedAt; HMSRecordingState state; HMSHLSRecordingState({required this.error, required this.running, this.startedAt, required this.state}); }
  1. hlsStreamingState an instance of HMSHlsStreamingState, which looks like:
class HMSHLSStreamingState { ///[running]: bool value `true` indicates that hls recording is running ///[variants] contains the information about HLS Streaming Url, meeting Url, metadata and startedAt. ///[state]: Contains info about current state of hls streaming final bool running; final List<HMSHLSVariant?> variants; HMSStreamingState state; HMSHLSStreamingState({required this.running, required this.variants, required this.state}); }

When to check for room status

The room status should be checked in three places:

  1. onJoin callback of HMSUpdateListener
  2. onRoomUpdate callback of HMSUpdateListener
  3. When hmsSDK.startRtmpOrRecording() is called
  4. When hmsSDK.stopRtmpAndRecording() is called.
  • In the onJoin(room: HMSRoom) & onRoomUpdate({required HMSRoom room, required HMSRoomUpdate update}) callback in HMSUpdateListener The properties mentioned above will be on the HMSRoom object.
  • Whenever either of the start or stop recording functions is called, their success or error callbacks are called, the values of the streaming and recording will be updated on the room object returned in onRoomUpdate. So update the instance of room in your application at that time.

Have a suggestion? Recommend changes ->

Was this helpful?

1234