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:
- How to start stop streaming / recording.
- How to check the current status for streaming/recording.
- 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:
-
meetingUrl: String?. The URL the 100ms bot user will open to join your room. It must allow access without any user-level interaction.
-
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.
-
-
toRecord: Boolean. If the recording is required, set it
true
. If the recording is not required, set false. This value does not affect streaming. -
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
andtoRecord = 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:
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,running
attribute if true indicates streaming is ON currentlyhmsBrowserRecordingState
- Contains info about Browser Recording,running
attribute if true indicates browser recording is ON currentlyhmsServerRecordingState
- Contains info about Server Recording,running
attribute if true indicates server recording is ON currently
Each of them is an object which contains a boolean running
which lets you know if it's active in the room right now and error
which lets you know if there was an error.
- 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 final HMSException? error; final bool running; DateTime? startedAt; HMSRtmpStreamingState({required this.error, required this.running, this.startedAt}); }
- 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 final HMSException? error; final bool running; final bool initialising; DateTime? startedAt; HMSBrowserRecordingState({required this.error, required this.running, this.startedAt}); }
- 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 final HMSException? error; final bool running; DateTime? startedAt; HMSServerRecordingState({required this.error,required this.running, this.startedAt}); }
When to check for room status
The room status should be checked in three places:
onJoin
callback ofHMSUpdateListener
onRoomUpdate
callback ofHMSUpdateListener
- When
hmsSDK.startRtmpOrRecording()
is called - When
hmsSDK.stopRtmpAndRecording()
is called.
- In the
onJoin(room: HMSRoom)
&onRoomUpdate({required HMSRoom room, required HMSRoomUpdate update})
callback inHMSUpdateListener
The properties mentioned above will be on theHMSRoom
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.