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.
To use the Video Media SDK, you need the following prerequisites:
-
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.
View how to create an API Key
- Install the SDK npm packages.
1npm install @twilio/video-node2npm install @twilio/video-node-sdk
- 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.
1const twilio = require('twilio');23function generateToken(identity, roomName) {4const token = new twilio.jwt.AccessToken(5process.env.TWILIO_ACCOUNT_SID,6process.env.TWILIO_API_KEY,7process.env.TWILIO_API_SECRET,8{ identity, ttl: 3600 },9);10token.addGrant(new twilio.jwt.AccessToken.VideoGrant({ room: roomName }));11return token.toJwt();12}
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.
1const { connect, createLocalVideoTrack } = require('@twilio/video-node-sdk');23const videoTrack = createLocalVideoTrack('virtual-camera');45const room = await connect(generateToken('node-participant', 'my-room'), {6name: 'my-room',7videoTracks: [videoTrack],8});910console.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.
1videoTrack.write({2y: yPlane, // Buffer3u: uPlane, // Buffer4v: vPlane, // Buffer5yStride: 1280,6uStride: 640,7vStride: 640,8width: 1280,9height: 720,10});
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.
Remote media arrives as raw decoded frames. Listen for trackSubscribed, then register an onFrame() callback on each video or audio track.
1function trackSubscribed(track) {2if (track.kind === 'video') {3track.onFrame(frame => {4console.log(`Received ${frame.width}x${frame.height} frame`);5});6}7}89function participantConnected(participant) {10participant.on('trackSubscribed', trackSubscribed);1112// A track can finish subscribing before this listener is attached.13participant.tracks.forEach(publication => {14if (publication.isSubscribed) {15trackSubscribed(publication.track);16}17});18}1920// participantConnected doesn't fire for Participants already in the Room, so21// seed from room.participants, then listen for Participants who join later.22room.participants.forEach(participantConnected);23room.on('participantConnected', participantConnected);
The SDK repository includes runnable examples. The virtual_camera.js example decodes an MP4 with ffmpeg and sends its frames into a Room.
1git clone https://github.com/twilio/twilio-video-node.git2cd twilio-video-node3cp .env.example .env4# Edit .env and set TWILIO_ACCOUNT_SID, TWILIO_API_KEY, and TWILIO_API_SECRET.5node examples/virtual_camera.js my-room
To review every example, see the examples directory.
- Work with media frames: Learn the I420 video and PCM audio frame formats in depth.
- Differences from the JavaScript SDK: Map what you know from the browser SDK to the server.
- Best practices: Pace frames, manage resources, and troubleshoot common issues.