Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

livekit-client

livekit390.3kApache-2.02.11.3TypeScript support: included

JavaScript/TypeScript client SDK for LiveKit

readme

<picture> <source media="(prefers-color-scheme: dark)" srcset="/.github/banner_dark.png"> <source media="(prefers-color-scheme: light)" srcset="/.github/banner_light.png"> The LiveKit icon, the name of the repository and some sample code in the background. </picture>

JavaScript/TypeScript client SDK for LiveKit

Use this SDK to add realtime video, audio and data features to your JavaScript/TypeScript app. By connecting to LiveKit Cloud or a self-hosted server, you can quickly build applications such as multi-modal AI, live streaming, or video calls with just a few lines of code.

Docs

Docs and guides at https://docs.livekit.io

SDK reference

[!NOTE] This is v2 of livekit-client. When migrating from v1.x to v2.x you might encounter a small set of breaking changes. Read the migration guide for a detailed overview of what has changed.

Installation

Yarn

yarn add livekit-client

NPM

npm install livekit-client --save

Minified JS

To use the SDK without a package manager, you can include it with a script tag:

<script src="https://cdn.jsdelivr.net/npm/livekit-client/dist/livekit-client.umd.min.js"></script>

The module will be exported under LivekitClient in the global namespace. When accessing symbols from the class, you'd need to prefix them with LivekitClient.. For example, Room becomes LivekitClient.Room.

Usage

Examples below are in TypeScript, if using JS/CommonJS imports replace import with:

const livekit = require('livekit-client');

const room = new livekit.Room(...);

// call this some time before actually connecting to speed up the actual connection
room.prepareConnection(url, token);

await room.connect(...);

Connecting to a room, publish video & audio

import {
  LocalParticipant,
  LocalTrackPublication,
  Participant,
  RemoteParticipant,
  RemoteTrack,
  RemoteTrackPublication,
  Room,
  RoomEvent,
  Track,
  VideoPresets,
} from 'livekit-client';

// creates a new room with options
const room = new Room({
  // automatically manage subscribed video quality
  adaptiveStream: true,

  // optimize publishing bandwidth and CPU for published tracks
  dynacast: true,

  // default capture settings
  videoCaptureDefaults: {
    resolution: VideoPresets.h720.resolution,
  },
});

// pre-warm connection, this can be called as early as your page is loaded
room.prepareConnection(url, token);

// set up event listeners
room
  .on(RoomEvent.TrackSubscribed, handleTrackSubscribed)
  .on(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed)
  .on(RoomEvent.ActiveSpeakersChanged, handleActiveSpeakerChange)
  .on(RoomEvent.Disconnected, handleDisconnect)
  .on(RoomEvent.LocalTrackUnpublished, handleLocalTrackUnpublished);

// connect to room
await room.connect('ws://localhost:7800', token);
console.log('connected to room', room.name);

// publish local camera and mic tracks
await room.localParticipant.enableCameraAndMicrophone();

function handleTrackSubscribed(
  track: RemoteTrack,
  publication: RemoteTrackPublication,
  participant: RemoteParticipant,
) {
  if (track.kind === Track.Kind.Video || track.kind === Track.Kind.Audio) {
    // attach it to a new HTMLVideoElement or HTMLAudioElement
    const element = track.attach();
    parentElement.appendChild(element);
  }
}

function handleTrackUnsubscribed(
  track: RemoteTrack,
  publication: RemoteTrackPublication,
  participant: RemoteParticipant,
) {
  // remove tracks from all attached elements
  track.detach();
}

function handleLocalTrackUnpublished(
  publication: LocalTrackPublication,
  participant: LocalParticipant,
) {
  // when local tracks are ended, update UI to remove them from rendering
  publication.track.detach();
}

function handleActiveSpeakerChange(speakers: Participant[]) {
  // show UI indicators when participant is speaking
}

function handleDisconnect() {
  console.log('disconnected from room');
}

In order to connect to a room, you need to first create an access token.

See authentication 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;
// turn on the local user's camera and mic, this may trigger a browser prompt
// to ensure permissions are granted
await p.setCameraEnabled(true);
await p.setMicrophoneEnabled(true);

// start sharing the user's screen, this will trigger a browser prompt to select
// the screen to share.
await p.setScreenShareEnabled(true);

// disable camera to mute them, when muted, the user's camera indicator will be turned off
await p.setCameraEnabled(false);

Similarly, you can access these common track types on the other participants' end.

// get a RemoteParticipant by their identity
const p = room.remoteParticipants.get('participant-identity');
if (p) {
  // if the other user has enabled their camera, attach it to a new HTMLVideoElement
  if (p.isCameraEnabled) {
    const publication = p.getTrackPublication(Track.Source.Camera);
    if (publication?.isSubscribed) {
      const videoElement = publication.videoTrack?.attach();
      // do something with the element
    }
  }
}

Creating a track prior to creating a room

In some cases, it may be useful to create a track before creating a room. For example, when building a staging area so the user may check their own camera.

