Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

6.0 Changelog: Twilio Video Android


(warning)

Warning

This documentation is for reference only. We are no longer onboarding new customers to Programmable Video. Existing customers can continue to use the product until December 5, 2026(link takes you to an external page).

We recommend migrating your application to the API provided by our preferred video partner, Zoom. We've prepared this migration guide(link takes you to an external page) to assist you in minimizing any service disruption.

(warning)

Warning

The Twilio Programmable Video SDKs use Semantic Versioning(link takes you to an external page). Twilio supports version N-1 for 12 months after the first GA release of version N. We recommend you upgrade to the latest version as soon as possible to avoid any breaking changes.

Support for 5.x will cease on December 4th, 2021. This branch will only receive fixes for critical issues until that date. Check this guide when planning your migration to 6.x.

Versions 4.x and below reached End of Life on September 8th, 2021. See the changelog here(link takes you to an external page).

Support for Android SDK 4.x ended on October 23nd, 2020.

Support for Android SDK 3.x ended on February 22nd, 2020.


6.4.1 (September 13th, 2021)

641-september-13th-2021 page anchor

Bug Fixes

bug-fixes page anchor
  • Fixed a crash when maxTracks or renderDimensions is set and a sink is added for a RemoteVideoTrack .
  • As of 6.0.0 of the SDK, hardware video encoding doesn't publish all of the three simulcast layers when VP8 simulcast is enabled on Android. This affects Video Content Preferences from working properly for subscribing video participants since the feature requires all three simulcast layers to switch between. Our team is working on a fix for this, but the feature does work when VP8 simulcast is used to publish video from participants using the Javascript or iOS SDKs.
  • Video Content Preferences might prefer larger video than needed when device orientations are mismatched. For example, if a participant in landscape mode publishes video, then the subscribing participant must also be in landscape mode in order for the correctly sized simulcast layers to be selected. The same is true for the portrait orientation.
  • When the publisher is publishing video at 720p with VP8 simulcast enabled and the subscriber varies their hints between 180p, 360p, and 720p, sometimes the subscriber receives larger video than expected.

Size Report

ABIAPK Size Impact
x865.6MB
x86_645.5MB
armeabi-v7a4.2MB
arm64-v8a5.2MB
universal19.9MB

6.4.0 (August 3rd, 2021)

640-august-3rd-2021 page anchor

This release contains a significant update to the Bandwidth Profile API. It allows for more efficient use of bandwidth and CPU in multi-party applications. In addition, it provides developers with more dynamic control over which video tracks are delivered to the client and the preferred video resolution of the tracks. These capabilities are provided via the Client Track Switch Off Control and Video Content Preferences settings.

Existing Bandwidth Profile settings will continue to function as before, however, we recommend developers update their Bandwidth Profile settings to make use of these new capabilities at their earliest convenience.

Client Track Switch Off Control

client-track-switch-off-control page anchor
  • This feature allows subscribers to control whether the media for a RemoteVideoTrack is received or not. Client Track Switch off Control has two modes of operation:
    • auto (default): The SDK determines whether tracks should be switched off based on renderer attachment, view visibility, and application lifecycle.
    • manual : The application requests that individual tracks be switched off or on using the RemoteVideoTrack.switchOff() and RemoteVideoTrack.switchOn() methods.

Note If your application previously set the maxTracks property to limit the number of tracks visible, you should instead use clientTrackSwitchOffControl to take advantage of this feature.

Video Content Preferences

video-content-preferences page anchor
  • This feature allows subscribers to specify preferences about the media that they receive on a RemoteVideoTrack. Video content preferences has two modes of operation:
    • auto (default): The SDK specifies content preferences based on video view size. A RemoteVideoTrack rendered by a VideoView or VideoTextureView with larger dimensions will get a higher quality video compared to a RemoteVideoTrack rendered by a VideoView or VideoTextureView with smaller dimensions.
    • manual : The application specifies the content preferences for individual tracks using RemoteVideoTrack.setContentPreferences() .

Note If your application previously set the renderDimensions property, you should instead use contentPreferencesMode to take advantage of this feature.

