/**
 * Minimal logger interface compatible with `console`, `pino`, `winston`, and
 * most structured logging libraries.
 *
 * Pass `logger: console` during development to see all internal events.
 */
interface Logger {
    debug(message: string, ...args: unknown[]): void;
    info(message: string, ...args: unknown[]): void;
    warn(message: string, ...args: unknown[]): void;
    error(message: string, ...args: unknown[]): void;
}
/**
 * Configuration for the automatic reconnect behaviour.
 *
 * Pass `autoReconnect: true` to use all defaults, or provide an object to
 * fine-tune the retry policy.
 */
interface AutoReconnectOptions {
    /**
     * Maximum number of reconnection attempts before emitting a final
     * `'failed'` event. Defaults to `5`.
     */
    maxAttempts?: number;
    /**
     * Delay before the **second** attempt (the first retry is immediate).
     * Subsequent delays grow according to `backoff`. Defaults to `1_000` ms.
     */
    initialDelayMs?: number;
    /**
     * Upper bound on the inter-attempt delay. Defaults to `30_000` ms.
     */
    maxDelayMs?: number;
    /**
     * Delay growth strategy.
     * - `'exponential'` – delay doubles on each attempt (default).
     * - `'fixed'` – delay stays at `initialDelayMs`.
     */
    backoff?: 'fixed' | 'exponential';
}
/**
 * Configuration for automatic encoding quality adaptation based on
 * connection statistics.
 *
 * Pass `adaptiveQuality: true` to `WHIPClientOptions` to use all defaults,
 * or provide an object to fine-tune the adaptation policy.
 *
 * When enabled, `WHIPClient` polls `getStats()` on an interval and scales
 * the video sender's `maxBitrate` according to the measured
 * `ConnectionQuality`. Bitrate is restored gradually when quality improves.
 */
interface AdaptiveQualityOptions {
    /**
     * How often to sample connection stats in milliseconds.
     * Defaults to `5000` (5 seconds).
     */
    intervalMs?: number;
    /**
     * Number of consecutive degraded quality readings required before
     * reducing the video bitrate. Defaults to `2`.
     */
    downgradeThreshold?: number;
    /**
     * Number of consecutive improved quality readings required before
     * increasing the video bitrate back toward the target. Defaults to `4`.
     */
    upgradeThreshold?: number;
    /**
     * Minimum video bitrate floor in **bits per second**. The encoder will
     * not be throttled below this value. Defaults to `150_000` (150 kbps).
     */
    minVideoBitrate?: number;
}
/** Overall connection quality derived from packet-loss rate and RTT. */
type ConnectionQuality = 'excellent' | 'good' | 'fair' | 'poor';
/** Audio-track statistics snapshot. */
interface AudioStats {
    /** Current encoding / decoding bitrate in **bits per second**. */
    bitrate: number;
    /** Total packets lost since the session started. */
    packetsLost: number;
    /** Fraction of packets lost (0–1). */
    packetsLostRate: number;
    /** Jitter in **seconds** (from RTCP). */
    jitter: number;
}
/** Video-track statistics snapshot. */
interface VideoStats {
    /** Current encoding / decoding bitrate in **bits per second**. */
    bitrate: number;
    /** Total packets lost since the session started. */
    packetsLost: number;
    /** Fraction of packets lost (0–1). */
    packetsLostRate: number;
    /** Current frames per second. */
    frameRate: number;
    /** Frame width in pixels. */
    width: number;
    /** Frame height in pixels. */
    height: number;
}
/**
 * A rolling window of past `StreamStats` snapshots passed as the second
 * argument to the `watchStats` callback.
 *
 * The window holds up to `historySize` entries (default `10`). Each new
 * snapshot is appended; once the cap is reached the oldest entry is evicted.
 */
interface StatsHistory {
    /**
     * All snapshots collected so far, in chronological order (oldest first,
     * newest last). Contains at most `historySize` entries.
     */
    readonly snapshots: ReadonlyArray<StreamStats>;
    /**
     * The snapshot from the previous polling interval, or `null` on the very
     * first callback invocation. Equivalent to `snapshots.at(-2)`.
     */
    readonly prev: StreamStats | null;
    /**
     * Mean video bitrate across all snapshots in the window, in **bits per
     * second**. Returns `null` when no snapshot contains video stats.
     */
    avgVideoBitrate(): number | null;
    /**
     * Mean audio bitrate across all snapshots in the window, in **bits per
     * second**. Returns `null` when no snapshot contains audio stats.
     */
    avgAudioBitrate(): number | null;
    /**
     * Mean packet-loss rate (0–1) across all audio and video tracks in the
     * window. Returns `null` when no stats are available yet.
     */
    avgPacketLossRate(): number | null;
    /**
     * Mean round-trip time in **seconds** across all snapshots in the window.
     * Returns `null` when no RTT measurements are available yet.
     */
    avgRoundTripTime(): number | null;
}
/**
 * Normalised snapshot of `RTCPeerConnection.getStats()` returned by
 * `WHIPClient.getStats()` and `WHEPClient.getStats()`.
 */
interface StreamStats {
    /** Timestamp when the snapshot was collected (ms since epoch). */
    timestamp: number;
    /** Audio statistics, or `null` when no audio track is active. */
    audio: AudioStats | null;
    /** Video statistics, or `null` when no video track is active. */
    video: VideoStats | null;
    /**
     * Round-trip time in **seconds**.
     *
     * - For `WHIPClient` (sender): derived from RTCP SR/RR reports via
     *   `remote-inbound-rtp` stats. `null` until the first RTCP measurement.
     * - For `WHEPClient` (receiver): derived from ICE candidate-pair stats
     *   (`nominated` pair preferred). `null` until the ICE connection is
     *   fully established.
     */
    roundTripTime: number | null;
    /** Overall connection quality derived from packet loss and RTT. */
    quality: ConnectionQuality;
}
/**
 * Configuration options shared by both WHIP and WHEP clients.
 */
