JavaScript/TypeScript client SDK for LiveKit
livekit-client
is the official client SDK for LiveKit. With it, you can add real time video and audio to your web apps.
Docs
Docs and guides at https://docs.livekit.io
SDK reference
Installation
Yarn
yarn add livekit-client
NPM
npm install livekit-client --save
Usage
Examples below are in TypeScript, if using JS/CommonJS imports replace import with:
const LiveKit = require('livekit-client');
LiveKit.connect(...);
Connecting to a room, publish video & audio
import {
connect,
RoomEvent,
RemoteParticipant,
RemoteTrackPublication,
RemoteTrack,
Participant,
} from 'livekit-client';
connect('ws://localhost:7800', token, {
audio: true,
video: true,
}).then((room) => {
console.log('connected to room', room.name);
console.log('participants in room:', room.participants.size);
room
.on(RoomEvent.TrackSubscribed, handleTrackSubscribed)
.on(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed)
.on(RoomEvent.ActiveSpeakersChanged, handleActiveSpeakerChange)
.on(RoomEvent.Disconnected, handleDisconnect);
});
function handleTrackSubscribed(
track: RemoteTrack,
publication: RemoteTrackPublication,
participant: RemoteParticipant
) {
if (track.kind === Track.Kind.Video || track.kind === Track.Kind.Audio) {
const element = track.attach();
parentElement.appendChild(element);
}
}
function handleTrackUnsubscribed(
track: RemoteTrack,
publication: RemoteTrackPublication,
participant: RemoteParticipant
) {
track.detach();
}
function handleActiveSpeakerChange(speakers: Participant[]) {
}
function handleDisconnect() {
console.log('disconnected from room');
}
In order to connect to a room, you need to first create an access token.
See access token docs for details
Handling common track types
While LiveKit is designed to be flexible, we've added a few shortcuts that makes working with common track types simple. For a user's camera, microphone, and screen share, you can enable them with the following LocalParticipant
methods:
const p = room.localParticipant;
await p.setCameraEnabled(true);
await p.setMicrophoneEnabled(true);
await p.setScreenShareEnabled(true);
await p.setCameraEnabled(false);
Similarly, you can access these common track types on the other participants' end.
const p = room.participants.get('participant-sid');
if (p) {
if (p.isCameraEnabled) {
const track = p.getTrack(Track.Source.Camera);
if (track?.isSubscribed) {
const videoElement = track.attach()
}
}
}
Advanced track manipulation
LiveKit lets you publish any track as long as it can be represented by a MediaStreamTrack. You can specify a name on the track in order to identify it later.
const pub = await room.localParticipant.publishTrack(mediaStreamTrack, {
name: 'mytrack',
simulcast: true,
source: Track.Source.Camera,
})
pub.setMuted(true);
room.localParticipant.unpublishTrack(mediaStreamTrack)
Device management APIs
Users may have multiple input and output devices available. LiveKit will automatically use the one that's deemed as the default
device on the system. You may also list and specify an alternative device to use.
We use the same deviceId as one returned by MediaDevices.enumerateDevices().
Example listing and selecting a camera device
const devices = await Room.getLocalDevices('audioinput');
const device = devices[devices.length-1];
await room.switchActiveDevice('audioinput', device.deviceId);
You can also switch devices given a constraint. This could be useful on mobile devices to switch to a back-facing camera:
await videoTrack.restartTrack({
facingMode: 'environment',
});
Handling device failures
When creating tracks using LiveKit APIs (connect
, createLocalTracks
, setCameraEnabled
, etc), it's possible to encounter errors with the underlying media device. In those cases, LiveKit will emit RoomEvent.MediaDevicesError
.
You can use the helper MediaDeviceFailure.getFailure(error)
to determine specific reason for the error.
PermissionDenied
- the user disallowed capturing devicesNotFound
- the particular device isn't availableDeviceInUse
- device is in use by another process (happens on Windows)
These distinctions enables you to provide more specific messaging to the user.
You could also retrieve the last error with getLastAudioCreateError
and getLastVideoCreateError
.
Audio playback
Browsers can be restrictive with regards to audio playback that is not initiated by user interaction. What each browser considers as user interaction can vary by vendor (for example, Safari on iOS is very restrictive).
LiveKit will attempt to autoplay all audio tracks when you attach them to audio elements. However, if that fails, we'll notify you via RoomEvent.AudioPlaybackStatusChanged
. Room.canPlayAudio
will indicate if audio playback is permitted. LiveKit takes an optimistic approach so it's possible for this value to change from true
to false
when we encounter a browser error.
In the case user interaction is required, LiveKit provides Room.startAudio
to start audio playback. This function must be triggered in an onclick or ontap event handler. In the same session, once audio playback is successful, additional audio tracks can be played without further user interactions.
room.on(RoomEvent.AudioPlaybackStatusChanged, () => {
if (!room.canPlayAudio) {
...
button.onclick = () => {
room.startAudio().then(() => {
button.remove();
});
}
}
});
Configuring logging
This library uses loglevel for its internal logs. You can change the effective log level with the logLevel
field in ConnectOptions
.
Examples
SDK Sample
example/sample.ts contains a demo webapp that uses the SDK. Run it with yarn sample
Browser Support
Browser | Desktop OS | Mobile OS |
---|
Chrome | Windows, macOS, Linux | Android |
Firefox | Windows, macOS, Linux | Android |
Safari | macOS | iOS |
Edge (Chromium) | Windows, macOS | |