Both of these features are available in Group Rooms and are enabled by default if your application specifies BandwidthProfileOptions during connect. The auto mode will be enabled if your application passes either a VideoTextureView or a VideoView to RemoteVideoTrack.addSink(VideoSink). However, if your application implements a custom VideoSink and it is passed to RemoteVideoTrack.addSink(VideoSink), then the track will remain switched on and video preferences are ignored as long as there is a custom VideoSink remaining in the track.


_10
BandwidthProfileOptions bandwidthProfileOptions = new BandwidthProfileOptions(
_10
new VideoBandwidthProfileOptions.
_10
Builder()
_10
// Use "auto" default. Be sure to remove "maxTracks" and "renderDimensions".
_10
.build());
_10
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
_10
.bandwidthProfile(bandwidthProfileOptions)
_10
.build();
_10
_10
Video.connect(context, connectOptions, roomListener);

If you don't want the SDK to automatically switch on/off RemoteVideoTracks then specify ClientTrackSwitchOffControl.manual and VideoContentPreferencesMode.manual instead:


_11
BandwidthProfileOptions bandwidthProfileOptions = new BandwidthProfileOptions(
_11
new VideoBandwidthProfileOptions.
_11
Builder()
_11
.clientTrackSwitchOffControl(ClientTrackSwitchOffControl.MANUAL)
_11
.videoContentPreferencesMode(VideoContentPreferencesMode.MANUAL)
_11
.build());
_11
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
_11
.bandwidthProfile(bandwidthProfileOptions)
_11
.build();
_11
_11
Video.connect(context, connectOptions, roomListener);

Subscribers that connect with ClientTrackSwitchOffControl.MANUAL can request which RemoteVideoTracks are switched on or off:


_10
@Override
_10
public void onVideoTrackSubscribed(
_10
RemoteParticipant remoteParticipant,
_10
RemoteVideoTrackPublication remoteVideoTrackPublication,
_10
RemoteVideoTrack remoteVideoTrack) {
_10
if (remoteParticipant.getIdentity() != "Bob") {
_10
remoteVideoTrack.switchOff();
_10
}
_10
}

Subscribers that connect with VideoContentPreferencesMode.MANUAL can request which resolution they prefer to receive RemoteVideoTracks in:


_10
@Override
_10
public void onVideoTrackSubscribed(
_10
RemoteParticipant remoteParticipant,
_10
RemoteVideoTrackPublication remoteVideoTrackPublication,
_10
RemoteVideoTrack remoteVideoTrack) {
_10
remoteVideoTrack.setContentPreferences(new VideoContentPreferences(new VideoDimensions(320, 240)));
_10
}

  • The VideoBandwidthProfileOptions.maxTracks property is now deprecated and will raise a warning when set. Calling RemoteVideoTrack.switchOn() or RemoteVideoTrack.switchOff() after setting maxTracks is not allowed and will raise an exception.
  • The VideoBandwidthProfileOptions.renderDimensions property is now deprecated and will raise a warning when set. Calling RemoteVideoTrack.setContentPreferences() after setting renderDimensions is not allowed and will raise an exception.
  • As of 6.0.0 of the SDK, hardware video encoding doesn't publish all of the three simulcast layers when VP8 simulcast is enabled on Android. This affects Video Content Preferences from working properly for subscribing video participants since the feature requires all three simulcast layers to switch between. Our team is working on a fix for this, but the feature does work when VP8 simulcast is used to publish video from participants using the JavaScript or iOS SDKs.
  • Video Content Preferences might prefer larger video than needed when device orientations are mismatched. For example, if a participant in landscape mode publishes video, then the subscribing participant must also be in landscape mode in order for the correctly sized simulcast layers to be selected. The same is true for the portrait orientation.
  • When the publisher is publishing video at 720p with VP8 simulcast enabled and the subscriber varies their hints between 180p, 360p, and 720p, sometimes the subscriber receives larger video than expected.

Size Report

ABIAPK Size Impact
x865.6MB
x86_645.5MB
armeabi-v7a4.2MB
arm64-v8a5.2MB
universal19.8MB


6.3.1 (June 24th, 2021)