interface BaseClientOptions {
    /**
     * The WHIP or WHEP endpoint URL.
     */
    endpoint: string;
    /**
     * Optional Bearer token sent as `Authorization: Bearer <token>`.
     *
     * For custom authorization schemes (e.g. `Token`, `Basic`, `Digest`) use
     * `headers` or `getHeaders` instead and omit this field.
     */
    token?: string;
    /**
     * Static custom headers appended to every HTTP request (POST, PATCH,
     * DELETE). Merged after built-in headers, so keys like `Authorization`
     * and `Content-Type` can be overridden here.
     *
     * @example
     * ```ts
     * headers: {
     *   'X-API-Key': 'my-key',
     *   'Authorization': 'Token abc123',   // overrides the token option
     * }
     * ```
     */
    headers?: Record<string, string>;
    /**
     * A function called before **each** HTTP request to supply dynamic
     * headers. The returned headers are merged on top of `headers`.
     *
     * Use this when the header value must be freshly computed per request,
     * for example:
     * - Refreshable access tokens
     * - HMAC / timestamp-based request signatures
     * - Session cookies obtained asynchronously
     *
     * @example
     * ```ts
     * getHeaders: async () => ({
     *   'Authorization': `Bearer ${await tokenStore.getValidToken()}`,
     * })
     * ```
     */
    getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
    /**
     * Custom ICE servers (STUN/TURN). Overrides browser defaults when provided.
     */
    iceServers?: RTCIceServer[];
    /**
     * ICE transport policy. Defaults to `'all'`.
     * Set to `'relay'` to force TURN relay usage only.
     */
    iceTransportPolicy?: RTCIceTransportPolicy;
    /**
     * Number of ICE candidates to pre-gather before the offer is sent.
     * Increasing this value improves connection time at the cost of higher
     * initial memory usage. Defaults to `0`.
     */
    iceCandidatePoolSize?: number;
    /**
     * Maximum time in milliseconds to wait for the SDP exchange to complete.
     * Defaults to `15000` (15 seconds).
     */
    timeout?: number;
    /**
     * Additional `RTCConfiguration` fields merged with library defaults.
     * `iceServers`, `iceTransportPolicy`, and `iceCandidatePoolSize` from
     * this object are ignored in favour of the dedicated top-level options.
     */
    peerConnectionConfig?: Omit<RTCConfiguration, 'iceServers' | 'iceTransportPolicy' | 'iceCandidatePoolSize'>;
    /**
     * Maximum time in milliseconds to wait for the ICE connection to reach
     * the `'connected'` state after `setRemoteDescription`.
     *
     * When omitted (default) no ICE-specific timeout is applied; only the
     * SDP-exchange `timeout` is enforced. When set, a `TimeoutError` is
     * thrown if ICE does not connect within the given window.
     */
    iceConnectionTimeout?: number;
    /**
     * Enable automatic reconnection when the underlying `RTCPeerConnection`
     * transitions to the `'failed'` state after a previously successful
     * connection.
     *
     * - `true` – use default retry policy (5 attempts, exponential back-off).
     * - `AutoReconnectOptions` – customise attempt count, delays, and strategy.
     *
     * Auto-reconnect does **not** trigger for errors that occur during the
     * initial signalling (e.g. a 401 from the server).
     */
    autoReconnect?: boolean | AutoReconnectOptions;
    /**
     * Optional logger for internal debug output.
     *
     * Any object with `debug`, `info`, `warn`, and `error` methods is
     * accepted, including the global `console`.
     *
     * @example
     * ```ts
     * const client = new WHIPClient({ endpoint: '...', logger: console });
     * ```
     */
    logger?: Logger;
}
/**
 * Advanced Opus codec parameters.
 *
 * These map to well-known `a=fmtp` parameters defined in RFC 7587.
 */
interface AudioEncodingOptions {
    /**
     * Maximum audio encoding bitrate in **bits per second**.
     * Applied via `RTCRtpSender.setParameters()` after negotiation.
     *
     * @example 128_000  // 128 kbps
     */
    maxBitrate?: number;
    /**
     * Enable Discontinuous Transmission (DTX) for Opus.
     * Reduces bitrate during silence by ~1 kbps. Defaults to `false`.
     */
    dtx?: boolean;
    /**
     * Force stereo audio. Defaults to `false` (mono).
     */
    stereo?: boolean;
    /**
     * Enable in-band Forward Error Correction (FEC) for Opus.
     * Improves packet-loss resilience. Defaults to `true`.
     */
    fec?: boolean;
    /**
     * Enable comfort noise generation. Defaults to `false`.
     */
    comfortNoise?: boolean;
    /**
     * Hint to the browser about the nature of the audio content.
     * Browsers may use this to choose encoder settings.
     *
     * - `'speech'` – optimize for voice (default in most browsers)
     * - `'speech-recognition'` – optimize for speech recognition
     * - `'music'` – optimize for music / wide-band audio
     * - `''` – no hint (browser decides)
     */
    contentHint?: 'speech' | 'speech-recognition' | 'music' | '';
}
/**
 * Advanced video encoding parameters for a single quality layer.
 *
 * Extends the standard `RTCRtpEncodingParameters` with convenience aliases.
 */
interface VideoLayerOptions {
    /**
     * RID label for simulcast layers (e.g. `'high'`, `'mid'`, `'low'`).
     * Required when simulcast is enabled.
     */
    rid?: string;
    /**
     * Maximum video encoding bitrate in **bits per second**.
     *
     * @example 2_500_000  // 2.5 Mbps
     */
    maxBitrate?: number;
    /**
     * Maximum frames per second for this layer.
     */
    maxFramerate?: number;
    /**
     * Downscale factor relative to the source resolution.
     * `1` = full resolution, `2` = half resolution, `4` = quarter resolution.
     * Defaults to `1`.
     */
    scaleResolutionDownBy?: number;
    /**
     * Whether this layer is active. Defaults to `true`.
     */
    active?: boolean;
    /**
     * How to degrade quality when bandwidth is constrained.
     * Defaults to `'balanced'`.
     */
    degradationPreference?: RTCDegradationPreference;
    /**
     * Hint to the encoder about the content type.
     * `'motion'` optimises for fast movement (sports, games).
     * `'detail'` optimises for sharpness (screen share, slides).
     */
    contentHint?: 'motion' | 'detail' | 'text' | '';
}
/**
 * Options specific to the WHIP (ingestion / publishing) client.
 */
interface WHIPClientOptions extends BaseClientOptions {
    /**
     * Enable simulcast for the video track with three quality layers:
     * `high`, `mid`, and `low`. Defaults to `false`.
     *
     * Use `videoLayers` to override the default layer configuration.
     */
    simulcast?: boolean;
    /**
     * Preferred audio codec name (e.g. `'opus'`).
     * Reorders the SDP payload type list so the preferred codec is offered first.
     */
    audioCodec?: string;
    /**
     * Preferred video codec name (e.g. `'h264'`, `'vp8'`, `'vp9'`, `'av1'`).
     * Reorders the SDP payload type list so the preferred codec is offered first.
     */
    videoCodec?: string;
    /**
     * Advanced audio encoding options (bitrate, DTX, stereo, FEC…).
     */
    audio?: AudioEncodingOptions;
    /**
     * Advanced video layer options.
     *
     * - When `simulcast` is **false**, provide a single `VideoLayerOptions`
     *   object to configure the single encoding layer.
     * - When `simulcast` is **true**, provide an array of up to three
     *   `VideoLayerOptions` objects (ordered high → low quality) to override
     *   the built-in simulcast defaults.
     */
    video?: VideoLayerOptions | VideoLayerOptions[];
    /**
     * Maximum total **session** bandwidth in **kilobits per second**.
     * Written as `b=AS:<maxKbps>` in the SDP offer.
     *
     * This is a hint to the server; actual enforcement depends on the server
     * implementation. For per-layer bitrate limits prefer `video.maxBitrate`.
     *
     * @example 4_000  // 4 Mbps
     */
    maxBandwidth?: number;
    /**
     * Attempt to recover the existing WHIP session via an HTTP PATCH when
     * the `RTCPeerConnection` fails, before falling back to a full
     * DELETE + POST reconnect.
     *
     * Per RFC 9725 §4.3, the client sends a new SDP offer to the resource
     * URL with an `If-Match` header containing the session `ETag`. If the
     * server still holds the session it responds with `200 OK` and a new SDP
     * answer; otherwise the library falls back to a full reconnect
     * automatically.
     *
     * Defaults to `false`.
     */
    endpointRecovery?: boolean;
    /**
     * Automatically adapt the video encoding bitrate based on measured
     * connection quality.
     *
     * - `true` – use default adaptation policy.
     * - `AdaptiveQualityOptions` – customise polling interval, thresholds,
     *   and minimum bitrate.
     *
     * When quality degrades, the video `maxBitrate` is scaled down
     * (`poor` → 25 %, `fair` → 50 %, `good` → 75 % of target).
     * It is restored gradually once quality improves. Emits a
     * `'qualitychange'` event on each level transition.
     *
     * Defaults to `false`.
     */
    adaptiveQuality?: boolean | AdaptiveQualityOptions;
}
/**
 * Options specific to the WHEP (egress / viewing) client.
 */
