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.
This guide provides an introduction to the 2.x Programmable Video JavaScript SDK (twilio-video.js) and a set of guidelines to migrate an application from 1.x to 2.x.
In twilio-video.js 2.x, you can now determine how your downlink bandwidth will be distributed among your subscribed RemoteVideoTracks in a Group Room using the Network Bandwidth Profile API. You can also use the Track Priority API to prioritize certain VideoTracks over others in order to protect audio and higher priority video qualities in times of network congestion.
In twilio-video.js 1.x, you would be disconnected from the Room if you experienced network disruption or handoff. twilio-video.js 2.x will instead attempt to re-establish your signaling and media connections to the Room. You can use the Reconnection States and Events to update your application's user interface accordingly. For more details, please refer to this guide.
NOTE: Please make the following changes to your AccessToken generation logic:
In twilio-video.js 2.x, your Participant will connect to the nearest region
as determined by latency based routing.
If you want your signaling traffic to originate and terminate in a specific region,
you can do so using a new ConnectOptions flag region
:
1const { connect } = require('twilio-video');2const room = await connect(token, {3region: 'de1'4});
In twilio-video.js 2.x, you can choose not to subscribe to any Tracks published by other
Participants in a Group or Small Group Room by setting a new ConnectOptions flag automaticSubscription
to false
:
1const { connect } = require('twilio-video');2const room = await connect(token, {3automaticSubscription: false4});
In twilio-video.js 1.x, developers primarily interacted with the LocalParticipant's and RemoteParticipants' media using Tracks. In twilio-video.js 2.x, developers will interact with TrackPublications, which basically represent Tracks that are published to the Room by its Participants. LocalTracks that are published by the LocalParticipant are represented by LocalTrackPublications, and RemoteTracks that are published by RemoteParticipants are represented by RemoteTrackPublications.
A LocalTrackPublication is created when a LocalParticipant successfully publishes
a LocalTrack, whether by adding it to the ConnectOptions' tracks
array, or by
using the LocalParticipant's publishTrack()
or publishTracks()
methods.
Publish a LocalTrack while connecting to a Room
1const { connect, createLocalVideoTrack } = require('twilio-video');23const videoTrack = await createLocalVideoTrack();45const room = await connect('$TOKEN', {6name: 'my-room',7tracks: [videoTrack]8});910function trackPublished(publication) {11console.log(`Published LocalTrack: ${publication.track}`);12}1314// Access the already published LocalTracks.15room.localParticipant.tracks.forEach(trackPublished);
Publish a LocalTrack after connecting to a Room
1// Access LocalTracks that are published after connecting to the Room.2room.localParticipant.on('trackPublished', trackPublished);34const audioTrack = await createLocalVideoTrack();56// publishTrack() resolves with a LocalTrackPublication when the LocalTrack is7// successfully published.8const audioTrackPublication = await room.localParticipant.publishTrack(audioTrack);910trackPublished(audioTrackPublication);
In order to unpublish the LocalTrack, the developer can either use the
LocalTrackPublication's unpublish()
method, or the LocalParticipant's
unpublishTrack()
method. The LocalTrackPublication maintains a reference to
the published LocalTrack through its track
property.
Unpublish a LocalTrack using LocalTrackPublication#unpublish
audioTrackPublication.unpublish();
Unpublish a LocalTrack using LocalParticipant#unpublishTrack
room.localParticipant.unpublishTrack(videoTrack);
A RemoteTrackPublication is created when a RemoteParticipant successfully publishes
a RemoteTrack. In twilio-video.js 1.x, the LocalParticipant always subscribed to
each published RemoteTrack. In 2.x, we are moving towards the LocalParticipant
being able to subscribe to only the desired RemoteTracks. In this regard,
RemoteTracks that are not yet subscribed to will have their RemoteTrackPublications'
isSubscribed
property set to false
, and their track
property set to null
.
A subscribed RemoteTrack will have its RemoteTrackPublication's isSubscribed
property set to true
, and the track
property will be set to the subscribed
RemoteTrack. When a RemoteTrack is subscribed to, a "subscribed" event is emitted
on the RemoteTrackPublication. When a RemoteTrack is unsubscribed from, an
"unsubscribed" event is emitted on the RemoteTrackPublication.
1const { connect } = require('twilio-video');23const room = await connect('$TOKEN', {4name: 'my-room'5});67function trackPublished(publication, participant) {8console.log(`RemoteParticipant ${participant.identity} published a RemoteTrack: ${publication}`);9assert(!publication.isSubscribed);10assert.equal(publication.track, null);1112publication.on('subscribed', track => {13console.log(`LocalParticipant subscribed to a RemoteTrack: ${track}`);14assert(publication.isSubscribed);15assert(publication.track, track);16});1718publication.on('unsubscribed', track => {19console.log(`LocalParticipant unsubscribed from a RemoteTrack: ${track}`);20assert(!publication.isSubscribed);21assert.equal(publication.track, null);22});23}2425function participantConnected(participant) {26participant.tracks.forEach(publication => {27trackPublished(publication, participant);28});2930participant.on('trackPublished', publication => {31trackPublished(publication, participant);32});3334participant.on('trackUnpublished', publication => {35console.log(`RemoteParticipant ${participant.identity} unpublished a RemoteTrack: ${publication}`);36});37}3839room.participants.forEach(participantConnected);40room.on('participantConnected', participantConnected);
NOTE: We do not have support for Track subscriptions yet. So each LocalParticipant will subscribe to all the published RemoteTracks. The only way a LocalParticipant unsubscribes from a RemoteTrack is if the RemoteParticipant unpublishes it. So:
When a RemoteParticipant publishes a RemoteTrack, the following events are emitted in the given order:
When a RemoteParticipant unpublishes a RemoteTrack, the following events are emitted in the given order:
dscpTagging
has been deprecated and renamed to
enableDscp
.
tracks
is now a collection of LocalTrackPublications instead of a collection of LocalTracks.
audioTracks
is now a collection of LocalAudioTrackPublications instead of a collection of LocalAudioTracks.
dataTracks
is now a collection of LocalDataTrackPublications instead of a collection of LocalDataTracks.
videoTracks
is now a collection of LocalVideoTrackPublications instead of a collection of LocalVideoTracks.
addTrack()
is now replaced by
publishTrack()
.
addTracks()
is now replaced by
publishTracks()
.
removeTrack()
is now replaced by
unpublishTrack()
.
removeTracks()
is now replaced by
unpublishTracks()
.
tracks
is now a collection of RemoteTrackPublications instead of a collection of RemoteTracks.
audioTracks
is now a collection of RemoteAudioTrackPublications instead of a collection of RemoteAudioTracks.
dataTracks
is now a collection of RemoteDataTrackPublications instead of a collection of RemoteDataTracks.
videoTracks
is now a collection of RemoteVideoTrackPublications instead of a collection of RemoteVideoTracks.
id
is no longer available. Use
sid
or
name
instead.
isSubscribed
is no longer available. Use the corresponding RemoteTrackPublication's
isSubscribed
instead.