You can use our global track creation functions for this:

const tracks = await createLocalTracks({
  audio: true,
  video: true,
});

Publish tracks from any source

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,
  // if this should be treated like a camera feed, tag it as such
  // supported known sources are .Camera, .Microphone, .ScreenShare
  source: Track.Source.Camera,
});

// you may mute or unpublish the track later
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

// list all microphone devices
const devices = await Room.getLocalDevices('audioinput');

// select last device
const device = devices[devices.length - 1];

// in the current room, switch to the selected device and set
// it as default audioinput in the future.
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 devices
  • NotFound - the particular device isn't available
  • DeviceInUse - 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 LocalParticipant.lastCameraError and LocalParticipant.lastMicrophoneError.

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.canPlaybackAudio 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.canPlaybackAudio) {
    // UI is necessary.
    ...
    button.onclick = () => {
      // startAudio *must* be called in an click/tap handler.
      room.startAudio().then(() => {
        // successful, UI can be removed now
        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. The method setLogExtension allows to hook into the livekit internal logs and send them to some third party logging service

setLogExtension((level: LogLevel, msg: string, context: object) => {
  const enhancedContext = { ...context, timeStamp: Date.now() };
  if (level >= LogLevel.debug) {
    console.log(level, msg, enhancedContext);
  }
});

RPC

Perform your own predefined method calls from one participant to another.

This feature is especially powerful when used with Agents, for instance to forward LLM function calls to your client application.

Registering an RPC method

The participant who implements the method and will receive its calls must first register support:

room.localParticipant?.registerRpcMethod(
  // method name - can be any string that makes sense for your application
  'greet',

  // method handler - will be called when the method is invoked by a RemoteParticipant
  async (data: RpcInvocationData) => {
    console.log(`Received greeting from ${data.callerIdentity}: ${data.payload}`);
    return `Hello, ${data.callerIdentity}!`;
  },
);

In addition to the payload, your handler will also receive responseTimeout, which informs you the maximum time available to return a response. If you are unable to respond in time, the call will result in an error on the caller's side.

Performing an RPC request

The caller may then initiate an RPC call like so:

try {
  const response = await room.localParticipant!.performRpc({
    destinationIdentity: 'recipient-identity',
    method: 'greet',
    payload: 'Hello from RPC!',
  });
  console.log('RPC response:', response);
} catch (error) {
  console.error('RPC call failed:', error);
}

You may find it useful to adjust the responseTimeout parameter, which indicates the amount of time you will wait for a response. We recommend keeping this value as low as possible while still satisfying the constraints of your application.

Errors

LiveKit is a dynamic realtime environment and calls can fail for various reasons.

You may throw errors of the type RpcError with a string message in an RPC method handler and they will be received on the caller's side with the message intact. Other errors will not be transmitted and will instead arrive to the caller as 1500 ("Application Error"). Other built-in errors are detailed in RpcError.

Error Codes

Code Name Reason
1 ConnectionError 0: NotAllowed
1: ServerUnreachable
2: InternalError
3: Cancelled
4:LeaveRequest
10 UnsupportedServer
12 UnexpectedConnectionState
13 NegotiationError
14 PublishDataError
15 SignalRequestError
20 TrackInvalidError
21 DeviceUnsupportedError
40 CryptorError

Examples

Demo App

examples/demo contains a demo webapp that uses the SDK. Run it with pnpm install && pnpm examples:demo

RPC Demo

examples/rpc contains a demo webapp that uses the SDK to showcase the RPC capabilities. Run it with pnpm install && pnpm dev from the examples/rpc directory.

Browser Support

Browser Desktop OS Mobile OS
Chrome Windows, macOS, Linux Android
Firefox Windows, macOS, Linux Android
Safari macOS iOS
Edge (Chromium) Windows, macOS

We aim to support a broad range of browser versions by transpiling the library code with babel. You can have a look at the "browerslist" section of package.json for more details.

Note that the library requires some specific browser APIs to be present. You can check general compatibility with the helper function isBrowserSupported(). Support for more modern features like adaptiveStream and dynacast can be checked for with supportsAdaptiveStream() and supportsDynacast().

If you are targeting legacy browsers, but still want adaptiveStream functionality you'll likely need to use polyfills for ResizeObserver and IntersectionObserver.

Also when targeting legacy browsers, older than the ones specified in our browserslist target, make sure to transpile the library code to your desired target and include required polyfills with babel and/or corejs.


LiveKit Ecosystem
LiveKit SDKsBrowser · iOS/macOS/visionOS · Android · Flutter · React Native · Rust · Node.js · Python · Unity · Unity (WebGL)
Server APIsNode.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (community) · .NET (community)
UI ComponentsReact · Android Compose · SwiftUI
Agents FrameworksPython · Node.js · Playground
ServicesLiveKit server · Egress · Ingress · SIP
ResourcesDocs · Example apps · Cloud · Self-hosting · CLI

changelog

Change Log

2.11.3

Patch Changes

2.11.2

Patch Changes

  • fix: request audio/video in create local track helpers - #1485 (@lukasIO)

2.11.1

Patch Changes

2.11.0

Minor Changes

  • Defer publishing until signal is connected - #1465 (@lukasIO)

  • Address chrome ideal device handling change by defaulting to exact device matching - #1478 (@lukasIO)

Patch Changes

2.10.0

Minor Changes

Patch Changes

  • Improve error message for WS errors during connection attempt - #1466 (@lukasIO)

  • Closable spatial layers for svc encoding - #1458 (@cnderrauber)

  • Improve connection URL handling and add unit tests - #1468 (@lukasIO)

  • Pass facingMode to initial getUserMedia call in track restart - #1451 (@lukasIO)

2.9.9

Patch Changes

2.9.8

Patch Changes

  • Use string instead of passing url object to WebSocket constructor - #1443 (@davidliu)

2.9.7

Patch Changes

2.9.6

Patch Changes

  • Automatically attempt to resume suspended audio contexts on click - #1431 (@lukasIO)

  • Fix ignored constraints in LocalTrack.restart - #1435 (@rktguswjd)

  • log ice candidates as debug rather than trace - #1437 (@haydenbr)

  • fix: handle server url with params correctly - #1366 (@jiyeyuran)

2.9.5

Patch Changes

  • fix: properly remove text stream controllers on stream close - #1422 (@lukasIO)

  • Reject publishing with insufficient permissions present - #1418 (@lukasIO)

2.9.4

Patch Changes

  • Improve utf8 text split and add unit test - #1414 (@lukasIO)

  • Fix applying default processors from captureDefaults - #1416 (@lukasIO)

2.9.3

Patch Changes

2.9.2

Patch Changes

2.9.1

Patch Changes

  • Fix correct typing on async iterator stream readers - #1401 (@lukasIO)

2.9.0

Minor Changes

  • Add backupCodecPolicy to TrackPublishDefaults - #1399 (@cnderrauber)

    The default policy of backup codec is codec regression for maxium compatibility, which means the publisher stops sending primary codec and all subscribers will receive backup codec even primary codec is supported. It changes the default behavior multi-codec simulcast in the previous version, will not break the functionality of the previous version but only cause potential extra bandwidth usage. The user can set the policy to multi-codec simulcast to keep the previous behavior.

  • Add DataStream support - #1301 (@lukasIO)

  • Move RPC registration to room level and deprecate localParticipant level registration - #1396 (@lukasIO)

  • Populate name property of LiveKit errors and add reasonName for enums - #1385 (@lukasIO)

Patch Changes

2.8.1

Patch Changes

2.8.0

Minor Changes

Patch Changes

  • Ensure maxFps applies for very low framerates - #1362 (@lukasIO)

  • Emit MediaDeviceError only when acquiring tracks fails - #1365 (@lukasIO)

2.7.5

Patch Changes

  • fix(deps): update dependency @livekit/protocol to v1.29.4 - #1352 (@renovate)

2.7.4

Patch Changes

  • Support swapping out the E2EEManager for react-native - #1345 (@davidliu)

  • fix: prevent monitoring leak when stopOnUnpublish is false - #1348 (@davidzhao)

  • Prevent undefined access to engine in connection reconciler - #1349 (@lukasIO)

  • Fix sdp connection address mismatch - #1342 (@cnderrauber)

  • Set participant attributes as soon as possible, making them available in all related events - #1344 (@holzgeist)

2.7.3

Patch Changes

  • Only wait for publications that are pending already - #1339 (@lukasIO)

2.7.2

Patch Changes

  • Fix blocking main thread on parallel publishing requests - #1336 (@lukasIO)

2.7.1

Patch Changes

  • Fix processor passing in CreateLocalTracks options - #1329 (@lukasIO)

  • Await pending publications with timeout - #1324 (@lukasIO)

2.7.0

Minor Changes

  • Add support for detecting video element visibility in Document PiP (can be tested on the examples/demo) - #1325 (@davideberlein)

Patch Changes

  • Expose ReconnectContext and ReconnectPolicy, for use in custom reconnection implementations. - #1328 (@wuhkuh)

2.6.3

Patch Changes

  • Add voiceIsolation constraint to AudioCaptureOptions - #1320 (@lukasIO)

  • Forward disconnect reason on leave requests and ConnectionErrors - #1323 (@lukasIO)

2.6.2

Patch Changes

  • Use capturing mediastreamtrack settings for audio feature detection - #1318 (@lukasIO)

2.6.1

Patch Changes

  • Add ConnectionErrorReason when cancelling ongoing connection attempt - #1315 (@lukasIO)

  • Make Remote Tracks getSenderStats method public - #1309 (@mpnri)

2.6.0

Minor Changes

Patch Changes

2.5.10

Patch Changes

2.5.9

Patch Changes

2.5.8

Patch Changes

2.5.7

Patch Changes

  • Actually allow E2EE keyring size of 256 - #1268 (@hughns)

  • Expose server version info - #1267 (@lukasIO)

  • Only emit TrackStreamStateChanged events on changed stream state - #1199 (@lukasIO)

  • Fix duplicate ParticipantPermissionsChanged updates for the local participant - #1270 (@davidzhao)

2.5.6

Patch Changes

2.5.5

Patch Changes

2.5.4

Patch Changes

2.5.3

Patch Changes

  • Ensure republishing is finished when calling setTrackEnabled methods - #1250 (@lukasIO)

  • Add dedicated chat API - #1224 (@lukasIO)

  • Fix permissions for all devices being requested when connecting/disconnecting devices - #1249 (@lukasIO)

2.5.2

Patch Changes

  • Pass connect options to room from connection checkers - #1245 (@jespermjonsson)

  • Avoid parallel offer processing - #1244 (@lukasIO)

  • Switch active device if previously selected device becomes unavailable - #1237 (@lukasIO)

  • Treat MissingKey as decryption failure to prevent spamming the logs - #1241 (@hughns)

  • Update API docs for room.getLocalDevices - #1243 (@lukasIO)

  • Fix trackProcessor creation from LocalParticipant.createTracks - #1247 (@lukasIO)

2.5.1

Patch Changes

  • Use ReturnTypes of built-in functions for critical timers - #1236 (@lukasIO)

  • Set default scalabilityMode to L3T3_KEY in sample/comment - #1238 (@cnderrauber)

  • Expose localTrackSubscribed event on localParticipant and room - #1229 (@lukasIO)

  • fast track publication - #1228 (@cnderrauber)

  • Add firstReceivedTime and lastReceivedTime to received TranscriptionSegments - #1223 (@lukasIO)

  • Ensure SVC layers are starting from LOW quality - #1226 (@lukasIO)

2.5.0

Minor Changes

  • Add RemoteTrack.setPlayoutDelay and make receiver non-optional in RemoteTrack constructor - #1209 (@lukasIO)

Patch Changes

2.4.2

Patch Changes

  • Only retry other regions if connection attempt has not been cancelled - #1205 (@lukasIO)

2.4.1

Patch Changes

  • Set region settings when fetching them on first connection - #1201 (@lukasIO)

  • Handle SignalReconnecting event in ReconnectCheck helper - #1198 (@svajunas-budrys)

  • Fix RoomEvent.ParticipantAttributesChanged not emitting for local participant (#1200) - #1203 (@lukasIO)

2.4.0

Minor Changes

  • Make metadata updates async and throw after timeout - #1168 (@lukasIO)

  • Add support for participant attributes - #1184 (@lukasIO)

Patch Changes

  • Include participant identity in CryptoError errors - #1186 (@hughns)

  • Fix wording in CryptorError debug log - #1189 (@zesun96)

  • Only set loglevel for specified logger if present - #1196 (@lukasIO)

  • Ensure permission request for listDevices works for audio outputs in Firefox - #1188 (@lukasIO)

2.3.2

Patch Changes

  • Emit transcription on transcribedParticipantIdentity and update protocol - #1177 (@lukasIO)

  • Wait for pending publish promise before attempting to unpublish track - #1178 (@lukasIO)

  • Add vp9 support for E2EE - #836 (@lukasIO)

  • Ensure app visibility listeners are only added for video tracks - #1173 (@renovate)

  • Fix activeSpeakers has old participant when participant sid changed - #1180 (@zesun96)

2.3.1

Patch Changes

2.3.0

Minor Changes

  • Disable webAudioMix by default - #1159 (@lukasIO)

  • Add RoomEvent.SignalReconnecting and ConnectionState.SignalReconnecting - #1158 (@lukasIO)

Patch Changes

  • Fix normalising of default device Ids in DeviceManager - #1162 (@lukasIO)

  • Fix resumeUpstream with local track processors enabled - #1157 (@kyleparrott)

2.2.0

Minor Changes

  • Allow processors to be set as part of track publish options - #1143 (@lukasIO)

  • Support SIP DTMF data messages. - #1130 (@dennwc)

Patch Changes

  • Use legacy SVC encoding specification for React-Native - #1093 (@davidzhao)

  • Make sure setting a new processor doesn't remove the processor html element - #1149 (@lukasIO)

  • Add support for ParticipantKind - #1150 (@lukasIO)

  • Also set audioOutput on audioElements when using webAudioMix - #1145 (@lukasIO)

2.1.5

Patch Changes

2.1.4

Patch Changes

2.1.3

Patch Changes

2.1.2

Patch Changes

2.1.1

Patch Changes

  • Allow simulcast together with E2EE for supported Safari versions - #1117 (@lukasIO) Also fixes the simulcast behaviour for iOS Chrome prior to 17.2

  • Remove internal calls to setCodecPreferences on senders - #1114 (@lukasIO)

2.1.0

Minor Changes

  • Force playback after app visibility changes back to visible - #1106 (@lukasIO)

Patch Changes

2.0.10

Patch Changes

  • Create processorElement before processor init - #1091 (@xdef)

  • Improve VideoSenderStats with FPS and targetBitrate - #1090 (@davidzhao)

2.0.9

Patch Changes

  • Fix publishing for Chrome M124. Read capabilities from RtcRTPReceiver instead of from sender - #1088 (@lukasIO)

  • Add keyring size to keyprovider options - #1085 (@lukasIO)

2.0.8

Patch Changes

2.0.7

Patch Changes

  • Recreate engine before trying to connect to another region - #1071 (@lukasIO)

  • Add experimental preferCurrentTab screen share capture option - #1070 (@lukasIO)

  • Fix FPS and latency issues with VP9 screenshare - #1069 (@davidzhao)

2.0.6

Patch Changes

2.0.5

Patch Changes

  • Set logExtension on all livekit loggers if not specified - #1061 (@lukasIO)

  • Don't treat PC config error as SignalReconnectError - #1052 (@lukasIO)

  • Align logContext fields with server naming - #1062 (@lukasIO)

  • Remove some noisy e2ee logs - #1057 (@lukasIO)

  • Throw error if trying to connect with a non-compatible browser - #1064 (@davidliu)

2.0.4

Patch Changes

  • Normalize audiooutput device id for webAudio mode - #1051 (@lukasIO)

  • Add page leave log - #1056 (@lukasIO)

  • Add stopProcessor param to replaceTrack function - #1040 (@lukasIO)

  • Set audio context on track as early as possible - #1053 (@lukasIO)

  • Export logger names to configure fine grained logging - #1042 (@lukasIO)

  • Emit Restarting as soon as both signal and pc connection are severed - #1047 (@lukasIO)

  • Add VideoPreset overload for more granular options settings - #1044 (@lukasIO)

  • Send worker loglevel in init message - #1045 (@lukasIO)

  • Only perform mute/unmute actions if necessary - #1048 (@lukasIO)

  • Make sure a 401 ConnectionError is thrown on invalid token permissions - #1049 (@lukasIO)

2.0.3

Patch Changes

  • Fix transceiver reuse for e2ee and add more verbose e2ee debug logging - #1041 (@lukasIO)

  • Make sure only one track restart request is processed at a time - #1039 (@lukasIO)

  • Emit event when track processor changes - #1036 (@lukasIO)

2.0.2

Patch Changes

  • Ignore unknown fields in protobuf parsing - #1029 (@lukasIO)

  • Stronger kind type for Tracks to improve processor support - #1033 (@lukasIO)

  • Verify participant identity matching when unsetting transformer for e2ee - #1032 (@lukasIO)

2.0.1

Patch Changes

2.0.0

Major Changes

  • Remove experimental hint for webAudioMix and enable it by default - #1013 (@lukasIO)

  • Add support for async room sid. Removes room.sid and replaces it with await room.getSid(). - #983 (@lukasIO)

  • Change publishData signature - #946 (@lukasIO)

  • Remote OFF option from VideoQuality enum - #985 (@lukasIO)

  • Rename participant.tracks to participant.trackPublications - #947 (@lukasIO)

  • Rename getTrack to getTrackPublications and participants to remoteParticipants - #945 (@lukasIO)

  • Remove previously deprecated APIs - #948 (@lukasIO)

Minor Changes

  • Don't emit RoomEvent.Reconnecting for resumes - #1012 (@lukasIO)

Patch Changes

1.15.11

Patch Changes

1.15.10

Patch Changes

1.15.9

Patch Changes

1.15.8

Patch Changes

1.15.7

Patch Changes

  • Fix stopping old track in setMediaStreamTrack - #980 (@mpnri)

  • Add class level configurable logger - #988 (@lukasIO)

  • Default screenshare capture resolution to 1080p - #972 (@davidzhao)

1.15.6

Patch Changes

  • Make sure that processorElement stays muted after attach - #984 (@lukasIO)

1.15.5

Patch Changes

  • Add receiver video mime type to stats - #963 (@cnderrauber)

  • Make sure all signal client callbacks are set up for a reconnect - #966 (@lukasIO)

  • Make sure to apply audio output selection when participant is first created - #968 (@lukasIO)

1.15.4

Patch Changes

1.15.3

Patch Changes

  • Prevent backup codec publishing when e2ee is enabled - #943 (@lukasIO)

  • Use enum to track connection state of signal client - #949 (@lukasIO)

  • Disable VP9 for Safari 15, AV1 for Safari (incomplete support) - #950 (@davidzhao)

1.15.2

Patch Changes

  • Make sure no backup codecs are published when e2ee is enabled - #941 (@lukasIO)

1.15.1

Patch Changes

  • Move PeerConnection logic into PCTransportManager - #909 (@lukasIO)

  • Add startVideo method and RoomEvent.VideoPlaybackStatusChanged - #939 (@lukasIO)

1.15.0

Minor Changes

Patch Changes

1.14.4

Patch Changes

  • Correctly apply elementVolume on attach for webaudioMix - #922 (@lukasIO)

  • Simplify multi-codec simulcast usage, backupCodec: true - #923 (@davidzhao)

1.14.3

Patch Changes

  • Update dependency @bufbuild/protobuf to v1.4.1 - #913 (@renovate)

  • Demote duplicate source log to info - #917 (@lukasIO)

  • Fix reconnect when E2EE is enabled - #921 (@lukasIO)

  • Don't set the autoplay attribute on video elements in Safari - #918 (@lukasIO)

  • Call startAudio when an audio track has been acquired in order to update audio playback status - #919 (@lukasIO)

  • Round start bitrate for svc - #920 (@cnderrauber)

1.14.2

Patch Changes

  • Use a deepClone util function for CreateLocalTrackOptions - #906 (@vas11yev1work)

  • Guard against overriding newly set key when auto-ratcheting - #895 (@lukasIO)

  • Fix Safari reporting wrong initial track resolution - #898 (@lukasIO)

  • Make peerconnection private on PCTransport - #903 (@lukasIO)

  • Improve handling of incompatible published codecs - #911 (@davidzhao)

  • Fix a race in setKeyFromMaterial that would cause keys to be set at the wrong index if several keys were set in quick succession. - #908 (@dbkr)

  • Update protocol - #902 (@lukasIO)

  • Add key index to e2e worker log lines - #904 (@dbkr)

  • Fix Typescript compilation error in angular setups - #901 (@pabloFuente)

  • Don't disconnect room before retrying new regions - #910 (@lukasIO)

1.14.1

Patch Changes

1.14.0

Minor Changes

  • Do not constrain screenshare resolution by default - #889 (@davidzhao)

Patch Changes

1.13.4

Patch Changes

  • Log connection error message on region retries - #879 (@lukasIO)

  • Wait for publisher connection after reconnects - #875 (@lukasIO)

1.13.3

Patch Changes

1.13.2

Patch Changes

  • Fix opus RED publishing option not taking effect - #856 (@lukasIO)

1.13.1

Patch Changes

  • Remove legacy code paths for tracks arriving before participant info - #854 (@lukasIO)

  • Make KeyProvider and ParticipantKeyHandler work consistently for shared key and sender key scenarios (e2ee) - #850 (@lukasIO)

  • Fix track processor blips when restarting tracks - #842 (@lukasIO)

  • Correctly import livekit logger in facingMode helper - #855 (@lukasIO)

1.13.0

Minor Changes

  • Convert pauseUpstream and resumeUpstream to regular class methods - #830 (@lukasIO)

Patch Changes

  • Add websocketTimeout to RoomConnectOptions - #834 (@lukasIO)

  • Add support for get/setVolume in react-native - #833 (@davidliu)

  • Refine pause/resumeUpstream, setProcessor for multi-codecs - #829 (@cnderrauber)

  • Force enable dynacast when backupCodec is enabled - #839 (@cnderrauber)

  • Fix video device switch not working for backup codec - #824 (@cnderrauber)

  • Update dependency webrtc-adapter to v8.2.3 - #819 (@renovate)

  • Allow ArrayBuffers to be used for ExternalKeyProvider keys - #844 (@lukasIO)

  • Fix passing maxRetries connectOption to RTCEngine - #838 (@mpnri)

  • Add support for audio processors - #822 (@lukasIO)

  • Ability to simulate subscriber-bandwidth - #835 (@davidzhao)

  • Fix getDevices permissions when no kind is supplied - #811 (@Talljoe)

  • Fix setTrackMute ignored simulcast-codec - #827 (@cnderrauber)

  • Add support for server injected frame trailer being passed down - #812 (@lukasIO)

  • Add ceil of width and height when emitting UpdateTrackSettings - #846 (@HermanBilous)

  • Setup signal callbacks before connecting signal - #832 (@lukasIO)

  • Ensure play requests are invoked synchronously in startAudio - #841 (@lukasIO)

1.12.3

Patch Changes

  • Fix missing ScalabilityMode import when using SVC - #816 (@davidzhao)

  • Adjust default bitrates according to VMAF results - #817 (@davidzhao)

1.12.2

Patch Changes

  • Set a default resolution for createLocalScreenTracks - #796 (@lukasIO)

  • Debounce reacting to mediastreamtrack mute events - #809 (@lukasIO)

  • Remove duplicate options being passed to publish - #794 (@lukasIO)

  • Replace ts-proto with protobuf-es - #700 (@lukasIO)

  • Do not attempt to restart screen share tracks when re-publishing after reconnect - #802 (@lukasIO)

  • Add failureTolerance to KeyProvider options (E2EE) - #810 (@lukasIO)

  • Remove dummy audio element on disconnect - #793 (@lukasIO)

  • Add video options to ScreenShareCaptureOptions - #792 (@lukasIO)

  • Fix iOS browser parser check, add more test cases - #798 (@lukasIO)

  • Improved connection checker with more details about ICE candidates - #806 (@davidzhao)

  • Throw connection error immediately if unauthorized instead of trying alternative URLs - #804 (@lukasIO)

  • Revert event emitter lib usage to 'events' - #807 (@lukasIO)

  • Support for region pinning with LiveKit Cloud using prepareConnection - #783 (@davidzhao)

  • Ensure we do not replace http unless it's in the scheme - #805 (@davidzhao)

  • Stop tracks if publishing fails with setTrackEnabled - #799 (@lukasIO)

1.12.1

Patch Changes

  • Allow specifying audio source for participant.setVolume API - #780 (@lukasIO)

  • Add iOS detection to browser parser and only use audio element workar… - #785 (@lukasIO)

  • Skip decryption if maximum ratchet accounts have exceeded until a new key is set - #786 (@lukasIO)

  • Set element Id for dummy audio element - #778 (@lukasIO)

  • Update constraints with actually selected deviceId on track creation - #773 (@toger5)

  • Always resume AudioContext if in suspended state - #779 (@lukasIO)

  • Only check for setSinkId support on AudioContext if webaudiomix is enabled - #787 (@lukasIO)

1.12.0

Minor Changes

  • Experimental end-to-end encryption support - #557 (@lukasIO)

Patch Changes

  • Update adaptive stream dimensions when a remote track is being detached - #766 (@burzomir)

  • Fixed missed event listeners on MediaStreamTrack - #768 (@davidzhao)

  • Forward signal events through engine - #772 (@lukasIO)

  • Emit activeDeviceChanged when publishing local track - #759 (@lukasIO)

  • Fix peer connections leak - #767 (@lukasIO)

1.11.4

Patch Changes

  • Use mutex lock for queueing calls to setProcessor - #756 (@lukasIO)

  • Use active device when publishing a new track - #757 (@lukasIO)

  • expose facingMode functions - #753 (@Ocupe)

1.11.3

Patch Changes

  • Apply user setting bitrate to maxaveragebitrates for firefox - #752 (@cnderrauber)

  • Do not override forceStereo=false when publishing stereo input - #748 (@davidzhao)

  • Add helper function to detect camera facingMode. - #738 (@Ocupe)

  • Only set priority on Firefox - #750 (@lukasIO)

1.11.2

Patch Changes

  • Fix missing await for async setMediaStreamTrack calls - #747 (@boris-graeff)

  • Emit RoomEvent.ActiveDeviceChanged when room.switchActiveDevice has been called. - #743 (@lukasIO) Add room.getActiveDevice(kind) method.

  • Use JSdocs instead of warning for mediastreamtrack access - #742 (@lukasIO)

1.11.1

Patch Changes

1.11.0

Minor Changes

  • Increase default adaptiveStream pixelDensity on high-density(mobile) screens - #735 (@davidzhao)

  • Replace event emitter lib with eventemitter3 - #681 (@lukasIO)

Patch Changes

  • Handle device mute and document freeze events - #734 (@davidzhao)

  • Pass method logLevel to LogExtension instead of configured logLevel - #730 (@lukasIO)

  • Fix svc encodings for safari and chrome before 113 - #731 (@cnderrauber)

  • Always catch reconnectFuture rejections - #727 (@HermanBilous)

  • Work around iOS safari audio playback issue when not publishing, by playing back silent audio - #733 (@lukasIO)

1.10.0

Minor Changes

Patch Changes

  • Use replaceTrack(null) for pauseUpstream - #716 (@davidzhao)

  • Always add codec info to AddTrackRequest - #728 (@cnderrauber)

  • Surface subscription error via TrackEvent.SubscriptionFailed when trying to subsribe to an unsupported codec - #722 (@lukasIO)

  • Reject signal connection promise immediately when aborted - #719 (@lukasIO)

  • Fix svc mode for chrome v113 - #720 (@cnderrauber)

1.9.7

Patch Changes

1.9.6

Patch Changes

  • Make sure TrackUnsubscribed events are emitted before the publication gets deleted from maps - #708 (@lukasIO)

  • Use body instead of document as intersection observer root - #703 (@lukasIO)

  • Use default video dimensions when they are not available - #709 (@davidzhao)

1.9.5

Patch Changes

  • Remove ua-parser-js dependency and fix browser version comparison - #697 (@lukasIO)

  • Use STATE_MISMATCH disconnect reason in connection reconciliation - #705 (@lukasIO)

  • Make sure engine gets closed when connection reconciliation triggers - #702 (@lukasIO)

1.9.4

Patch Changes

1.9.3

Patch Changes

1.9.2

Patch Changes

  • Ensure engine is always set to undefined when closing - #682 (@lukasIO)

  • Handle connection state mismatch with periodic reconciliation - #680 (@davidzhao)

1.9.1

Patch Changes

  • Only set maxFramerate on encoding if defined - #676 (@lukasIO)

  • added experimental option suppressLocalAudioPlayback - #675 (@jibon57)

  • Fix: Emit connected events for participants that connected during signal reconnect - #672 (@lukasIO)

  • Add VP9 SVC support - #643 (@cnderrauber)

1.9.0

Minor Changes

  • Fix race condition with full reconnect sequence during server restart - #663 (@davidzhao)

Patch Changes

  • Add support for local participants to update own metadata - #599 (@lukasIO)

  • Expose numParticipants and numPublishers on Room - #668 (@davidzhao)

  • Handle signal reconnect and full reconnection separately #665 - #670 (@lukasIO)

1.8.0

Minor Changes

Patch Changes

1.7.1

Patch Changes

  • #625 b74da67 Thanks @wjaykim! - Emit mute status events also for unsubscribed publications

  • #622 2268333 Thanks @lukasIO! - Don't auto-pause videos when element is in pictureInPicture mode (only applies when adaptiveStream is enabled)

  • #627 0342650 Thanks @lukasIO! - Add room option to configure automatic disconnect on page leave

  • #628 4ed8b89 Thanks @lukasIO! - Respect incoming data message order by processing message events sequentially

  • #623 d8e7a20 Thanks @lukasIO! - Emit RoomEvent.LocalAudioSilenceDetected if a LocalAudioTrack is silent after publishing

1.7.0

Minor Changes

1.6.9

Patch Changes

1.6.8

Patch Changes

1.6.7

Patch Changes

1.6.6

Patch Changes

1.6.5

Patch Changes

1.6.4

Patch Changes

1.6.3

Patch Changes

1.6.2

Patch Changes

1.6.1

Patch Changes

1.6.0

Minor Changes

Patch Changes

1.5.0

Minor Changes

  • #487 e1a0a7e Thanks @lukasIO! - Sync muted state with track.enabled when calling replaceTrack"

  • #485 1cc2cab Thanks @lukasIO! - Don't filter out default devices in order to detect OS Level default switches

Patch Changes

1.4.4

Patch Changes

1.4.3

Patch Changes

1.4.2

Patch Changes

1.4.1

Patch Changes

1.4.0

Minor Changes

  • #443 438d067 Thanks @lukasIO! - Breaking Decouple SubscriptionStatus and SubscriptionPermissionStatus

Patch Changes

1.3.3

Patch Changes

1.3.2

Patch Changes

1.3.1

Patch Changes

1.3.0

Minor Changes

Patch Changes

1.2.11

Patch Changes

1.2.10

Patch Changes

1.2.9

Patch Changes

1.2.8

Patch Changes

  • #371 e1a004e Thanks @lukasIO! - only set volume on attach if elementVolume has been previously set

1.2.7

Patch Changes

  • #369 a3d6de6 Thanks @lukasIO! - Fix reconnect promise not being reset after reconnect attempts are exhausted

1.2.6

Patch Changes

1.2.5

Patch Changes

  • #359 31e3883 Thanks @lukasIO! - Only reject connection promise if it was triggered by a call to connect()

  • #358 8ceceff Thanks @lukasIO! - Add safari explicitly to browserslist, to ensure compatibility with Safari 11"

  • #363 4665f74 Thanks @lukasIO! - Decrease publication timeout to 10s and clean local state on failed unpublish attempts

  • #311 61a41e0 Thanks @lukasIO! - Avoid multiple calls to getUserMedia for getLocalDevices

  • #332 b3df000 Thanks @lukasIO! - Clean up simulcast codecs in unpublishTrack

1.2.4

Patch Changes

  • #330 dbbfe5f Thanks @lukasIO! - Check for duplicate source publications before adding them to tracks

1.2.3

Patch Changes

1.2.2

Patch Changes

1.2.1

Patch Changes

1.2.0

Minor Changes

  • #308 5b1c5a0 Thanks @lukasIO! - Try to re-aquire mediastreamtrack when device has been disconnected, pause upstream if no device could be acquired

  • #310 40a51f5 Thanks @lukasIO! - Deprecate publishOnly connect option

Patch Changes

1.1.9

Patch Changes

1.1.8

Patch Changes

1.1.7

Patch Changes

1.1.6

Patch Changes

1.1.5

Patch Changes

1.1.4

Patch Changes

1.1.3

Patch Changes

1.1.2

Patch Changes

1.1.1

Patch Changes

1.1.0

Minor Changes

Patch Changes

1.0.4

Patch Changes

  • 3e5e3b8: Fix dynacast fallback when simulcast codec is not available
  • 4a51ae0: Fix getParticipantIdentity returning undefined in some cases

1.0.3

Patch Changes

  • 9487a4d: Fix typescript declaration location

1.0.2

Patch Changes

  • 4effe17: Moving StreamState to Track to improve usability
  • 3bca206: Fix: guard against (multiple) simultaneous reconnect attempts

0.12.0

  • Updated API to create screen share tracks.