Publishing tracks

Camera and microphone

It's simple to publish the local participant's camera and/or microphone streams to the room. We provide a consistent way to do this across platforms:

// Turns camera track on
// Turns microphone track on

and to mute them, you can perform:


Disabling camera or microphone will turn off their respective recording indicators. Other participants will receive a TrackMuted event.

Screen sharing

LiveKit also supports screen share natively across all platforms.

// this will trigger browser prompt to share screen
await currentRoom.localParticipant.setScreenShareEnabled(true);

Publishing from backend

You can also publish media from your backend. The following SDKs & tools will enable you to publish from server environments:

Advanced track management

setCameraEnabled, setMicrophoneEnabled, and setScreenShareEnabled are convenience wrappers around our Track APIs, you could create tracks manually and publish or unpublish them at any time. There are no limits to the number of tracks a participant could publish.

LiveKit uses sane defaults for the tracks it publishes, but exposes knobs for you to fine tune for your application. These settings are organized into two categories:

  • Capture settings: how media is captured, including device selection and capabilities.
  • Publish settings: how it's encoded, including bitrate and framerate.
// option 1, set room defaults
const room = new Room({
audioCaptureDefaults: {
autoGainControl: true,
deviceId: '',
echoCancellation: true,
noiseSuppression: true,
videoCaptureDefaults: {
deviceId: '',
facingMode: 'user',
resolution: {
width: 1280,
height: 720,
frameRate: 30,
publishDefaults: {
videoEncoding: {
maxBitrate: 1_500_000,
maxFramerate: 30,
screenShareEncoding: {
maxBitrate: 1_500_000,
maxFramerate: 30,
audioBitrate: 20_000,
dtx: true,
// only needed if overriding defaults
videoSimulcastLayers: [
width: 640,
height: 360,
encoding: {
maxBitrate: 500_000,
maxFramerate: 20,
width: 320,
height: 180,
encoding: {
maxBitrate: 150_000,
maxFramerate: 15,
// option 2, settings for individual tracks
async function publishTracks() {
const videoTrack = await createLocalVideoTrack({
facingMode: "user",
// preset resolutions
resolution: VideoPresets.h720
const audioTrack = await createLocalAudioTrack({
echoCancellation: true,
noiseSuppression: true,
const videoPublication = await room.localParticipant.publishTrack(videoTrack)
const audioPublication = await room.localParticipant.publishTrack(audioTrack)

See options.ts for details.

Mute and unmute

You can mute any track to stop it from sending data to the server. When a track is muted, LiveKit will trigger a TrackMuted event on all participants in the room. You can use this event to update your app's UI and reflect the correct state to all users in the room.

Mute/unmute a track using its corresponding LocalTrackPublication object.

Video simulcast

Simulcast enables a client to publish multiple versions of the same video track, each with a different bitrate profile. This feature allows LiveKit to dynamically forward the most suitable stream based on each recipient's available bandwidth and preferred resolution.

Automatic adaptive layer selection occurs within the Selective Forwarding Unit (SFU) when the server identifies a participant with bandwidth constraints. As the participant's bandwidth improves, the server would upgrade the subscribed streams to higher resolutions accordingly.

For more information about Simulcast, see an introduction to WebRTC simulcast.

Simulcast is supported in all of LiveKit's client SDKs. It's enabled by default, and can be disabled in publish settings.

Dynamic broadcasting

LiveKit is designed with end-to-end optimizations to minimize bandwidth consumption. Dynamic Broadcasting (Dynacast), automatically pauses the publication of video layers when they are not consumed by subscribers. This functionality extends to simulcasted video as well: if subscribers only consume medium and low-resolution layers, the high-resolution publication will be paused.

To activate this feature, set dynacast: true in the Room options.

When using SVC codecs (VP9 or AV1), Dynacast can only pause the entire stream, not individual layers. This limitation is due to the encoding characteristics of SVC codecs.


Subscription permissions

By default, any track published to a Room can be subscribed to by all participants.

In certain situations, a publisher may want to limit who can subscribe to the tracks they are publishing. For instance, when two individuals wish to engage in a private conversation within a larger meeting.

For those use cases, Track Subscription Permissions provide the means for publishers to specify who is allowed to subscribe to their tracks.

localParticipant.setTrackSubscriptionPermissions(false, [
participantIdentity: "allowed-identity",
allowAll: true,