Skip to contentSkip to navigationSkip to topbar
Page tools
Useful for sharing or LLM
Accelerate development with AI

On this page
Looking for more inspiration?Visit the

Video Media SDK for Node.js quickstart


This quickstart shows how to connect to a Video Room from a Node.js server, publish a video track by pushing raw frames, and receive decoded frames from remote Participants. To learn what the SDK is and how it differs from the client-side SDKs, see the Overview.


Prerequisites

prerequisites page anchor

To use the Video Media SDK, you need the following prerequisites:

  • Create a Twilio account(link takes you to an external page).

  • Install Node.js version 24.0.0 or later on Linux x64 or macOS x64. On an Apple Silicon Mac, run an x64 build of Node.js under Rosetta. To learn more, see system requirements.

  • Create an API key SID and secret.


  1. Install the SDK npm packages.
    1
    npm install @twilio/video-node
    2
    npm install @twilio/video-node-sdk
  2. In your app, add the import statement for the SDK:
    const { connect, createLocalVideoTrack } = require('@twilio/video-node-sdk');

The connect() function takes a standard Twilio Video Access Token with a VideoGrant, the same token format the JavaScript SDK uses. Generate an Access Token on your server with the twilio helper library(link takes you to an external page).

Create an access token example

create-an-access-token-example page anchor
1
const twilio = require('twilio');
2
3
function generateToken(identity, roomName) {
4
const token = new twilio.jwt.AccessToken(
5
process.env.TWILIO_ACCOUNT_SID,
6
process.env.TWILIO_API_KEY,
7
process.env.TWILIO_API_SECRET,
8
{ identity, ttl: 3600 },
9
);
10
token.addGrant(new twilio.jwt.AccessToken.VideoGrant({ room: roomName }));
11
return token.toJwt();
12
}
(warning)

Treat an API Key like a password

Keep your API key secret on the server. Never ship Twilio credentials in client-side code or commit the controls to source control.


Create a local video track then pass it to connect(). The call resolves once the Room connects.

Connect to a Room example

connect-to-a-room-example page anchor
1
const { connect, createLocalVideoTrack } = require('@twilio/video-node-sdk');
2
3
const videoTrack = createLocalVideoTrack('virtual-camera');
4
5
const room = await connect(generateToken('node-participant', 'my-room'), {
6
name: 'my-room',
7
videoTracks: [videoTrack],
8
});
9
10
console.log('Connected to Room:', room.name, room.sid);

Unlike the client-side SDKs, a local track lacks a camera. To supply raw I420 video frames, call the write() method on the track. Each call takes the y, u, and v planes as Buffer objects, along with their strides and the frame dimensions.

1
videoTrack.write({
2
y: yPlane, // Buffer
3
u: uPlane, // Buffer
4
v: vPlane, // Buffer
5
yStride: 1280,
6
uStride: 640,
7
vStride: 640,
8
width: 1280,
9
height: 720,
10
});
(information)

Connect before you send

Resolve connect(), then send frames. Any frames before that resolution get dropped. Start your send loop after the await returns.

To learn about I420 video planes and strides and PCM audio, see Work with media frames.


Receive media from remote Participants

receive-media-from-remote-participants page anchor

Remote media arrives as raw decoded frames. Listen for trackSubscribed, then register an onFrame() callback on each video or audio track.

1
function trackSubscribed(track) {
2
if (track.kind === 'video') {
3
track.onFrame(frame => {
4
console.log(`Received ${frame.width}x${frame.height} frame`);
5
});
6
}
7
}
8
9
function participantConnected(participant) {
10
participant.on('trackSubscribed', trackSubscribed);
11
12
// A track can finish subscribing before this listener is attached.
13
participant.tracks.forEach(publication => {
14
if (publication.isSubscribed) {
15
trackSubscribed(publication.track);
16
}
17
});
18
}
19
20
// participantConnected doesn't fire for Participants already in the Room, so
21
// seed from room.participants, then listen for Participants who join later.
22
room.participants.forEach(participantConnected);
23
room.on('participantConnected', participantConnected);

The SDK repository(link takes you to an external page) includes runnable examples. The virtual_camera.js(link takes you to an external page) example decodes an MP4 with ffmpeg and sends its frames into a Room.

1
git clone https://github.com/twilio/twilio-video-node.git
2
cd twilio-video-node
3
cp .env.example .env
4
# Edit .env and set TWILIO_ACCOUNT_SID, TWILIO_API_KEY, and TWILIO_API_SECRET.
5
node examples/virtual_camera.js my-room

To review every example, see the examples directory(link takes you to an external page).