631-june-24th-2021 page anchor
  • Fixed a crash (see stack trace below) that sometimes occurs on Pixel devices when decoding VP8 video streams.


    _10
    java.lang.IllegalArgumentException: Texture width must be positive, but was 0
    _10
    FATAL EXCEPTION: AndroidVideoDecoder.outputThread
    _10
    Process: com.twilio.video.test, PID: 13001
    _10
    java.lang.IllegalArgumentException: Texture width must be positive, but was 0
    _10
    at tvi.webrtc.SurfaceTextureHelper.setTextureSize(SurfaceTextureHelper.java:256)
    _10
    at tvi.webrtc.AndroidVideoDecoder.deliverTextureFrame(AndroidVideoDecoder.java:432)
    _10
    at tvi.webrtc.AndroidVideoDecoder.deliverDecodedFrame(AndroidVideoDecoder.java:407)
    _10
    at tvi.webrtc.AndroidVideoDecoder$1.run(AndroidVideoDecoder.java:369)

  • Fixed a bug that could cause a crash when changing log level to Trace at runtime.

Size report

ABIAPK Size Impact
x865.5MB
x86_645.5MB
armeabi-v7a4.1MB
arm64-v8a5.2MB
universal19.7MB


6.3.0 (April 7th, 2021)

630-april-7th-2021 page anchor
  • 100 Participant Group Rooms Pilot Program: A Group Room created with max participants greater than 50 is structured to support a small number of presenters and a large number of viewers. It has the following behavioral differences compared to regular Group Rooms:
    • The RoomListener.onParticipantConnected() callback method is invoked when a RemoteParticipant connects to the Room and publishes at least one Track.
    • The RoomListener.onParticipantDisconnected() callback method is invoked when a RemoteParticipant disconnects from the Room or unpublishes all of its Tracks.
    • If a RemoteParticipant unpublishes all of its tracks (resulting in the RoomListener.onParticipantDisconnected() callback method being invoked) and later republishes a track, a new RemoteParticipant object will be provided in the subsequent RoomListener.onParticipantConnected() callback method invocation with the same Participant Sid as before.
    • The maximum number of published Tracks in a Room at the same time cannot exceed 16. Attempts to publish more Tracks will result in a publication failure with TwilioException.PARTICIPANT_MAX_TRACKS_EXCEEDED_EXCEPTION unless one or more published Tracks is unpublished.
    • Contact your Twilio Account Executive to enroll in this pilot program.
  • Updated ReLinker to 1.4.3 to consume from Maven Central.
  • Now published to MavenCentral along with the Kotlin Extensions Library.
    • Ensure that you have mavenCentral listed in your project's buildscript repositories section:


      _10
      buildscript {
      _10
      repositories {
      _10
      mavenCentral()
      _10
      ...
      _10
      }
      _10
      }

Size report

ABIAPK Size Impact
x865.5MB
x86_645.5MB
armeabi-v7a4.1MB
arm64-v8a5.2MB
universal19.8MB


6.2.1 (January 25th, 2021)

621-january-25th-2021 page anchor
  • Fixed a crash that occurred while using either the CameraCapturer or Camera2Capturer , switching from the front camera to the back camera, and toggling the camera flash.
  • Publishing multiple tracks with the same name results in a crash if network quality is enabled. To avoid this, use unique names for each track in the Room .

Size Report

ABIAPK Size Impact
x865.5MB
x86_645.5MB
armeabi-v7a4.1MB
arm64-v8a5.2MB
universal19.6MB


6.2.0 (January 13th, 2021)

620-january-13th-2021 page anchor
  • Updated the SDK to Android Gradle Plugin 4.1.1
  • Removed tvi.webrtc.NetworkMonitor and tvi.webrtc.NetworkMonitorAutoDetect from the libwebrtc.jar since they are unused by the SDK.

Size report

ABIAPK Size Impact
x865.5MB
x86_645.5MB
armeabi-v7a4.1MB
arm64-v8a5.2MB
universal19.6MB


6.1.0 (December 17th, 2020)

610-december-17th-2020 page anchor

New Kotlin Extensions Library

new-kotlin-extensions-library page anchor

As part of this release, we have created a new Kotlin Extensions Library. This library provides a set of convenience functions and extensions(link takes you to an external page) that provide Kotlin developers with a more idiomatic programming experience.

