Skip to contentSkip to navigationSkip to topbar
On this page

Twilio Video Quickstart for JavaScript


Run the Twilio Video quickstart app(link takes you to an external page) to see the Twilio Video JavaScript SDK in action. Then explore the code to learn how to build your own video application using the SDK.

A Twilio Video app has three main components. This guide describes the front-end application and the Video Room functionality. To learn how the quickstart app implements an access token server using Express, see /server/index.js in the quickstart app(link takes you to an external page).


Prerequisites

prerequisites page anchor

Install Node.js and gather the credentials you need to run the quickstart app.

Install Node.js

install-nodejs page anchor

Install Node.js(link takes you to an external page) on your local machine. The quickstart app uses Node.js to run a local web server.

API keys represent credentials to access the Twilio API.

  1. Create an API key in the API keys & tokens(link takes you to an external page) section of the Twilio Console.
  2. Save the API key SID and secret in a secure place. The secret is only shown once when you create the key.

Learn more about API Keys.

Get your Account SID from the Twilio Console dashboard home page(link takes you to an external page).


Clone and configure the quickstart app

clone-and-configure-the-quickstart-app page anchor
  1. Clone the Twilio Video JavaScript quickstart app repository to your local machine. For example:

    git clone https://github.com/twilio/video-quickstart-js.git
    (information)

    Customizing the quickstart app?

    To use the quickstart app as a starting point for your own application, you can fork(link takes you to an external page) the twilio/video-quickstart-js(link takes you to an external page) repository to your GitHub account, then clone your fork.

  2. Change to the video-quickstart-js directory:

    cd video-quickstart-js
  3. Create a .env file from the template:

    cp .env.template .env
  4. Edit the new .env file. Replace the placeholders with your credentials from the Prerequisites section:

    1
    TWILIO_ACCOUNT_SID=ACxxxxxxxxxx
    2
    TWILIO_API_KEY=SKxxxxxxxxxx
    3
    TWILIO_API_SECRET=xxxxxxxxxx
  5. Install the dependencies:

    npm install

Run the quickstart app locally and join a Video Room

run-the-quickstart-app-locally-and-join-a-video-room page anchor
  1. Run the application:

    npm start
  2. Open your web browser to http://localhost:3000(link takes you to an external page).

  3. When prompted, test and choose your microphone and camera.

    (information)

    Info

    Desktop browsers save your choices. On mobile browsers, you're prompted to test and choose your microphone and camera every time you load the application to make sure they're not reserved by another application.

  4. Enter a Room name and your user name, then click Join Room. You should see your own camera feed and name displayed.

To test the multi-Participant functionality, you can open another browser tab and enter the same Room name to join the Room and see and hear yourself on both tabs.


Explore Twilio Video capabilities with the quickstart app code

explore-twilio-video-capabilities-with-the-quickstart-app-code page anchor

The quickstart app's quickstart/src/joinroom.js file demonstrates how to use the Video SDK APIs to build a multi-participant video session. You can incorporate this code into your application and build your user interface around it.

The Twilio Video API includes the following resources:

  • Room: The real-time audio, data, video and screen-share session. It's the basic building block for a Programmable Video application.
  • Participants: The client applications that are connected to a Room and sharing audio, data, and video media with one another.
  • Tracks: The audio, data, and video media streams that are shared within a Room.
  • LocalTracks: The audio, data, and video captured from the local client's media sources (for example, microphone and camera).
  • RemoteTracks: The audio, data, and video tracks from other participants connected to the Room.
(information)

Info

The UI code in the quickstart app uses jQuery, but you can use the Twilio Video SDK with any framework.

The following sections describe the key parts of the quickstart app code that use the Twilio Video JavaScript SDK to connect to a Room, set up local media, work with remote Participants, and participate in a Room.

Connect to a new or existing Room

connect-to-a-new-or-existing-room page anchor

joinroom.js makes a single call to the Video SDK's connect() API to create a new Room or to join an existing Room.

1
async function joinRoom(token, connectOptions) {
2
3
// Join to the Room with the given AccessToken and ConnectOptions.
4
const room = await connect(token, connectOptions);
5
6
}

token is required and is the Access Token obtained from the back-end server (not described in this quickstart). connectOptions are optional and can include name, audio, video, and other properties.

(information)

Ad-hoc Room creation

The name of the Room specifies the Room to join. If you're using client-side Room ("ad-hoc Room") creation for your account and a Room by that name doesn't already exist, it's created upon connection. If a Room by that name is already active, the Participant is connected to the Room and can receive notifications from any other Participants also connected to the same Room. Room names must be unique within an account.