interface WHEPClientOptions extends BaseClientOptions {
    /**
     * Preferred audio codec name for the inbound stream (e.g. `'opus'`).
     */
    audioCodec?: string;
    /**
     * Preferred video codec name for the inbound stream (e.g. `'h264'`, `'vp8'`).
     */
    videoCodec?: string;
    /**
     * Maximum receive bandwidth per media section in **kilobits per second**.
     * Written as `b=AS:<maxKbps>` in the SDP offer to hint the server to
     * limit the outgoing bitrate to this value.
     */
    maxBandwidth?: number;
}
/**
 * Per-track publish options passed to `WHIPClient.publish()`.
 */
interface PublishOptions {
    /**
     * Set to `false` to skip publishing the audio track even if the stream
     * contains one. Defaults to `true`.
     */
    audio?: boolean;
    /**
     * Set to `false` to skip publishing the video track even if the stream
     * contains one. Defaults to `true`.
     */
    video?: boolean;
    /**
     * Override simulcast for this specific `publish()` call.
     * Takes precedence over the constructor-level `simulcast` option.
     */
    simulcast?: boolean;
    /**
     * An `AbortSignal` that cancels the publish operation when signalled.
     *
     * When the signal fires mid-publish, the in-flight HTTP request is aborted,
     * the peer connection is closed, and a `DOMException` with name
     * `'AbortError'` is thrown. Any partial server resource is cleaned up
     * automatically.
     *
     * @example
     * ```ts
     * const ac = new AbortController();
     * setTimeout(() => ac.abort(), 5_000);
     * await client.publish(stream, { signal: ac.signal });
     * ```
     */
    signal?: AbortSignal;
}
/**
 * Options for `WHIPClient.publishScreen()`.
 *
 * Controls which media sources are captured and combined into the published
 * stream.
 */
interface PublishScreenOptions {
    /**
     * Request system / browser-tab audio from `getDisplayMedia`.
     *
     * Browser support varies: Chrome supports tab and system audio; Safari and
     * Firefox generally do not. Ignored when `micAudio` is also set (the
     * microphone track takes precedence as the published audio source).
     * Defaults to `false`.
     */
    displayAudio?: boolean;
    /**
     * Capture microphone audio via `getUserMedia` and use it as the published
     * audio track instead of display audio.
     *
     * Pass `true` to use browser defaults, or provide `MediaTrackConstraints`
     * to fine-tune (e.g. `{ echoCancellation: true }`).
     * Defaults to `false`.
     */
    micAudio?: boolean | MediaTrackConstraints;
    /**
     * Video constraints merged on top of the `getDisplayMedia` defaults
     * (`{ width: 1920, height: 1080, frameRate: 30 }`).
     */
    videoConstraints?: MediaTrackConstraints;
    /**
     * Per-call publish overrides forwarded to the underlying `publish()` call
     * (e.g. `simulcast`, `signal`). The `audio` and `video` flags are set
     * automatically based on what was captured and cannot be overridden here.
     */
    publishOptions?: Omit<PublishOptions, 'audio' | 'video'>;
}
/**
 * Options passed to `WHEPClient.view()`.
 */
interface ViewOptions {
    /**
     * Set to `false` to skip adding an audio receive transceiver.
     * Defaults to `true`.
     */
    audio?: boolean;
    /**
     * Set to `false` to skip adding a video receive transceiver.
     * Defaults to `true`.
     */
    video?: boolean;
}
/**
 * Generic typed event listener map used internally by `TypedEventEmitter`.
 * @internal
 */
type EventMap = Record<string, (...args: any[]) => void>;
/**
 * Event map for the base client (shared by both WHIP and WHEP).
 *
 * The index signature `[event: string]` is required so the interface
 * satisfies the `EventMap` constraint on `TypedEventEmitter`. It does not
 * weaken the typed overloads for known events.
 */
interface BaseClientEvents extends EventMap {
    /** Fired when the ICE + DTLS connection is fully established. */
    connected: () => void;
    /**
     * Fired when the peer connection transitions to `disconnected` state.
     * Media may recover automatically; wait for `failed` before giving up.
     */
    disconnected: () => void;
    /** Fired when the connection has irrecoverably failed. */
    failed: (error: Error) => void;
    /** Fired on every `RTCPeerConnection.connectionState` change. */
    connectionstatechange: (state: RTCPeerConnectionState) => void;
    /** Fired on every `RTCPeerConnection.iceConnectionState` change. */
    iceconnectionstatechange: (state: RTCIceConnectionState) => void;
    /** Fired on every `RTCPeerConnection.iceGatheringState` change. */
    icegatheringstatechange: (state: RTCIceGatheringState) => void;
    /**
     * Fired at the start of each auto-reconnect attempt.
     *
     * @param attempt  1-based attempt number.
     * @param delayMs  Milliseconds the library waited before this attempt.
     */
    reconnecting: (attempt: number, delayMs: number) => void;
    /** Fired when an auto-reconnect attempt successfully re-establishes the session. */
    reconnected: () => void;
}
/**
 * Events emitted exclusively by the WHEP viewer client.
 */
interface WHEPClientEvents extends BaseClientEvents {
    /**
     * Fired when the remote `MediaStream` is ready to be attached to a
     * `<video>` or `<audio>` element.
     */
    stream: (stream: MediaStream) => void;
}
/**
 * Events emitted by the WHIP publisher client.
 */
interface WHIPClientEvents extends BaseClientEvents {
    /**
     * Fired when adaptive quality changes the effective encoding level.
     *
     * Only emitted when `adaptiveQuality` is enabled. The `quality` argument
     * reflects the measured `ConnectionQuality` that triggered the change.
     *
     * @param quality  The new quality level driving the bitrate target.
     */
    qualitychange: (quality: ConnectionQuality) => void;
    /**
     * Fired periodically while audio level monitoring is active.
     *
     * Only emitted after `startAudioLevelMonitor()` is called.
     * `level` is a normalised RMS value in the range **[0, 1]**, where `0` is
     * silence and `1` is the maximum measurable amplitude.
     *
     * @param level  Normalised RMS audio level (0–1).
     */
    audiolevel: (level: number) => void;
}

/**
 * Strongly-typed event emitter.
 *
 * Provides `on`, `off`, `once`, and `emit` with full TypeScript inference
 * over a generic event map.
 *
 * Internal storage is untyped (`unknown`) to avoid the variance conflicts
 * that arise when trying to make the listener Set generic. All type safety
 * is enforced at the public API boundary.
 */
declare class TypedEventEmitter<TEvents extends EventMap> {
    private readonly _listeners;
    on<K extends keyof TEvents>(event: K, listener: TEvents[K]): this;
    off<K extends keyof TEvents>(event: K, listener: TEvents[K]): this;
    once<K extends keyof TEvents>(event: K, listener: TEvents[K]): this;
    protected emit<K extends keyof TEvents>(event: K, ...args: Parameters<TEvents[K]>): void;
    removeAllListeners(event?: keyof TEvents): this;
}
/**
 * Lifecycle state of a WHIP or WHEP client instance.
 *
 * ```
 * idle → connecting → connected ↔ disconnected
 *                  ↘ failed
 *                  (any) → closed
 * ```
 */