Below is a list of all of the extension APIs that are now available:

  • AudioOptions.kt
  • BandwidthProfileOptions.kt
  • ConnectOptions.kt
  • DataTrackOptions.kt
  • IceOptions.kt
  • LocalAudioTrack.kt
  • LocalDataTrack.kt
  • LocalVideoTrack.kt
  • Video.kt
  • VideoBandwidthProfileOptions.kt

To get started using the extensions, replace implementation com.twilio:video-android:6.1.0 with implementation com.twilio:video-android-ktx:6.1.0 in your application's build.gradle file. The extensions and functions are available under the com.twilio.video.ktx package. The extensions library also includes the SDK, so developers do not need to include the SDK and extensions library.


_10
implementation 'com.twilio:video-android-ktx:6.1.0'

The Video Android Kotlin extensions will follow the same semantic versioning policy of the Video Android SDK itself. Each Video Android release will now consist of the Java SDK and the Kotlin extensions library with the same version. Using the Kotlin extensions library is completely optional and developers can continue to use the Java based Video Android SDK as before.

All of the options extensions follow a similar pattern. For example, here's how to connect to a room with connect options using Java:


_10
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
_10
.roomName("my-room")
_10
.enableAutomaticSubscription(false)
_10
.build();
_10
room = Video.connect(context, connectOptions, roomListener);

The following Kotlin snippet shows how you can call connect with connect options all in one statement using the Video.kt connect extension function:


_10
val room = Video.connect(context, token, roomListener) {
_10
roomName("my-room")
_10
enableAutomaticSubscription(false)
_10
}

The library also introduces extension properties that make it easier to get and set specific Java fields. For example, here's how to check if a LocalVideoTrack track is enabled and how to disable it in Java:


_10
LocalVideoTrack localVideoTrack = LocalVideoTrack.create(context, enable, cameraCapturer);
_10
_10
// Check if the track is enabled
_10
localVideoTrack.isEnabled();
_10
_10
// Disable the track
_10
localVideoTrack.enabled(false);

The following Kotlin snippet show how to do the same with the enabled extension property that is part of LocalVideoTrack.kt:


_10
val localVideoTrack = LocalVideoTrack.create(context, enable, cameraCapturer)
_10
_10
// Check if the track is enabled
_10
localVideoTrack.enabled
_10
_10
// Disable the track
_10
localVideoTrack.enabled = false

  • The following classes now override the equals and hashCode object methods:
    • ConnectOptions.java
    • IceOptions.java
    • BandwidthProfileOptions.java
    • VideoBandwidthProfileOptions.java
    • AudioOptions.java
    • DataTrackOptions.java
  • Added a new Video.java static method named getModuleLogLevel(LogModule module) that retrieves the log level for the specified LogModule .
  • Fixed a bug where publishing multiple tracks with the same name may result in a crash if network quality is enabled.


6.0.0 (December 4th, 2020)

600-december-4th-2020 page anchor

SDK 6.0 is now generally available. 6.0 provides the following new features:

  • The SDK has been upgraded to use Chromium WebRTC 83.
  • The SDK now enables Discontinuous Transmission (DTX) by default when using the Opus codec. Enabling DTX results in a lower bitrate when silent audio is detected.
  • The capturing and rendering facilities have been updated to allow developers more control, flexibility, and capabilities. This update includes the adoption of WebRTC classes.
  • The SDK includes new callbacks onParticipantReconnecting and onParticipantReconnected to Room.Listener . These callbacks will be raised when a RemoteParticipant is attempting to reconnect to a room due to a signaling network interruption.

Please visit our migration guide for more details on how to update your application to 6.0.

  • Added API documentation to Rgba8888Buffer .
  • Publishing multiple tracks with the same name results in a crash if network quality is enabled. To avoid this, use unique names for each track in the Room .


6.0.0-beta2 (December 2nd, 2020)

600-beta2-december-2nd-2020 page anchor
  • The SDK API docs now include documentation for classes defined in tvi.webrtc(link takes you to an external page) . For example, the VideoCapturer API docs will now provide a link to the base interface tvi.webrtc.VideoCapturer .
  • isRecording() API now accurately reflects the current recording state of the Room . In the previous versions of the SDK, isRecording() could return false positives. The onRecordingStarted(...) and onRecordingStopped(...) callbacks will now be invoked when recording for at least a single track in the Room has started and stopped respectively.