Listen for Participant events in a Room

listen-for-participant-events-in-a-room page anchor

The quickstart app registers event listeners for all Participant lifecycle events immediately after it connects.

1
// Handle the LocalParticipant's media.
2
participantConnected(room.localParticipant, room);
3
4
// Subscribe to RemoteParticipants already in the Room.
5
room.participants.forEach(participant => {
6
participantConnected(participant, room);
7
});
8
9
// Subscribe to RemoteParticipants joining later.
10
room.on('participantConnected', participant => {
11
participantConnected(participant, room);
12
});
13
14
// Handle a disconnected RemoteParticipant.
15
room.on('participantDisconnected', participant => {
16
participantDisconnected(participant, room);
17
});

participantConnected and participantDisconnected are the helper functions that attach and detach media and update the user interface.

Immediately after connecting, the app stores the LocalVideoTrack that connect() created for you.

1
let localVideoTrack =
2
Array.from(room.localParticipant.videoTracks.values())[0].track;

When a Participant backgrounds the app (mobile browsers), the app stops and unpublishes the track.

1
localVideoTrack.stop();
2
room.localParticipant.unpublishTrack(localVideoTrack);

The app creates a new track (respecting any constraints present in connectOptions.video) when the app returns to the foreground.

1
localVideoTrack = await createLocalVideoTrack(connectOptions.video);
2
await room.localParticipant.publishTrack(localVideoTrack);

Display a camera preview

display-a-camera-preview page anchor

The app renders the local Participant's camera the same way as any remote track. Upon connection, participantConnected immediately calls attachTrack so the local preview appears instantly.

participantConnected(room.localParticipant, room);

Working with Remote Participants

working-with-remote-participants page anchor

When a remote Participant joins the Room, the quickstart app sets up event listeners to attach newly published audio and video tracks in real time. The app updates the UI to render each Participant's media and clean up if they disconnect.

1
function participantConnected(participant, room) {
2
// Set up the Participant's media container.
3
setupParticipantContainer(participant, room);
4
5
// Tracks already published.
6
participant.tracks.forEach(publication => {
7
trackPublished(publication, participant);
8
});
9
10
// Tracks that will be published later.
11
participant.on('trackPublished', publication => {
12
trackPublished(publication, participant);
13
});
14
}
15
16
function trackPublished(publication, participant) {
17
if (publication.track) {
18
attachTrack(publication.track, participant);
19
}
20
publication.on('subscribed', track => attachTrack(track, participant));
21
publication.on('unsubscribed', track => detachTrack(track, participant));
22
}

attachTrack renders the audio or video into the app's page.

1
function attachTrack(track, participant) {
2
const $media = $(`div#${participant.sid} > ${track.kind}`, $participants);
3
$media.css('opacity', '');
4
track.attach($media.get(0));
5
6
if (track.kind === 'video' && participant === activeParticipant) {
7
track.attach($activeVideo.get(0));
8
$activeVideo.css('opacity', '');
9
}
10
}

Mute and unmute audio and video

mute-and-unmute-audio-and-video page anchor

The quickstart app automatically mutes video when the app is backgrounded and unmutes when the app returns to the foreground.

1
// Mute (backgrounded)
2
localVideoTrack.stop();
3
room.localParticipant.unpublishTrack(localVideoTrack);
4
5
// Unmute (foregrounded)
6
localVideoTrack = await createLocalVideoTrack(connectOptions.video);
7
await room.localParticipant.publishTrack(localVideoTrack);

To disconnect from a room, the application can call room.disconnect() in response to user actions or events.

When the user clicks the Leave Room button, the app disconnects from the room.

1
$leave.click(function onLeave() {
2
$leave.off('click', onLeave);
3
$togglePip.off('click', togglePipButtonHandler);
4
room.disconnect();
5
});

The app automatically disconnects when the Participant leaves or reloads the app page, or closes the tab.

1
window.onbeforeunload = () => { room.disconnect(); };
2
window.onpagehide = () => { room.disconnect(); }; // iOS Safari

After the SDK emits the disconnected event, the app performs the final resource cleanup.

1
room.once('disconnected', (room, error) => {
2
3
localVideoTrack.stop();
4
participantDisconnected(room.localParticipant, room);
5
room.participants.forEach(participant => {
6
participantDisconnected(participant, room);
7
});
8
$activeVideo.get(0).srcObject = null;
9
window.room = null;
10
11
});