type ClientState = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'failed' | 'closed';
/**
 * Abstract base class shared by `WHIPClient` and `WHEPClient`.
 *
 * Responsibilities:
 * - `RTCPeerConnection` lifecycle management
 * - HTTP signalling (POST / PATCH / DELETE)
 * - Bearer token injection
 * - Connection-state event forwarding
 * - Timeout handling
 * - Auto-reconnect orchestration
 * - Structured logging
 */
declare abstract class BaseClient<TEvents extends BaseClientEvents> extends TypedEventEmitter<TEvents> {
    protected readonly options: Required<Omit<BaseClientOptions, 'headers' | 'getHeaders' | 'logger' | 'autoReconnect' | 'iceConnectionTimeout'>> & {
        headers: Record<string, string> | undefined;
        getHeaders: (() => Record<string, string> | Promise<Record<string, string>>) | undefined;
        logger: Logger | undefined;
        autoReconnect: boolean | AutoReconnectOptions | undefined;
        iceConnectionTimeout: number | undefined;
    };
    protected pc: RTCPeerConnection | null;
    protected resourceUrl: string | null;
    /**
     * The `ETag` value from the most recent successful WHIP/WHEP POST (or
     * ICE-restart PATCH) response. Used by endpoint recovery to send an
     * `If-Match` header per RFC 9725 §4.3. `null` until the first successful
     * exchange and after the resource is deleted.
     */
    protected etag: string | null;
    /** Set to `true` once the connection reaches `'connected'` for the first time. */
    protected _wasConnected: boolean;
    /** Incremented on each `stop()` or manual reconnect to cancel pending retries. */
    protected _reconnectToken: number;
    private _state;
    constructor(options: BaseClientOptions);
    /** Current lifecycle state of the client. */
    get state(): ClientState;
    /**
     * The resource URL returned by the server after a successful WHIP / WHEP
     * POST. `null` before connection and after `stop()`.
     */
    get resource(): string | null;
    protected createPeerConnection(): RTCPeerConnection;
    /**
     * Wait for the `RTCPeerConnection` to reach `'connected'` state.
     *
     * Resolves immediately when already connected. Rejects with a
     * `TimeoutError` when `iceConnectionTimeout` is set and the deadline
     * passes before the connection is established.
     */
    protected waitForIceConnection(pc: RTCPeerConnection): Promise<void>;
    /**
     * Dispatch connection-state transitions using an object-literal handler map.
     */
    private handleConnectionStateChange;
    /**
     * Type-safe emit for events defined in `BaseClientEvents`.
     */
    private emitBase;
    /**
     * Build request headers by merging all sources in priority order:
     *
     * 1. Built-in defaults (`Content-Type`, `Authorization` from `token`)
     * 2. Static `headers` option
     * 3. Dynamic `getHeaders()` return value  ← highest priority
     * 4. `extra` (per-call overrides, e.g. `Content-Type` for PATCH)
     */
    protected buildHeaders(extra?: Record<string, string>): Promise<Headers>;
    /**
     * POST an SDP offer to the WHIP / WHEP endpoint.
     *
     * @param sdpOffer       The SDP offer string to send.
     * @param externalSignal Optional `AbortSignal` from the caller. When the
     *   signal fires the in-flight fetch is cancelled and the original
     *   `DOMException` is re-thrown so the caller can distinguish an intentional
     *   abort from a timeout.
     * @returns The SDP answer body and the resource URL from the `Location`
     *   response header.
     * @throws {TimeoutError}    When the request exceeds `options.timeout`.
     * @throws {DOMException}    When `externalSignal` is aborted.
     * @throws {WhipWhepError}   On network errors or non-201 responses.
     */
    protected postSdpOffer(sdpOffer: string, externalSignal?: AbortSignal): Promise<{
        sdpAnswer: string;
        resourceUrl: string;
    }>;
    /**
     * PATCH trickle ICE candidates to the resource URL (best-effort).
     * Failures are silently ignored per the WHIP/WHEP spec.
     */
    protected patchIceCandidates(candidates: RTCIceCandidate[]): Promise<void>;
    /**
     * Send an HTTP DELETE to release the WHIP / WHEP resource on the server.
     * Best-effort: failures are silently ignored.
     */
    protected deleteResource(): Promise<void>;
    /**
     * Tear down the current peer connection and delete the server resource
     * **without** removing event listeners. Used by the reconnect flow so
     * that user-registered handlers survive the reconnect cycle.
     */
    protected teardownForReconnect(): Promise<void>;
    /**
     * Close the peer connection **without** deleting the server resource or
     * clearing the resource URL / ETag. Used by the endpoint-recovery flow so
     * that the session can be resumed via a PATCH rather than a full
     * DELETE + POST cycle.
     */
    protected teardownPcOnly(): void;
    /**
     * Override in subclasses to clean up ICE trickle handlers before
     * `teardownForReconnect` closes the peer connection.
     */
    protected onBeforeTeardown(): void;
    /**
     * PATCH a new SDP offer to the existing WHIP resource URL to perform an
     * ICE restart per RFC 9725 §4.3.
     *
     * Sends `Content-Type: application/sdp` with an `If-Match` header
     * containing the session ETag (when available). Expects a `200 OK`
     * response with a new SDP answer; any other status causes a
     * `WhipWhepError` to be thrown so the caller can fall back to a full
     * reconnect.
     *
     * On success, the ETag is updated from the response headers.
     *
     * @throws {TimeoutError}  When the request exceeds `options.timeout`.
     * @throws {WhipWhepError} On network error or non-200 response.
     */
    protected patchSdpForIceRestart(sdpOffer: string): Promise<string>;
    /**
     * Run a retry loop calling `callback` up to `opts.maxAttempts` times.
     *
     * Emits `'reconnecting'` before each attempt and `'reconnected'` on
     * success. After exhausting all attempts, emits a final `'failed'`.
     * Stops early when `token` no longer matches `this._reconnectToken`
     * (i.e. `stop()` was called).
     */
    protected scheduleReconnect(callback: () => Promise<void>, token: number): Promise<void>;
    private resolveAutoReconnect;
    protected setState(state: ClientState): void;
    /** Close the peer connection and clear all event listeners. */
    protected close(): void;
    protected assertIdle(methodName: string): void;
}

/**
 * WHIP (WebRTC-HTTP Ingestion Protocol – RFC 9725) client.
 *
 * Publishes a `MediaStream` to a WHIP-compatible ingest server using a
 * single SDP offer/answer exchange over HTTP POST, followed by an optional
 * trickle-ICE exchange via HTTP PATCH.
 *
 * ### Minimal usage
 *
 * ```ts
 * const client = new WHIPClient({ endpoint: 'https://ingest.example.com/whip/live' });
 * const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
 * await client.publish(stream);
 * // …
 * await client.stop();
 * ```
 *
 * ### Advanced usage
 *
 * ```ts
 * const client = new WHIPClient({
 *   endpoint: 'https://ingest.example.com/whip/live',
 *   token: 'my-secret',
 *   simulcast: true,
 *   videoCodec: 'h264',
 *   maxBandwidth: 4_000,          // 4 Mbps session limit (b=AS in SDP)
 *   audio: {
 *     maxBitrate: 128_000,        // 128 kbps
 *     dtx: true,
 *     stereo: true,
 *     fec: true,
 *   },
 *   video: [
 *     { rid: 'high', maxBitrate: 2_500_000, scaleResolutionDownBy: 1 },
 *     { rid: 'mid',  maxBitrate: 1_000_000, scaleResolutionDownBy: 2 },
 *     { rid: 'low',  maxBitrate: 300_000,   scaleResolutionDownBy: 4 },
 *   ],
 * });
 * ```
 */