Size Report

ABIAPK Size Impact
x865.5MB
x86_645.5MB
armeabi-v7a4.1MB
arm64-v8a5.2MB
universal19.6MB


6.0.0-beta1 (November 23rd, 2020)

600-beta1-november-23rd-2020 page anchor
  • Added the ParticipantState enumeration.
  • Added the getState() method to Participant .
  • Added new callbacks onParticipantReconnecting and onParticipantReconnected to Room.Listener. These callbacks will be raised when a RemoteParticipant is attempting to reconnect to a room due to a signaling network interruption

    Note It can take up to 15 seconds for our signaling backend to detect that a RemoteParticipant's connection has been disrupted due to a network degradation or handoff.

  • Removed the RemoteParticipant.isConnected() method in favor of Participant.getState() .

Size Report

ABIAPK Size Impact
x865.5MB
x86_645.5MB
armeabi-v7a4.1MB
arm64-v8a5.2MB
universal19.6MB


6.0.0-preview3 (November 17th, 2020)

600-preview3-november-17th-2020 page anchor
  • Added useDtx parameter for constraining bitrate while using Opus codec. useDtx is enabled by default. Disabling useDtx will result in higher bitrate for silent audio while using Opus codec.
  • OpusCodec class has a new constructor that takes useDtx as an input OpusCodec(boolean useDtx) . Use this to explicitly enable or disable DTX.
  • Removed IceOptions.abortOnIceServersTimeout and IceOptions.iceServersTimeout .
  • Removed CameraCapturer.CameraSource . CameraCapturer instances are now created using a camera ID as a String . You can use tvi.webrtc.Camera1Enumerator#getDeviceNames() to query the list of supported camera IDs.
  • Updated CameraCapturer#switchCamera() signature to require a camera ID. Users now must specify which camera ID to switch to. This behavior is similar to the Camera2Capturer switch camera behavior.

    The snippet below demonstrates the updated use of CameraCapturer.


    _10
    // Determine the front and back camera
    _10
    val camera1Enumerator = Camera1Enumerator()
    _10
    val frontCameraId = camera1Enumerator.deviceNames.find { camera1Enumerator.isFrontFacing(it) }
    _10
    val backCameraId = camera1Enumerator.deviceNames.find { camera1Enumerator.isBackFacing(it) }
    _10
    _10
    // Create the instance
    _10
    val cameraCapturer = CameraCapturer(context, frontCameraId)
    _10
    _10
    // Switch camera Ids
    _10
    cameraCapturer.switchCamera(backCameraId)

  • Camera2Capturer.Listener implementations are now optional when creating a Camera2Capturer


6.0.0-preview2 (November 9th, 2020)

600-preview2-november-9th-2020 page anchor

Use the AudioDevice API to create innovative and advanced in-app audio capabilities. For example, enable pre-recorded messages to be played in-room, or, apply noise reduction algorithms before playing out the received audio.

An AudioDevice is a logical device that is used to capture and render (play out) audio. The captured audio is sent to the remote party, and the received audio is rendered locally. The current DefaultAudioDevice uses the mic for capturing and the local speaker/earpiece/headset for rendering. The AudioDevice API allows for the creation of custom audio capturers and renderers.

See this example(link takes you to an external page) and API docs(link takes you to an external page) to learn more about custom audio devices.

  • Introduced the Video.audioDevice class member. You can now set your own AudioDevice before connecting to a Room .
  • Added DefaultAudioDevice to render and capture audio. By default, the Video SDK uses DefaultAudioDevice to capture and render audio.
  • Added the ability to provide custom audio capturing and rendering via the AudioDevice interface. AudioFormat describes the audio that is being captured and rendered.


6.0.0-preview1 (October 27th, 2020)

600-preview1-october-27th-2020 page anchor
  • The Video Android SDK uses Chromium WebRTC 83.
  • The Video Android SDK is built with NDK r20b.

The update to video capturing and rendering includes an adoption of WebRTC classes defined in libwebrtc.jar included with the Video Android SDK. In previous major releases, the SDK would define public APIs with classes defined exclusively in the com.twilio.video package. The SDK will now include public APIs with classes defined in libwebrtc.jar.

