-
Removed
tvi.webrtc.NetworkMonitor
andtvi.webrtc.NetworkMonitorAutoDetect
from thelibwebrtc.jar
since they are unused by the SDK.
Size report
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.6MB |
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.
We recommend migrating your application to the API provided by our preferred video partner, Zoom. We've prepared this migration guide to assist you in minimizing any service disruption.
The Twilio Programmable Video SDKs use Semantic Versioning. 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.
Support for Android SDK 4.x ended on October 23nd, 2020.
Support for Android SDK 3.x ended on February 22nd, 2020.
maxTracks
or
renderDimensions
is set and a sink is added for a
RemoteVideoTrack
.
Size Report
ABI | APK Size Impact |
---|---|
x86 | 5.6MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.2MB |
arm64-v8a | 5.2MB |
universal | 19.9MB |
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.
RemoteVideoTrack
is received or not. Client Track Switch off Control has two modes of operation:
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.
RemoteVideoTrack
. Video content preferences has two modes of operation:
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.
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.
_10BandwidthProfileOptions bandwidthProfileOptions = new BandwidthProfileOptions(_10 new VideoBandwidthProfileOptions._10 Builder()_10 // Use "auto" default. Be sure to remove "maxTracks" and "renderDimensions"._10 .build());_10ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)_10 .bandwidthProfile(bandwidthProfileOptions)_10 .build();_10_10Video.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:
_11BandwidthProfileOptions bandwidthProfileOptions = new BandwidthProfileOptions(_11 new VideoBandwidthProfileOptions._11 Builder()_11 .clientTrackSwitchOffControl(ClientTrackSwitchOffControl.MANUAL)_11 .videoContentPreferencesMode(VideoContentPreferencesMode.MANUAL)_11 .build());_11ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)_11 .bandwidthProfile(bandwidthProfileOptions)_11 .build();_11_11Video.connect(context, connectOptions, roomListener);
Subscribers that connect with ClientTrackSwitchOffControl.MANUAL
can request which RemoteVideoTracks
are switched on or off:
_10@Override_10public 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_10public void onVideoTrackSubscribed(_10 RemoteParticipant remoteParticipant,_10 RemoteVideoTrackPublication remoteVideoTrackPublication,_10 RemoteVideoTrack remoteVideoTrack) {_10 remoteVideoTrack.setContentPreferences(new VideoContentPreferences(new VideoDimensions(320, 240)));_10}
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.
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.
Size Report
ABI | APK Size Impact |
---|---|
x86 | 5.6MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.2MB |
arm64-v8a | 5.2MB |
universal | 19.8MB |
Fixed a crash (see stack trace below) that sometimes occurs on Pixel devices when decoding VP8 video streams.
_10java.lang.IllegalArgumentException: Texture width must be positive, but was 0_10 FATAL EXCEPTION: AndroidVideoDecoder.outputThread_10Process: com.twilio.video.test, PID: 13001_10java.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)
Size report
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.7MB |
RoomListener.onParticipantConnected()
callback method is invoked when a
RemoteParticipant
connects to the Room and publishes at least one Track.
RoomListener.onParticipantDisconnected()
callback method is invoked when a
RemoteParticipant
disconnects from the Room or unpublishes all of its Tracks.
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.
TwilioException.PARTICIPANT_MAX_TRACKS_EXCEEDED_EXCEPTION
unless one or more published Tracks is unpublished.
Ensure that you have mavenCentral
listed in your project's buildscript repositories section:
_10buildscript {_10 repositories {_10 mavenCentral()_10 ..._10 }_10}
Size report
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.8MB |
CameraCapturer
or
Camera2Capturer
, switching from the front camera to the back camera, and toggling the camera flash.
Room
.
Size Report
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.6MB |
tvi.webrtc.NetworkMonitor
and
tvi.webrtc.NetworkMonitorAutoDetect
from the
libwebrtc.jar
since they are unused by the SDK.
Size report
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.6MB |
As part of this release, we have created a new Kotlin Extensions Library. This library provides a set of convenience functions and extensions 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.
_10implementation '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:
_10ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)_10 .roomName("my-room")_10 .enableAutomaticSubscription(false)_10 .build();_10room = 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:
_10val 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:
_10LocalVideoTrack localVideoTrack = LocalVideoTrack.create(context, enable, cameraCapturer);_10_10// Check if the track is enabled_10localVideoTrack.isEnabled();_10_10// Disable the track_10localVideoTrack.enabled(false);
The following Kotlin snippet show how to do the same with the enabled extension property that is part of LocalVideoTrack.kt
:
_10val localVideoTrack = LocalVideoTrack.create(context, enable, cameraCapturer)_10_10// Check if the track is enabled_10localVideoTrack.enabled_10_10// Disable the track_10localVideoTrack.enabled = false
equals
and hashCode
object methods:
ConnectOptions.java
IceOptions.java
BandwidthProfileOptions.java
VideoBandwidthProfileOptions.java
AudioOptions.java
DataTrackOptions.java
Video.java
static method named
getModuleLogLevel(LogModule module)
that retrieves the log level for the specified
LogModule
.
SDK 6.0 is now generally available. 6.0 provides the following new features:
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.
Rgba8888Buffer
.
Room
.
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
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.6MB |
ParticipantState
enumeration.
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.
RemoteParticipant.isConnected()
method in favor of
Participant.getState()
.
Size Report
ABI | APK Size Impact |
---|---|
x86 | 5.5MB |
x86_64 | 5.5MB |
armeabi-v7a | 4.1MB |
arm64-v8a | 5.2MB |
universal | 19.6MB |
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.
IceOptions.abortOnIceServersTimeout
and
IceOptions.iceServersTimeout
.
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_10val camera1Enumerator = Camera1Enumerator()_10val frontCameraId = camera1Enumerator.deviceNames.find { camera1Enumerator.isFrontFacing(it) }_10val backCameraId = camera1Enumerator.deviceNames.find { camera1Enumerator.isBackFacing(it) }_10_10// Create the instance_10val cameraCapturer = CameraCapturer(context, frontCameraId)_10_10// Switch camera Ids_10cameraCapturer.switchCamera(backCameraId)
Camera2Capturer.Listener
implementations are now optional when creating a
Camera2Capturer
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 and API docs to learn more about custom audio devices.
Video.audioDevice
class member. You can now set your own
AudioDevice
before connecting to a
Room
.
DefaultAudioDevice
to render and capture audio. By default, the Video SDK uses
DefaultAudioDevice
to capture and render audio.
AudioDevice
interface.
AudioFormat
describes the audio that is being captured and rendered.
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. LocalVideoTrack
s are now created with implementations of tvi.webrtc.VideoCapturer
and VideoFormat
s. VideoCapturer
remains a part of the SDK as an extension of tvi.webrtc.VideoCapturer
, but VideoConstraints
have been completely removed in favor of VideoFormat
s.
libwebrtc.jar
.
When a caller create a LocalVideoTrack
, the following methods of a tvi.webrtc.VideoCapturer
are called in the order listed.
isScreencast()
— The return value is used to create a
tvi.webrtc.VideoSource
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.
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:
stopCapture()
— The capturer should stop capturing frames. The SDK expects this method to block until frames have stopped being captured.
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.
VideoFrame
in favor of
tvi.webrtc.VideoFrame
.
AspectRatio
.
This release includes updated video rendering facilities. RemoteVideoTrack
s and LocalVideoTrack
s 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.
VideoRenderer
in favor of
tvi.webrtc.VideoSink
.
VideoRenderer.Listener
in favor of
tvi.webrtc.RendererCommon.RendererEvents
.
VideoTrack#addRenderer
in favor of
VideoTrack#addSink
.
VideoTrack#removeRenderer
in favor of
VideoTrack#removeSink
.
VideoView#setListener
to take a
tvi.webrtc.RendererCommon.RendererEvents
instead of a
VideoRenderer.Listener
.
VideoTextureView#setListener
to take a
tvi.webrtc.RendererCommon.RendererEvents
instead of a
VideoRenderer.Listener
.
CameraCapturer#takePicture
. The functionality this API provides can be recreated using a custom
VideoSink
. Reference the
Custom Video Sink quickstart
for more details.
The table below highlights the updated app size impact.
ABI | App Size Impact 5.x | App Size Impact 6.0.0-preview1 |
---|---|---|
universal | 21.9MB | 19.5MB |
armeabi-v7a | 4.8MB | 4.1MB |
arm64-v8a | 5.7MB | 5.1MB |
x86 | 6MB | 5.5MB |
x86_64 | 6.1MB | 5.4MB |