declare class WHIPClient extends BaseClient<WHIPClientEvents> {
    private readonly whipOptions;
    private cleanupIce;
    private _lastStream;
    private _lastPublishOptions;
    private _statsSnapshot;
    private _adaptiveTimer;
    private _targetBitrate;
    private _currentAdaptiveQuality;
    private _degradedCount;
    private _improvedCount;
    private _audioMonitorTimer;
    private _audioContext;
    private _audioAnalyser;
    private _audioLevelBuffer;
    constructor(options: WHIPClientOptions);
    /**
     * Publish a `MediaStream` to the WHIP endpoint.
     *
     * Steps performed:
     * 1. Create `RTCPeerConnection`
     * 2. Add media tracks / configure encodings
     * 3. Munge SDP (codec order, simulcast, bandwidth)
     * 4. `POST` offer → receive answer → `setRemoteDescription`
     * 5. Apply post-negotiation bitrate constraints via `RTCRtpSender.setParameters()`
     * 6. Wait for ICE connection (when `iceConnectionTimeout` is set)
     * 7. Start trickle-ICE PATCH in the background
     *
     * @param stream  The `MediaStream` to publish.
     * @param options Per-call overrides for audio/video flags and simulcast.
     *
     * @throws {WHIPError}         On server rejection or network error.
     * @throws {TimeoutError}      When the SDP or ICE exchange exceeds its timeout.
     * @throws {InvalidStateError} When `publish()` is called on a non-idle client.
     */
    publish(stream: MediaStream, options?: PublishOptions): Promise<void>;
    /**
     * Stop publishing and release all resources.
     *
     * Sends an HTTP DELETE to the WHIP resource URL (if available) and closes
     * the peer connection. Safe to call multiple times.
     */
    stop(): Promise<void>;
    /**
     * Re-establish the WHIP session using the stream from the last `publish()`
     * call. Cleans up the current peer connection, resets internal state, and
     * calls `publish()` again.
     *
     * Useful for manually triggering a reconnect after a `'failed'` event.
     *
     * @throws {InvalidStateError} When called before `publish()` has been called.
     */
    reconnect(): Promise<void>;
    /**
     * Mute the active audio or video sender by disabling its track.
     *
     * Disabling the track sends silence (audio) or a black frame (video) to the
     * remote peer without re-negotiation. The sender remains active and can be
     * unmuted instantly via `unmuteTrack()`.
     *
     * @param kind `'audio'` or `'video'`.
     * @throws {InvalidStateError} When there is no active sender for the given kind.
     */
    muteTrack(kind: 'audio' | 'video'): void;
    /**
     * Unmute the active audio or video sender by re-enabling its track.
     *
     * @param kind `'audio'` or `'video'`.
     * @throws {InvalidStateError} When there is no active sender for the given kind.
     */
    unmuteTrack(kind: 'audio' | 'video'): void;
    /**
     * Returns `true` when the given track kind is currently muted (i.e. the
     * underlying `MediaStreamTrack.enabled` is `false`).
     *
     * @param kind `'audio'` or `'video'`.
     * @throws {InvalidStateError} When there is no active sender for the given kind.
     */
    isTrackMuted(kind: 'audio' | 'video'): boolean;
    /**
     * Capture the screen / window / tab and publish it to the WHIP endpoint.
     *
     * Calls `getDisplayMedia` internally (triggering the browser's native
     * screen-picker). An optional microphone track can be added via
     * `micAudio`. The captured `MediaStream` is returned so the caller can
     * stop individual tracks when sharing ends.
     *
     * **Typical usage**
     * ```ts
     * const stream = await client.publishScreen({ micAudio: true });
     *
     * // Stop sharing when the user clicks a button
     * stopBtn.onclick = () => {
     *   for (const t of stream.getTracks()) t.stop();
     *   await client.stop();
     * };
     * ```
     *
     * @param options Screen capture and publish configuration.
     * @returns The captured `MediaStream` (video + optional audio tracks).
     *
     * @throws {DOMException}      `'NotAllowedError'` when the user denies the screen picker.
     * @throws {WHIPError}         On server rejection or network error.
     * @throws {InvalidStateError} When the client is not in the `'idle'` state.
     */
    publishScreen(options?: PublishScreenOptions): Promise<MediaStream>;
    /**
     * Start monitoring the outgoing audio level and emitting `'audiolevel'`
     * events at the given interval.
     *
     * Internally creates an `AudioContext` and connects the active audio
     * sender's track to an `AnalyserNode`. The emitted `level` value is the
     * normalised RMS amplitude of the audio signal in the range **[0, 1]**.
     *
     * Call `stopAudioLevelMonitor()` to release the `AudioContext` and stop
     * the polling timer. The monitor is stopped automatically by `stop()`.
     *
     * @param intervalMs Polling interval in milliseconds. Defaults to `100`.
     * @throws {InvalidStateError} When called before `publish()` or when there
     *   is no active audio sender.
     */
    startAudioLevelMonitor(intervalMs?: number): void;
    /**
     * Stop the audio level monitor started by `startAudioLevelMonitor()`.
     *
     * Clears the polling timer and closes the underlying `AudioContext`.
     * Safe to call when monitoring is not active.
     */
    stopAudioLevelMonitor(): void;
    /**
     * Poll `getStats()` on a fixed interval and invoke `callback` with each
     * snapshot and a rolling history window. Returns a cleanup function that
     * stops the polling when called.
     *
     * @example
     * ```ts
     * const stop = client.watchStats(2_000, (stats, history) => {
     *   console.log('bitrate', stats.video?.bitrate);
     *   console.log('avg bitrate (10s)', history.avgVideoBitrate());
     *   console.log('delta', stats.video!.bitrate - (history.prev?.video?.bitrate ?? 0));
     * });
     * // Later:
     * stop();
     * ```
     *
     * @param intervalMs  How often to collect stats in milliseconds.
     * @param callback    Invoked with each `StreamStats` snapshot and the
     *                    rolling `StatsHistory` window.
     * @param historySize Maximum number of past snapshots retained in the
     *                    history window. Defaults to `10`.
     * @returns A zero-argument cleanup function that cancels polling.
     */
    watchStats(intervalMs: number, callback: (stats: StreamStats, history: StatsHistory) => void, historySize?: number): () => void;
    /**
     * Replace the active audio or video track on the sender without
     * re-negotiation. The new track takes effect immediately.
     *
     * The stored stream reference used for reconnection is updated
     * automatically so that future `reconnect()` calls use the new track.
     *
     * @param kind  `'audio'` or `'video'`.
     * @param track The replacement `MediaStreamTrack`.
     *
     * @throws {InvalidStateError} When there is no active sender for the given kind.
     */
    replaceTrack(kind: 'audio' | 'video', track: MediaStreamTrack): Promise<void>;
    /**
     * Collect a normalised statistics snapshot from the active
     * `RTCPeerConnection`. Bitrate values are computed as a delta since the
     * previous `getStats()` call.
     *
     * @throws {InvalidStateError} When no active peer connection exists.
     */
    getStats(): Promise<StreamStats>;
    private addAudioTransceiver;
    private addVideoTransceiver;
    private buildSimulcastEncodings;
    private buildSingleEncoding;
    private mutateSdpOffer;
    /**
     * Apply bitrate and degradation-preference constraints via
     * `RTCRtpSender.setParameters()` after `setRemoteDescription`.
     */
    private applyEncodingConstraints;
    private applyAudioConstraints;
    private applyVideoConstraints;
    protected onBeforeTeardown(): void;
    private _doReconnect;
    /**
     * Attempt to recover the WHIP session by sending a new SDP offer to the
     * existing resource URL via HTTP PATCH (RFC 9725 §4.3).
     *
     * Creates a fresh `RTCPeerConnection`, generates a new offer, and PATCHes
     * the resource with `If-Match: <etag>`. If the server responds with
     * `200 OK`, the new answer is applied and ICE proceeds normally.
     *
     * The server resource is **not** deleted before the attempt, preserving
     * the session for potential recovery.
     *
     * @throws When the PATCH is rejected or the connection fails to establish.
     */
    private _tryEndpointRecovery;
    private startAdaptiveQuality;
    private stopAdaptiveQuality;
    private _adaptStep;
    /**
     * Apply the bitrate target for the given quality level to the active
     * video sender via `RTCRtpSender.setParameters()`.
     */
    private _applyQualityBitrate;
    /** Determine the baseline video bitrate for adaptive quality scaling. */
    private getTargetBitrate;
    private resolveAdaptiveQuality;
}