Any public APIs that reference a WebRTC class are only compatible with the libwebrtc.jar provided from the Video Android SDK. The classes provided in this artifact are defined under the tvi.webrtc package to ensure side-by-side compatibility with other WebRTC based libraries.

Adopting WebRTC classes in public APIs provides developers already familiar with WebRTC more flexibility when capturing media and rendering media.

This release includes an overhaul to the video capturer facilities. LocalVideoTracks are now created with implementations of tvi.webrtc.VideoCapturer and VideoFormats. VideoCapturer remains a part of the SDK as an extension of tvi.webrtc.VideoCapturer, but VideoConstraints have been completely removed in favor of VideoFormats.

  • Leverage capturers provided by libwebrtc.jar .
  • Implement custom capturers that capture to textures.
  • Added support for NV12 format.
  • The video capturer API now enables cropping and scaling in response to network conditions.

Updated Programming Model

updated-programming-model page anchor

When a caller create a LocalVideoTrack, the following methods of a tvi.webrtc.VideoCapturer are called in the order listed.

  1. isScreencast() — The return value is used to create a tvi.webrtc.VideoSource
  2. initialize(surfaceTextureHelper, context, capturerObserver) - This method is called so the capturer can setup to capture frames. The capturer should retain a reference to the capturer observer.
  3. startCapture(width, height, framerate) — The capturer should start capturing in a format as close as possible to width x height at framerate .

When a caller releases a local video track, the following methods are then called:

  1. stopCapture() — The capturer should stop capturing frames. The SDK expects this method to block until frames have stopped being captured.
  2. dispose() — The capturer should perform any final clean up.
  • VideoPixelFormat has been removed in favor of implementing tvi.webrtc.VideoFrame.Buffer . The SDK includes support for the following buffer types: tvi.webrtc.VideoFrame.TextureBuffer , tvi.webrtc.NV21Buffer , tvi.webrtc.NV12Buffer , and Rgba8888Buffer .
  • VideoCapturer now extends tvi.webrtc.VideoCapturer.
    • getSupportedFormats() has been removed in favor of getCaptureFormat() . This update allows a VideoCapturer to provide a default capture format. For example, the ScreenCapturer returns a capture format based on the device screen dimensions.
  • VideoConstraints has been removed. Developers can now specify a capture format when creating a local video track and the tvi.webrtc.VideoCapturer is responsible for capturing at a format as close as possible to the specified format. The VideoFormat provided to LocalVideoTrack.create(...) takes highest priority over the format returned by VideoCapturer#getCaptureFormat() . The default format for video tracks remains 640x480 at 30 FPS.
  • Removed VideoFrame in favor of tvi.webrtc.VideoFrame .
  • Removed AspectRatio .

This release includes updated video rendering facilities. RemoteVideoTracks and LocalVideoTracks are now rendered with a tvi.webrtc.VideoSink instead of a VideoRenderer. VideoRenderer and VideoRenderer.Listener have been removed in favor of tvi.webrtc.VideoSink and tvi.webrtc.RendererCommon.RendererEvents respectively.

  • Removed VideoRenderer in favor of tvi.webrtc.VideoSink .
  • Removed VideoRenderer.Listener in favor of tvi.webrtc.RendererCommon.RendererEvents .
  • Removed VideoTrack#addRenderer in favor of VideoTrack#addSink .
  • Removed VideoTrack#removeRenderer in favor of VideoTrack#removeSink .
  • Updated VideoView#setListener to take a tvi.webrtc.RendererCommon.RendererEvents instead of a VideoRenderer.Listener .
  • Updated VideoTextureView#setListener to take a tvi.webrtc.RendererCommon.RendererEvents instead of a VideoRenderer.Listener .
  • Removed CameraCapturer#takePicture . The functionality this API provides can be recreated using a custom VideoSink . Reference the Custom Video Sink quickstart(link takes you to an external page) for more details.

The table below highlights the updated app size impact.

ABIApp Size Impact 5.xApp Size Impact 6.0.0-preview1
universal21.9MB19.5MB
armeabi-v7a4.8MB4.1MB
arm64-v8a5.7MB5.1MB
x866MB5.5MB
x86_646.1MB5.4MB
  • AudioDevice API is not available in this release.

Rate this page: