Twilio Video Quickstart for JavaScript
Run the Twilio Video quickstart app 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.
Install Node.js and gather the credentials you need to run the quickstart app.
Install Node.js 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.
- Create an API key in the API keys & tokens section of the Twilio Console.
- 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.
-
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 the twilio/video-quickstart-js repository to your GitHub account, then clone your fork.
-
Change to the
video-quickstart-js
directory:cd video-quickstart-js -
Create a
.env
file from the template:cp .env.template .env -
Edit the new
.env
file. Replace the placeholders with your credentials from the Prerequisites section:1TWILIO_ACCOUNT_SID=ACxxxxxxxxxx2TWILIO_API_KEY=SKxxxxxxxxxx3TWILIO_API_SECRET=xxxxxxxxxx -
Install the dependencies:
npm install
-
Run the application:
npm start -
Open your web browser to http://localhost:3000.
-
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.
-
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.
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.
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.
joinroom.js
makes a single call to the Video SDK's connect()
API to create a new Room or to join an existing Room.
1async function joinRoom(token, connectOptions) {2…3// Join to the Room with the given AccessToken and ConnectOptions.4const 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.
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.
The quickstart app registers event listeners for all Participant lifecycle events immediately after it connects.
1// Handle the LocalParticipant's media.2participantConnected(room.localParticipant, room);34// Subscribe to RemoteParticipants already in the Room.5room.participants.forEach(participant => {6participantConnected(participant, room);7});89// Subscribe to RemoteParticipants joining later.10room.on('participantConnected', participant => {11participantConnected(participant, room);12});1314// Handle a disconnected RemoteParticipant.15room.on('participantDisconnected', participant => {16participantDisconnected(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.
1let localVideoTrack =2Array.from(room.localParticipant.videoTracks.values())[0].track;
When a Participant backgrounds the app (mobile browsers), the app stops and unpublishes the track.
1localVideoTrack.stop();2room.localParticipant.unpublishTrack(localVideoTrack);
The app creates a new track (respecting any constraints present in connectOptions.video
) when the app returns to the foreground.
1localVideoTrack = await createLocalVideoTrack(connectOptions.video);2await room.localParticipant.publishTrack(localVideoTrack);
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);
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.
1function participantConnected(participant, room) {2// Set up the Participant's media container.3setupParticipantContainer(participant, room);45// Tracks already published.6participant.tracks.forEach(publication => {7trackPublished(publication, participant);8});910// Tracks that will be published later.11participant.on('trackPublished', publication => {12trackPublished(publication, participant);13});14}1516function trackPublished(publication, participant) {17if (publication.track) {18attachTrack(publication.track, participant);19}20publication.on('subscribed', track => attachTrack(track, participant));21publication.on('unsubscribed', track => detachTrack(track, participant));22}
attachTrack
renders the audio or video into the app's page.
1function attachTrack(track, participant) {2const $media = $(`div#${participant.sid} > ${track.kind}`, $participants);3$media.css('opacity', '');4track.attach($media.get(0));56if (track.kind === 'video' && participant === activeParticipant) {7track.attach($activeVideo.get(0));8$activeVideo.css('opacity', '');9}10}
The quickstart app automatically mutes video when the app is backgrounded and unmutes when the app returns to the foreground.
1// Mute (backgrounded)2localVideoTrack.stop();3room.localParticipant.unpublishTrack(localVideoTrack);45// Unmute (foregrounded)6localVideoTrack = await createLocalVideoTrack(connectOptions.video);7await 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);4room.disconnect();5});
The app automatically disconnects when the Participant leaves or reloads the app page, or closes the tab.
1window.onbeforeunload = () => { room.disconnect(); };2window.onpagehide = () => { room.disconnect(); }; // iOS Safari
After the SDK emits the disconnected
event, the app performs the final resource cleanup.
1room.once('disconnected', (room, error) => {2…3localVideoTrack.stop();4participantDisconnected(room.localParticipant, room);5room.participants.forEach(participant => {6participantDisconnected(participant, room);7});8$activeVideo.get(0).srcObject = null;9window.room = null;10…11});
- Install the Twilio Video JavaScript SDK.
- Check out the full-featured Twilio Video React app.
- Learn how the Twilio Video API gives you control of your video application from your back-end server using HTTP requests.