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.
Before you can run the quickstart app, you need to install Node.js and gather your Twilio account credentials.
Install Node.js on your local machine. The quickstart app uses Node.js to run a local web server.
API keys represent credentials that allow your application 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.
Follow these steps to download the quickstart app and set up your Twilio credentials:
-
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-jsdirectory:cd video-quickstart-js -
Create a
.envfile from the template:cp .env.template .env -
Edit the new
.envfile. 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
After configuring the app, you can run it locally and test joining a Video Room:
-
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.
The joinroom.js file 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}
The function accepts two parameters:
tokenis required and is the Access Token obtained from the back-end server (not described in this quickstart).connectOptionsare optional and can includename,audio,video, and other properties.
Ad-hoc Room creation
The name of the Room specifies which 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});
The participantConnected and participantDisconnected functions are helper methods 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 (on 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}
The attachTrack function 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});
Now that you've run the quickstart app and understand the basics of connecting to a Room, explore these resources to build and enhance your video application:
- Install the Twilio Video JavaScript SDK: Add the SDK to your own project
- Twilio Video React app: Explore a full-featured video application built with React
- Video app components: Understand the architecture of a complete video application