/**
 * WHEP (WebRTC-HTTP Egress Protocol) client.
 *
 * Subscribes to a live media stream from a WHEP-compatible server using a
 * single SDP offer/answer exchange over HTTP POST, followed by an optional
 * trickle-ICE exchange via HTTP PATCH.
 *
 * ### Minimal usage
 *
 * ```ts
 * const client = new WHEPClient({ endpoint: 'https://cdn.example.com/whep/stream123' });
 *
 * client.on('stream', (stream) => { videoEl.srcObject = stream; });
 *
 * await client.view();
 * // …
 * await client.stop();
 * ```
 *
 * ### Advanced usage
 *
 * ```ts
 * const client = new WHEPClient({
 *   endpoint: 'https://cdn.example.com/whep/stream123',
 *   token: 'viewer-token',
 *   videoCodec: 'h264',
 *   maxBandwidth: 2_500,   // hint server to send ≤2.5 Mbps
 * });
 * ```
 */
declare class WHEPClient extends BaseClient<WHEPClientEvents> {
    private readonly whepOptions;
    private cleanupIce;
    private _lastViewOptions;
    private _statsSnapshot;
    constructor(options: WHEPClientOptions);
    /**
     * Start receiving the remote stream from the WHEP endpoint.
     *
     * Steps performed:
     * 1. Create `RTCPeerConnection`
     * 2. Add `recvonly` transceivers for audio and/or video
     * 3. Munge SDP (codec order, bandwidth hint)
     * 4. `POST` offer → receive answer → `setRemoteDescription`
     * 5. Wait for ICE connection (when `iceConnectionTimeout` is set)
     * 6. Start trickle-ICE PATCH in the background
     *
     * The returned `MediaStream` is populated with tracks as they arrive via
     * `ontrack`. The `'stream'` event fires once all expected tracks have been
     * received, making it safe to assign directly to `videoEl.srcObject`.
     *
     * @param options Per-call control over which media types to receive.
     * @returns A `MediaStream` that will be populated as remote tracks arrive.
     *
     * @throws {WHEPError}         On server rejection or network error.
     * @throws {TimeoutError}      When the SDP or ICE exchange exceeds its timeout.
     * @throws {InvalidStateError} When `view()` is called on a non-idle client.
     */
    view(options?: ViewOptions): Promise<MediaStream>;
    /**
     * Stop receiving and release all resources.
     *
     * Stops all remote tracks, sends an HTTP DELETE, and closes the peer
     * connection. Safe to call multiple times.
     */
    stop(): Promise<void>;
    /**
     * Re-establish the WHEP session. Cleans up the current peer connection,
     * resets internal state, and calls `view()` with the options from the
     * last `view()` call.
     *
     * The new `MediaStream` is delivered via the `'stream'` event.
     */
    reconnect(): Promise<void>;
    /**
     * Collect a normalised statistics snapshot from the active
     * `RTCPeerConnection`. Bitrate values are computed as a delta since the
     * previous `getStats()` call.
     *
     * @throws {InvalidStateError} When no active peer connection exists.
     */
    getStats(): Promise<StreamStats>;
    private mutateSdpOffer;
    protected onBeforeTeardown(): void;
    private _doReconnect;
}

/**
 * Base error class for all `whip-whep-client` errors.
 *
 * Carries the HTTP `status` code when the error originates from a server
 * response, and a `cause` chain compatible with the native `Error` options
 * added in ES2022.
 */
declare class WhipWhepError extends Error {
    /**
     * HTTP status code from the server response, when applicable.
     * `undefined` for local errors (network failure, timeout, etc.).
     */
    readonly status: number | undefined;
    constructor(message: string, options?: {
        status?: number;
        cause?: unknown;
    });
}
/** Thrown by `WHIPClient` when an error occurs during publishing. */
declare class WHIPError extends WhipWhepError {
    constructor(message: string, options?: {
        status?: number;
        cause?: unknown;
    });
}
/** Thrown by `WHEPClient` when an error occurs during viewing. */
declare class WHEPError extends WhipWhepError {
    constructor(message: string, options?: {
        status?: number;
        cause?: unknown;
    });
}
/** Thrown when a timed operation exceeds its deadline. */
declare class TimeoutError extends WhipWhepError {
    constructor(timeoutMs: number, message?: string);
}
/**
 * Thrown when a method is called on a client that is not in the expected
 * lifecycle state (e.g. calling `publish()` on a connected client).
 */
declare class InvalidStateError extends WhipWhepError {
    constructor(message: string);
}

/**
 * SDP utility helpers.
 *
 * Pure string-manipulation functions with no dependency on browser APIs –
 * all functions are fully unit-testable in a Node.js / jsdom environment.
 */
/**
 * Reorder codecs in an SDP offer so the preferred codec appears first in the
 * `m=<kind>` payload type list.
 *
 * The matching is case-insensitive. Associated RTX payload types are moved
 * together with their primary codec. Returns the SDP unchanged when the
 * codec is not present.
 *
 * @param sdp            Raw SDP string.
 * @param kind           `'audio'` or `'video'`.
 * @param preferredCodec Codec name – e.g. `'opus'`, `'H264'`, `'VP8'`.
 */
declare const preferCodec: (sdp: string, kind: "audio" | "video", preferredCodec: string) => string;
/**
 * Add a bandwidth limit to the `m=<kind>` section of an SDP string.
 *
 * Writes both:
 * - `b=AS:<maxKbps>` (RFC 4566 – kbps, widely supported)
 * - `b=TIAS:<maxBps>` (RFC 3890 – bps, more precise)
 *
 * If a `b=` line already exists it is replaced. When `maxKbps` is `0` or
 * negative any existing bandwidth lines are removed.
 *
 * @param sdp      Raw SDP string.
 * @param kind     `'audio'` or `'video'`, or `'session'` to set the session-level limit.
 * @param maxKbps  Maximum bandwidth in **kilobits per second**.
 */
declare const setBandwidth: (sdp: string, kind: "audio" | "video" | "session", maxKbps: number) => string;
/**
 * Add simulcast send layers to the first `m=video` section of an SDP offer.
 *
 * Appends `a=rid` and `a=simulcast` lines for three quality tiers:
 * `high`, `mid`, and `low`. Safe to call when no `m=video` section is
 * present (SDP is returned unchanged). Idempotent – does nothing when the
 * section already contains an `a=simulcast` line.
 *
 * @param sdp Raw SDP offer string.
 */
