Real-Time Streaming Optimizations - Amazon IVS

Real-Time Streaming Optimizations

To ensure that your users have the best experience when streaming and viewing video using IVS real-time streaming, there are several ways you can improve or optimize for parts of the experience, using features that we offer today.

Introduction

When optimizing for a user's quality of experience, it’s important to consider their desired experience, which can change depending on the content they are watching and network conditions.

Throughout this guide we focus on users who are either publishers of streams or subscribers of streams, and we consider the desired actions and experiences of those users.

Adaptive Streaming: Layered Encoding with Simulcast

This feature is supported only in the following client versions:

You must email amazon-ivs-simulcast@amazon.com to opt-in to this feature for your account. Enabling simulcast via the SDK configuration will have no effect unless you are opted in.

Once you have opted into the feature, when using IVS real-time broadcast SDKs, publishers encode multiple layers of video and subscribers automatically adapt or change to the quality best suited for their network. We call this layered encoding with simulcast.

Layered encoding with simulcast is supported on Android and iOS, and on Chrome desktop browsers (for Windows and macOS). We do not support layered encoding on other browsers.

In the diagram below, the host is sending three video qualities (high, medium, and low). IVS forwards the highest quality video to each viewer based on available bandwidth; this provides an optimal experience for each viewer. If Viewer's 1 network connection changes from good to bad, IVS automatically starts sending Viewer 1 lower quality video, so Viewer 1 can keep watching the stream uninterrupted (with the best quality possible).


                Use layered encoding with simulcast to adjust quality video based on the
                    quality of a viewer's network connection.

Default Layers, Qualities, and Framerates

The default qualities and layers provided for mobile and web users are as follows:

Mobile (Android, iOS) Web (Chrome)

High layer (or custom):

  • Max bitrate: 900,000 bps

  • Framerate: 15 fps

  • Resolution: 360x640

High layer (or custom):

  • Max bitrate: 1,700,000 bps

  • Framerate: 30 fps

  • Resolution: 1280x720

Mid layer: none (not needed, because the difference between the high- and low-layer bitrates on mobile is narrow)

Mid layer:

  • Max bitrate: 700,000 bps

  • Framerate: 20 fps

  • Resolution: 640x360

Low layer:

  • Max bitrate: 150,000 bps

  • Framerate: 15 fps

  • Resolution: 180x320

Low layer:

  • Max bitrate: 200,000 bps

  • Framerate: 15 fps

  • Resolution: 320x180

Configuring Layered Encoding with Simulcast

By default (once you have opted into the feature), layered encoding with simulcast is enabled. To disable it, use the following video configurations on a StageStream. If you disable it, you might see a degradation of the quality under poor network conditions.

Android

// Opt-out of Simulcast StageVideoConfiguration config = new StageVideoConfiguration(); config.simulcast.setEnabled(false); ImageLocalStageStream cameraStream = new ImageLocalStageStream(frontCamera, config); // Other Stage implementation code

iOS

// Opt-out of Simulcast let config = IVSLocalStageStreamVideoConfiguration() config.simulcast.enabled = false let cameraStream = IVSLocalStageStream(device: camera, configuration: config) // Other Stage implementation code

Web

// Opt-out of Simulcast let cameraStream = new LocalStageStream(cameraDevice, { simulcast: { enabled: false } }) // Other Stage implementation code

Streaming Configurations

This section explores other configurations you can make to your video and audio streams.

Changing Video Stream Bitrate

To change the bitrate of your video stream, use the following configuration samples.

Android

StageVideoConfiguration config = new StageVideoConfiguration(); // Update Max Bitrate to 1.5mbps config.setMaxBitrate(1500000); ImageLocalStageStream cameraStream = new ImageLocalStageStream(frontCamera, config); // Other Stage implementation code

iOS

let config = IVSLocalStageStreamVideoConfiguration(); // Update Max Bitrate to 1.5mbps try! config.setMaxBitrate(1500000); let cameraStream = IVSLocalStageStream(device: camera, configuration: config); // Other Stage implementation code

Web

// Note: On web it is also recommended to configure the framerate of your device from userMedia const camera = await navigator.mediaDevices.getUserMedia({ video: { bitrate: { ideal: 1500, max: 1500, }, }, }); let cameraStream = new LocalStageStream(camera.getVideoTracks()[0], { // Update Max Bitrate to 1.5mbps or 1500kbps maxBitrate: 1500 }) // Other Stage implementation code

Changing Video Stream Framerate

To change the framerate of your video stream, use the following configuration samples.

Android

StageVideoConfiguration config = new StageVideoConfiguration(); // Update target framerate to 10fps config.targetFramerate(10); ImageLocalStageStream cameraStream = new ImageLocalStageStream(frontCamera, config); // Other Stage implementation code

iOS

let config = IVSLocalStageStreamVideoConfiguration(); // Update target framerate to 10fps try! config.targetFramerate(10); let cameraStream = IVSLocalStageStream(device: camera, configuration: config); // Other Stage implementation code

Web

// Note: On web it is also recommended to configure the framerate of your device from userMedia const camera = await navigator.mediaDevices.getUserMedia({ video: { frameRate: { ideal: 10, max: 10, }, }, }); let cameraStream = new LocalStageStream(camera.getVideoTracks()[0], { // Update Max Framerate to 10fps maxFramerate: 10 }) // Other Stage implementation code

Optimizing Audio Bitrate and Stereo Support

To change the bitrate and stereo settings of your audio stream, use the following configuration samples.

Web

// Note: Disable autoGainControl, echoCancellation, and noiseSuppression when enabling stereo. const camera = await navigator.mediaDevices.getUserMedia({ audio: { autoGainControl: false, echoCancellation: false, noiseSuppression: false }, }); let audioStream = new LocalStageStream(camera.getAudioTracks()[0], { // Optional: Update Max Audio Bitrate to 96Kbps. Default is 64Kbps maxAudioBitrateKbps: 96, // Signal stereo support. Note requires dual channel input source. stereo: true }) // Other Stage implementation code

Android

StageAudioConfiguration config = new StageAudioConfiguration(); // Update Max Bitrate to 96Kbps. Default is 64Kbps. config.setMaxBitrate(96000); AudioLocalStageStream microphoneStream = new AudioLocalStageStream(microphone, config); // Other Stage implementation code

iOS

let config = IVSLocalStageStreamConfiguration(); // Update Max Bitrate to 96Kbps. Default is 64Kbps. try! config.audio.setMaxBitrate(96000); let microphoneStream = IVSLocalStageStream(device: microphone, config: config); // Other Stage implementation code

Suggested Optimizations

Scenario Recommendations
Streams with text, or slow moving content, like presentations or slides Use layered encoding with simulcast or configure streams with lower framerate.
Streams with action or a lot of movement Use layered encoding with simulcast.
Streams with conversation or little movement Use layered encoding with simulcast or choose audio-only (see "Subscribing to Participants" in the Real-Time Streaming Broadcast SDK Guides: Web, Android, and iOS).
Users streaming with limited data Use layered encoding with simulcast or, if you want lower data usage for everyone, configure a lower framerate and lower the bitrate manually.