Subscribe: Management & Events
This guide covers managing Subscriber behavior and reacting to runtime events.
Managing Subscriber Streams (React Native)
Detecting When a Stream's Video Dimensions Change
A stream's video dimensions can change if a stream published from a mobile device resizes (for example, due to device orientation changes) or if a screen-sharing source window is resized.
When a stream's video dimensions change, the Session object dispatches a streamPropertyChanged event, with changedProperty set to videoDimensions.
<OTSubscriber
eventHandlers={{
streamVideoDimensionsChanged: (event) => {
console.log('stream video dimensions changed -- stream ID:', event.streamId);
console.log('new dimensions:', event.width, 'x', event.height);
},
}}
/>
Setting the Preferred Frame Rate and Resolution
When subscribing to a stream that uses the scalable video feature, you can set preferredResolution to 'auto' to automatically manage Subscriber video resolution and optimize CPU/network usage.
For advanced control, set the preferred frame rate and resolution for the subscribed stream:
<OTSubscriber
properties={{
preferredFrameRate: 15,
preferredResolution: { width: 640, height: 480 },
}}
/>
These are hints, not commands. The Media Router selects the closest available layer that fits the subscriber's actual network conditions. They have no effect in relayed sessions, when scalable video is disabled, or when the negotiated codec is H.264. For other techniques to reduce resource usage in large sessions, see the Single Peer Connection guide.
Detecting When Streams Leave a Session
When a remote stream leaves a session, the OTSubscriber component dispatches a streamDestroyed event. The event includes details such as streamId, name, reason, hasAudio, hasVideo, and videoType. For full details on the event and its reason values, see the Subscribe diagnostics guide.
<OTSubscriber
eventHandlers={{
streamDestroyed: (event) => {
console.log('Stream stopped. Reason: ' + event.reason);
},
}}
/>
Custom Rendering of Subscribers
By default, OTSubscriber renders child views for subscriber videos. You can also provide a render function to fully control rendering using renderView:
<OTSubscriber
renderView={(streamId) => (
<View style={styles.subscriberTile}>
<OTSubscriberView streamId={streamId} style={styles.video} />
</View>
)}
/>
Setting Stream Properties
Set global properties for all subscribers via the subscriberProperties prop on OTSession, or set per-stream properties via the properties prop on OTSubscriber. For the full list of available properties, see the OTSubscriber API reference.
// Global defaults for all subscribers in the session
<OTSession
subscriberProperties={{
subscribeToAudio: true,
subscribeToVideo: true,
}}
/>
// Per-stream override
<OTSubscriber
properties={{
subscribeToAudio: true,
subscribeToVideo: false,
}}
/>
Managing Subscriber Streams (iOS Swift)
Manage subscribers, handle events, and adjust preferences in iOS.
Detecting When a Subscriber's Video Is Disabled
func subscriberVideoDisabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
print("subscriber video disabled.")
}
Possible Reasons
OTSubscriberVideoEventPublisherPropertyChangedOTSubscriberVideoEventQualityChangedOTSubscriberVideoEventSubscriberPropertyChanged
When video resumes:
func subscriberVideoEnabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
print("subscriber video enabled.")
}
Getting Information About a Stream
The OTStream object includes:
connection— The publishing connectioncreationTime— TimestamphasAudio— BoolhasVideo— Boolname— Optional stream namesession— Associated sessionstreamId— Unique IDvideoDimensions— CGSizevideoType— Camera, screen, or custom
You can monitor stats using OTSubscriberKitNetworkStatsDelegate.
See the client observability guide for more details.
Setting the Preferred Frame Rate and Resolution
For scalable video streams, you can set:
SubscriberKit.preferredFrameRateSubscriberKit.preferredResolution
Managing Subscriber Streams (JavaScript)
Restricting the Frame Rate of a Subscribed Stream
You can also restrict the frame rate of a Subscriber's video stream.
To restrict the frame rate of a subscriber, call the restrictFrameRate() method of the Subscriber object, passing in true:
subscriber.restrictFrameRate(true);
Pass in false and the frame rate of the video stream is not restricted:
subscriber.restrictFrameRate(false);
When the frame rate is restricted, the Subscriber video frame will update once or less per second. This feature is only available in routed sessions. In relayed sessions, calling this method has no effect.
Restricting the subscriber frame rate has the following benefits:
- It reduces CPU usage.
- It reduces the network bandwidth consumed by the app.
- It lets you subscribe to more streams simultaneously.
Reducing a subscriber's frame rate has no effect on the frame rate of the video in other clients. For other techniques to reduce resource usage in large sessions, see the Single Peer Connection guide.
Detecting When a Subscriber's Audio Is Blocked or Unblocked
Some browsers automatically block audio playback until the user interacts with the page. For the full implementation of handling blocked audio, including how to disable the default playback button and display your own UI, see Displaying a custom UI element when Subscriber audio is blocked.
Also, the Subscriber includes an isAudioBlocked() method which returns true if the audio is blocked or false if it is not.
Detecting When a Subscriber's Video Is Disabled
When the subscriber's video is disabled, the Subscriber object dispatches a videoDisabled event. When the Media Router disables the video of a subscriber, you may want to adjust the user interface related to the subscriber.
The reason property of the videoDisabled event object defines the reason the video was disabled ('publishVideo', 'quality', or 'subscribeToVideo'). For the full description of each reason, see the Subscribe diagnostics guide. Before the video is disabled due to quality, the Subscriber dispatches a videoDisableWarning event. To prevent a stream from having its video disabled due to quality, see the Subscriber audio fallback guide.
subscriber.on('videoDisableWarning', () => {
showConnectionWarning(subscriber.id);
});
subscriber.on('videoDisableWarningLifted', () => {
hideConnectionWarning(subscriber.id);
});
subscriber.on('videoDisabled', (event) => {
if (event.reason === 'quality') {
showVideoDisabledOverlay(subscriber.id);
}
});
subscriber.on('videoEnabled', () => {
hideVideoDisabledOverlay(subscriber.id);
});
By default, the Subscriber displays its own video-disabled indicator when quality is the reason. To replace it with your own UI, set style.videoDisabledDisplayMode to 'off' in the subscribe options. For codec-specific behaviour (e.g. why H.264 streams are not affected by quality-based fallback), see the Video codecs guide.
Getting Subscriber Stats (Web)
The getStats() method of a Subscriber object provides you with information about the subscriber's stream. For the full list of available fields, see the Subscribe diagnostics guide.
The following code logs loss ratios and bit rates every second:
window.setInterval(() => {
subscriber.getStats((error, stats) => {
if (error) {
console.error('Error getting subscriber stats:', error.message);
return;
}
if (stats.video) {
console.log('video bitrate:', stats.video.bitrate, 'bps');
const total = stats.video.packetsLost + stats.video.packetsReceived;
console.log('video packet loss ratio:', total > 0 ? stats.video.packetsLost / total : 0);
}
if (stats.audio) {
console.log('audio bitrate:', stats.audio.bitrate, 'bps');
}
});
}, 1000);
To get statistics for a stream published by the local client, you must use a routed session and set the testNetwork option to true when subscribing:
const subscriber = session.subscribe(stream, 'container', {
testNetwork: true,
});
To get more detailed stream statistics, use subscriber.getRtcStatsReport(). For a full description of all available fields, see the Client Observability guide.
Setting the Preferred Frame Rate and Resolution (Web)
When subscribing to a stream that uses the scalable video feature, you can set preferredResolution to 'auto' to automatically manage Subscriber video resolution and optimize CPU/network usage. For a full explanation of how these hints work, supported values, and limitations, see the Scalable video guide.
Set preferredResolution and preferredFrameRate in the options you pass to Session.subscribe() (or use Subscriber.setPreferredResolution() and Subscriber.setPreferredFrameRate() after subscribing):
// Set at subscribe time using 'auto' (recommended)
const subscriber = session.subscribe(stream, 'container', {
preferredResolution: 'auto',
});
// Or set explicitly after subscribing
subscriber.setPreferredResolution({ width: 1280, height: 720 });
subscriber.setPreferredFrameRate(30);
// Downgrade for a thumbnail tile
subscriber.setPreferredResolution({ width: 320, height: 240 });
subscriber.setPreferredFrameRate(7);
Managing Subscriber Streams (Android)
Manage subscribers, handle events, and adjust preferences in Android.
Detecting When a Subscriber's Video Is Disabled
When video is disabled:
override fun onVideoDisabled(subscriber: SubscriberKit, reason: String) {
// Video disabled
}
When video resumes:
override fun onVideoEnabled(subscriber: SubscriberKit, reason: String) {
// Video resumed
}
The reason parameter explains why the change occurred.
Getting Information About a Stream
The Stream object provides:
getConnection()— Connection objectgetCreationTime()— Creation timestamphasAudio()— BooleanhasVideo()— BooleangetName()— Stream namegetStreamId()— Unique IDgetVideoHeight()— Height in pixelsgetVideoWidth()— Width in pixelsgetVideoType()— Camera, screen share, or custom
You can also monitor stats:
setAudioStatsListener()setVideoStatsListener()setMediaLinkStatsListener()getRtcStatsReport()
Setting the Preferred Frame Rate and Resolution
For scalable video streams, you can set preferences:
SubscriberKit.setPreferredFrameRate()SubscriberKit.setPreferredResolution()
Managing Subscriber Streams (Windows)
Manage subscribers, handle events, and adjust preferences in Windows.
Detecting When a Subscriber's Video Is Disabled
The OpenTok Media Router may stop sending video if network conditions degrade.
The subscriber continues receiving audio if available.
When video is disabled, the Subscriber object sends a VideoDisabled event:
subscriber.VideoDisabled += Subscriber_VideoDisabled;
public void Subscriber_VideoDisabled(object sender)
{
// Display a user interface notification.
}
When video resumes:
subscriber.VideoEnabled += Subscriber_VideoEnabled;
public void Subscriber_VideoEnabled(object sender)
{
// Video resumes for the subscriber.
}
You may want to adjust the UI in response to these events.
Getting Information About a Stream
The Stream object exposes the following properties:
Connection— The publishing connectionCreationTime— Stream creation timestampHasAudio— Whether the stream has audioHasVideo— Whether the stream has videoName— Stream nameId— Unique stream IDHeight— Video height in pixelsWidth— Video width in pixelsVideoSourceType— Camera, screen-sharing, or custom source type
Possible VideoSourceType values:
VideoSourceType.StreamVideoTypeCameraVideoSourceType.StreamVideoTypeScreenVideoSourceType.StreamVideoTypeCustom
Monitoring Statistics
Use these events to monitor stream statistics:
Subscriber.AudioStatsUpdatedSubscriber.VideoStatsUpdatedSubscriber.MediaLinkStatsUpdated
To retrieve low-level RTC statistics:
subscriber.GetRtcStatsReport();
Setting the Preferred Frame Rate and Resolution
For streams using the scalable video feature, configure:
Subscriber.PreferredFramerateSubscriber.PreferredResolution
Managing Subscriber Streams (Linux)
Manage subscribers, handle events, and adjust preferences in Linux.
Detecting When a Stream's Video Is Disabled
The on_stream_has_video_changed callback function of the otc_session_callbacks struct is called when a stream’s video availability changes.
The stream parameter is a pointer to an otc_stream struct.
Use:
otc_stream_get_id(stream)
to retrieve the stream ID.
Getting Information About a Stream
Use the following functions to retrieve stream information:
otc_stream_get_connection()— Returns the publishing connectionotc_stream_get_creation_time()— Returns the stream creation timestampotc_stream_has_audio()— Whether the stream is publishing audiootc_stream_has_video()— Whether the stream is publishing videootc_stream_has_audio_track()— Whether the stream has an audio trackotc_stream_has_video_track()— Whether the stream has a video trackotc_stream_get_name()— Returns the stream nameotc_stream_get_id()— Returns the unique stream IDotc_stream_get_video_height()— Returns the video height in pixelsotc_stream_get_video_width()— Returns the video width in pixelsotc_stream_get_video_type()— Returns the stream video type
Possible video types:
OTC_STREAM_VIDEO_TYPE_CAMERAOTC_STREAM_VIDEO_TYPE_SCREEN
Monitoring Statistics
Use these subscriber callback functions:
on_audio_stats()on_video_stats()on_media_link_stats()
To retrieve low-level RTC statistics, use:
otc_subscriber_get_rtc_stats_report()
Setting the Preferred Frame Rate and Resolution
For streams using the scalable video feature, you can set preferred frame rate and resolution using:
otc_subscriber_set_preferred_framerate()otc_subscriber_set_preferred_resolution()