declare const addSimulcast: (sdp: string) => string;
/**
 * Patch `a=fmtp` attributes for the given codec in the `m=<kind>` section.
 *
 * Merges the provided key-value pairs into any existing `a=fmtp` line for
 * each matching payload type. Creates a new `a=fmtp` line if none exists.
 *
 * @param sdp    Raw SDP string.
 * @param kind   `'audio'` or `'video'`.
 * @param codec  Codec name used to locate the `a=rtpmap` line (e.g. `'opus'`).
 * @param params Key-value map merged into `a=fmtp` (e.g. `{ usedtx: 1, stereo: 1 }`).
 */
declare const patchFmtp: (sdp: string, kind: "audio" | "video", codec: string, params: Record<string, string | number>) => string;
/**
 * Extract the SSRC value from the first `a=ssrc` line in the `m=<kind>`
 * section. Returns `undefined` when not found.
 */
declare const extractSsrc: (sdp: string, kind: "audio" | "video") => number | undefined;
/**
 * Strip all `a=extmap` lines referencing a specific URI from an SDP.
 * Useful for removing unsupported RTP header extensions.
 */
declare const removeExtmap: (sdp: string, uri: string) => string;
/**
 * Return all codec names found in the given `m=<kind>` section.
 * Codec names are derived from `a=rtpmap` lines (e.g. `'opus'`, `'VP8'`).
 */
declare const listCodecs: (sdp: string, kind: "audio" | "video") => string[];

/**
 * ICE trickle helpers.
 *
 * Collects ICE candidates emitted by an `RTCPeerConnection` and forwards
 * them to the server via HTTP PATCH (per the WHIP / WHEP trickle-ICE
 * extension defined in the respective RFCs).
 */
/**
 * Controls when gathered ICE candidates are dispatched to the server.
 *
 * - `'end-of-candidates'` – buffer all candidates and send a single PATCH
 *   once ICE gathering is complete. Maximises server compatibility.
 * - `'immediate'` – send each candidate individually as soon as it arrives.
 *   Reduces latency but may result in many small PATCH requests.
 */
type IceTrickleMode = 'end-of-candidates' | 'immediate';
interface IceTrickleOptions {
    /**
     * Dispatch mode. Defaults to `'end-of-candidates'`.
     */
    mode?: IceTrickleMode;
    /**
     * Called when one or more candidates should be sent to the server.
     * The host is responsible for making the PATCH request.
     */
    onCandidates: (candidates: RTCIceCandidate[]) => Promise<void>;
    /**
     * Optional callback invoked when ICE gathering is complete regardless
     * of whether any candidates were gathered.
     */
    onGatheringComplete?: () => void;
}
/**
 * Subscribe to ICE candidate events on `pc` and forward gathered candidates
 * via `options.onCandidates`.
 *
 * @returns A cleanup function that removes the attached event listeners.
 */
declare function setupIceTrickle(pc: RTCPeerConnection, options: IceTrickleOptions): () => void;
/**
 * Wait for ICE gathering to reach the `'complete'` state on `pc`.
 *
 * Resolves immediately when `iceGatheringState` is already `'complete'`.
 * Rejects after `timeoutMs` milliseconds (default 5 000 ms).
 */
declare function waitForIceGathering(pc: RTCPeerConnection, timeoutMs?: number): Promise<void>;

/**
 * Browser media utilities.
 *
 * Convenience wrappers around `getUserMedia` and `getDisplayMedia` that apply
 * sensible defaults and set `contentHint` values so the WebRTC encoder can
 * choose the most appropriate settings for the content type.
 */
/**
 * Options for `getScreenStream`.
 */
interface ScreenStreamOptions {
    /**
     * Capture system audio along with the screen.
     *
     * Browser support varies: Chrome supports tab and system audio; Safari and
     * Firefox do not support system audio capture via `getDisplayMedia`.
     * Defaults to `false`.
     */
    audio?: boolean;
    /**
     * Override individual video constraints merged on top of the defaults
     * (`{ width: 1920, height: 1080, frameRate: 30 }`).
     */
    videoConstraints?: MediaTrackConstraints;
}
/**
 * Options for `getUserStream`.
 */
interface UserStreamOptions {
    /** Request audio. Defaults to `true`. */
    audio?: boolean | MediaTrackConstraints;
    /** Request video. Defaults to `true`. */
    video?: boolean | MediaTrackConstraints;
    /**
     * Hint to set on the video track.
     * - `'motion'` – optimise for fast movement (default for camera).
     * - `'detail'` – optimise for sharpness (slides, documents).
     */
    videoContentHint?: 'motion' | 'detail' | 'text' | '';
    /**
     * Hint to set on the audio track.
     * - `'speech'` – optimise for voice (default).
     * - `'music'` – optimise for music / wide-band content.
     */
    audioContentHint?: 'speech' | 'speech-recognition' | 'music' | '';
}
/**
 * Request a screen / window / tab capture stream using `getDisplayMedia`.
 *
 * Sets `contentHint = 'detail'` on all video tracks so the encoder can
 * prioritise sharpness over motion smoothness, which is appropriate for
 * most screen-sharing scenarios.
 *
 * @example
 * ```ts
 * import { getScreenStream } from 'whip-whep-client/utils/media';
 *
 * const screen = await getScreenStream({ audio: true });
 * await whipClient.publish(screen);
 * ```
 *
 * @throws `DOMException` with name `'NotAllowedError'` when the user denies
 * the permission prompt.
 */
declare function getScreenStream(options?: ScreenStreamOptions): Promise<MediaStream>;
/**
 * Request a camera + microphone stream using `getUserMedia`.
 *
 * Applies `contentHint` values that match typical live-streaming use-cases
 * and can be overridden via the `videoContentHint` / `audioContentHint`
 * options.
 *
 * @example
 * ```ts
 * import { getUserStream } from 'whip-whep-client/utils/media';
 *
 * const stream = await getUserStream({ videoContentHint: 'motion' });
 * await whipClient.publish(stream);
 * ```
 *
 * @throws `DOMException` with name `'NotAllowedError'` when the user denies
 * the permission prompt.
 */
declare function getUserStream(options?: UserStreamOptions): Promise<MediaStream>;

/**
 * A partial options object that can be spread into `WHIPClient` or
 * `WHEPClient` constructors. The `endpoint` field is intentionally excluded
 * because it is always server-instance-specific.
 */
type WHIPPreset = Omit<WHIPClientOptions, 'endpoint'>;
type WHEPPreset = Omit<WHEPClientOptions, 'endpoint'>;
/**
 * Presets for LiveKit Cloud and self-hosted LiveKit Server.
 *
 * LiveKit uses standard WHIP/WHEP signalling. Tokens are LiveKit Access
 * Tokens (JWTs) generated server-side via the LiveKit Server SDK.
 *
 * Endpoint formats:
 * - WHIP: `https://<project>.livekit.cloud/rtc/whip`
 * - WHEP: `https://<project>.livekit.cloud/rtc/whep`
 *
 * @see https://docs.livekit.io/realtime/ingress/whip/
 * @see https://docs.livekit.io/realtime/egress/whep/
 */
