/* Copyright 2026 Element Creations Ltd. SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ /** * The public media types of the SDK: what a member publishes, the tracks it * arrives as and how a host renders them. The client and member types are in * `api.ts`. */ import { type Observable } from "rxjs"; import { type Behavior } from "./reactive/Behavior"; export interface AudioCaptureSettings { echoCancellation?: boolean; noiseSuppression?: boolean; autoGainControl?: boolean; } export type VideoCodec = "vp8" | "h264" | "vp9" | "av1" | "h265"; export interface VideoCaptureSettings { resolution?: { width: number; height: number; frameRate?: number }; maxBitrate?: number; maxFramerate?: number; codec?: VideoCodec; } /** * Transforms a camera track before it is published: background blur and the * like. `init` resolves with the track to publish in place of the captured * one; `restart` does the same for a new capture, where the camera changes. */ export interface VideoProcessor { name: string; init( track: MediaStreamTrack, element?: HTMLMediaElement, ): Promise; restart( track: MediaStreamTrack, element?: HTMLMediaElement, ): Promise; destroy(): Promise; } /** * One thing to publish: a source, where to capture it from and how to encode * it. Where the device and the settings are left out, the browser's and * LiveKit's defaults apply. */ export type PublishRequest = | { source: "microphone"; deviceId?: string; capture?: AudioCaptureSettings } | { source: "camera"; deviceId?: string; /** Background blur and the like, applied before the first frame is published. */ processor?: VideoProcessor; capture?: VideoCaptureSettings; } | { source: "screenShare"; /** Whether to capture the screen's audio too. Default true. */ audio?: boolean; capture?: VideoCaptureSettings; }; export type MediaSource = | "microphone" | "camera" | "screenShare" | "screenShareAudio" /** Published without a source; the application knows what it is. */ | "unknown"; export type MediaStreamStats = | RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats | undefined; /** One published track of a member. */ export interface MediaTrack { source: MediaSource; kind: "audio" | "video"; /** Stable for the life of the track. */ id: string; muted$: Behavior; /** * False when the SFU reports the track as unencrypted. Fixed for the life * of the track: a publisher that changes its encryption publishes anew. */ encrypted: boolean; /** * Inbound statistics for a remote track, outbound for a local one, polled * every `intervalMs` while the observable is subscribed and not at all * otherwise. Each subscription runs its own poll, so a view shares one. */ stats$(intervalMs: number): Observable; /** * Rendering. The view hands its `