declare const livekit: {
    /**
     * Recommended options for publishing to a LiveKit WHIP endpoint.
     *
     * @param token LiveKit Access Token (JWT).
     */
    whip(token: string): WHIPPreset;
    /**
     * Recommended options for viewing from a LiveKit WHEP endpoint.
     *
     * @param token LiveKit Access Token (JWT).
     */
    whep(token: string): WHEPPreset;
};
/**
 * Presets for OvenMediaEngine (OME).
 *
 * OME exposes WHIP and WHEP on separate ports by default:
 * - WHIP port: `3333`  (WebRTC Push)
 * - WHEP port: `3334`  (WebRTC Pull)
 *
 * Endpoint formats:
 * - WHIP: `http://<host>:3333/<app>/<stream>`
 * - WHEP: `http://<host>:3334/<app>/<stream>`
 *
 * Authentication is optional and configured per-application in
 * `Server.xml`. When enabled, pass the signed policy token via `token`.
 *
 * @see https://airensoft.gitbook.io/ovenmediaengine/live-source/whip
 * @see https://airensoft.gitbook.io/ovenmediaengine/streaming/webrtc-publishing
 */
declare const ovenmedia: {
    /**
     * Recommended options for publishing to an OvenMedia Engine WHIP endpoint.
     *
     * @param token Signed policy token (omit when access control is disabled).
     */
    whip(token?: string): WHIPPreset;
    /**
     * Recommended options for viewing from an OvenMedia Engine WHEP endpoint.
     *
     * @param token Signed policy token (omit when access control is disabled).
     */
    whep(token?: string): WHEPPreset;
};
/**
 * Presets for Cloudflare Stream WebRTC (WHIP ingest).
 *
 * The authentication key is embedded in the endpoint URL; no separate
 * `Authorization` header is needed. H.264 is required.
 *
 * Endpoint format:
 * - WHIP: `https://customer-<uid>.cloudflarestream.com/<live-input-key>/webrtc/publish`
 * - WHEP: `https://customer-<uid>.cloudflarestream.com/<live-input-key>/webrtc/play`
 *
 * The `<live-input-key>` is obtained when creating a Live Input via the
 * Cloudflare Stream API or dashboard.
 *
 * @see https://developers.cloudflare.com/stream/webrtc-beta/
 */
declare const cloudflare: {
    /**
     * Recommended options for publishing to Cloudflare Stream via WHIP.
     *
     * Authentication is handled through the endpoint URL; no token is needed.
     */
    whip(): WHIPPreset;
    /**
     * Recommended options for viewing from Cloudflare Stream via WHEP.
     */
    whep(): WHEPPreset;
};
/**
 * Presets for Millicast (Dolby.io Real-time Streaming).
 *
 * Millicast is a managed WebRTC CDN with global delivery via WHIP ingest
 * and WHEP egress. Authentication uses Bearer tokens issued by the Millicast
 * Director API — never embed long-lived tokens in client code.
 *
 * Endpoint formats:
 * - WHIP: `https://director.millicast.com/api/whip/<streamName>`
 * - WHEP: `https://director.millicast.com/api/whep/<streamName>`
 *
 * @see https://docs.dolby.io/streaming-apis/docs/whip
 * @see https://docs.dolby.io/streaming-apis/docs/whep
 */
declare const millicast: {
    /**
     * Recommended options for publishing to Millicast via WHIP.
     *
     * @param token Short-lived publish token obtained from the Millicast Director API.
     */
    whip(token: string): WHIPPreset;
    /**
     * Recommended options for viewing from Millicast via WHEP.
     *
     * @param token Short-lived subscribe token obtained from the Millicast Director API.
     */
    whep(token: string): WHEPPreset;
};
/**
 * Presets for SRS (Simple Realtime Server).
 *
 * SRS is a popular open-source media server with native WHIP and WHEP
 * support. By default no authentication is required; to enable it, set
 * `http_hooks` or `security` in `srs.conf` and pass the generated token.
 *
 * Endpoint formats:
 * - WHIP: `http://<host>:1985/rtc/v1/whip/?app=<app>&stream=<streamName>`
 * - WHEP: `http://<host>:1985/rtc/v1/whep/?app=<app>&stream=<streamName>`
 *
 * @see https://ossrs.io/lts/en-us/docs/v6/doc/whip
 */
declare const srs: {
    /**
     * Recommended options for publishing to SRS via WHIP.
     *
     * @param token Auth token (omit when SRS security hooks are disabled).
     */
    whip(token?: string): WHIPPreset;
    /**
     * Recommended options for viewing from SRS via WHEP.
     *
     * @param token Auth token (omit when SRS security hooks are disabled).
     */
    whep(token?: string): WHEPPreset;
};
/**
 * Presets for MediaMTX (formerly rtsp-simple-server).
 *
 * MediaMTX is a lightweight, zero-dependency media server that supports
 * WHIP and WHEP out of the box. Authentication is optional and configured
 * via `mediamtx.yml`; when enabled, pass the credentials as a Bearer token.
 *
 * Endpoint formats:
 * - WHIP: `http://<host>:8889/<pathName>/whip`
 * - WHEP: `http://<host>:8889/<pathName>/whep`
 *
 * @see https://github.com/bluenviron/mediamtx#webrtc
 */
declare const mediamtx: {
    /**
     * Recommended options for publishing to MediaMTX via WHIP.
     *
     * @param token Internal authentication token (omit when auth is disabled).
     */
    whip(token?: string): WHIPPreset;
    /**
     * Recommended options for viewing from MediaMTX via WHEP.
     *
     * @param token Internal authentication token (omit when auth is disabled).
     */
    whep(token?: string): WHEPPreset;
};
/**
 * Presets for Ant Media Server (AMS) Community and Enterprise editions.
 *
 * Endpoint formats:
 * - WHIP: `http://<host>:5080/<app>/whip/<streamId>`
 * - WHEP: `http://<host>:5080/<app>/whep/<streamId>`
 *
 * Enterprise edition supports HTTPS and JWT-based authentication.
 * The token, when required, is passed as a Bearer token.
 *
 * @see https://antmedia.io/docs/guides/publish-live-stream/WebRTC/webrtc-whip/
 * @see https://antmedia.io/docs/guides/playing-live-stream/WebRTC/webrtc-whep/
 */
declare const antmedia: {
    /**
     * Recommended options for publishing to Ant Media Server via WHIP.
     *
     * @param token JWT subscriber token (omit when authentication is disabled).
     */
    whip(token?: string): WHIPPreset;
    /**
     * Recommended options for viewing from Ant Media Server via WHEP.
     *
     * @param token JWT subscriber token (omit when authentication is disabled).
     */
    whep(token?: string): WHEPPreset;
};

export { type AdaptiveQualityOptions, type AudioEncodingOptions, type AudioStats, type AutoReconnectOptions, type BaseClientEvents, type BaseClientOptions, type ClientState, type ConnectionQuality, type IceTrickleMode, type IceTrickleOptions, InvalidStateError, type Logger, type PublishOptions, type PublishScreenOptions, type ScreenStreamOptions, type StatsHistory, type StreamStats, TimeoutError, TypedEventEmitter, type UserStreamOptions, type VideoLayerOptions, type VideoStats, type ViewOptions, WHEPClient, type WHEPClientEvents, type WHEPClientOptions, WHEPError, type WHEPPreset, WHIPClient, type WHIPClientEvents, type WHIPClientOptions, WHIPError, type WHIPPreset, WhipWhepError, addSimulcast, antmedia, cloudflare, extractSsrc, getScreenStream, getUserStream, listCodecs, livekit, mediamtx, millicast, ovenmedia, patchFmtp, preferCodec, removeExtmap, setBandwidth, setupIceTrickle, srs, waitForIceGathering };
