@daydreamlive/browser 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +40 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -8
- package/dist/index.d.ts +4 -8
- package/dist/index.js +40 -139
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/errors.ts","../src/internal/dependencies.ts","../src/internal/WHIPClient.ts","../src/internal/TypedEventEmitter.ts","../src/internal/StateMachine.ts","../src/Broadcast.ts","../src/internal/WHEPClient.ts","../src/Player.ts","../src/internal/compositor/Registry.ts","../src/internal/compositor/Renderer.ts","../src/internal/compositor/Scheduler.ts","../src/internal/compositor/AudioManager.ts","../src/internal/compositor/VisibilityHandler.ts","../src/Compositor.ts"],"sourcesContent":["import type { BroadcastOptions, WHIPResponseResult } from \"./types\";\nimport { Broadcast, createBroadcast as baseCreateBroadcast } from \"./Broadcast\";\nimport { Player, createPlayer as baseCreatePlayer } from \"./Player\";\nimport type { PlayerOptions } from \"./types\";\n\nexport const livepeerResponseHandler = (\n response: Response,\n): WHIPResponseResult => ({\n whepUrl: response.headers.get(\"livepeer-playback-url\") ?? undefined,\n});\n\nexport type LivepeerBroadcastOptions = Omit<BroadcastOptions, \"onResponse\">;\n\nexport function createBroadcast(options: LivepeerBroadcastOptions): Broadcast {\n return baseCreateBroadcast({\n ...options,\n onResponse: livepeerResponseHandler,\n });\n}\n\nexport function createPlayer(whepUrl: string, options?: PlayerOptions): Player {\n return baseCreatePlayer(whepUrl, options);\n}\n\nexport {\n BaseDaydreamError,\n NetworkError,\n ConnectionError,\n StreamNotFoundError,\n UnauthorizedError,\n} from \"./errors\";\n\nexport type {\n AudioConfig,\n BroadcastOptions,\n PlayerOptions,\n BroadcastState,\n PlayerState,\n ReconnectConfig,\n ReconnectInfo,\n VideoConfig,\n BroadcastEventMap,\n PlayerEventMap,\n DaydreamError,\n DaydreamErrorCode,\n WHIPResponseResult,\n} from \"./types\";\n\nexport {\n DEFAULT_ICE_SERVERS,\n DEFAULT_VIDEO_BITRATE,\n DEFAULT_AUDIO_BITRATE,\n} from \"./types\";\n\nexport { Broadcast, type BroadcastConfig } from \"./Broadcast\";\nexport { Player, type PlayerConfig } from \"./Player\";\nexport { createCompositor } from \"./Compositor\";\n\nexport type {\n Compositor,\n CompositorOptions,\n CompositorEvent,\n CompositorEventMap,\n Source,\n VideoSource,\n CanvasSource,\n CustomSource,\n Size,\n FitMode,\n ContentHint,\n Ctx2D,\n} from \"./types\";\n","export type BroadcastState =\n | \"connecting\"\n | \"live\"\n | \"reconnecting\"\n | \"ended\"\n | \"error\";\n\nexport type PlayerState =\n | \"connecting\"\n | \"playing\"\n | \"buffering\"\n | \"ended\"\n | \"error\";\n\nexport interface WHIPResponseResult {\n whepUrl?: string;\n}\n\nexport interface BroadcastOptions {\n whipUrl: string;\n stream: MediaStream;\n reconnect?: ReconnectConfig;\n video?: VideoConfig;\n audio?: AudioConfig;\n iceServers?: RTCIceServer[];\n connectionTimeout?: number;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n onResponse?: (response: Response) => WHIPResponseResult | void;\n}\n\nexport interface PlayerOptions {\n reconnect?: ReconnectConfig;\n iceServers?: RTCIceServer[];\n connectionTimeout?: number;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n}\n\nexport interface ReconnectConfig {\n enabled?: boolean;\n maxAttempts?: number;\n baseDelayMs?: number;\n}\n\nexport interface ReconnectInfo {\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n}\n\nexport interface VideoConfig {\n bitrate?: number;\n maxFramerate?: number;\n}\n\nexport interface AudioConfig {\n bitrate?: number;\n}\n\nexport interface BroadcastEventMap {\n stateChange: (state: BroadcastState) => void;\n error: (error: DaydreamError) => void;\n reconnect: (info: ReconnectInfo) => void;\n}\n\nexport interface PlayerEventMap {\n stateChange: (state: PlayerState) => void;\n error: (error: DaydreamError) => void;\n reconnect: (info: ReconnectInfo) => void;\n}\n\nexport interface DaydreamError extends Error {\n code: DaydreamErrorCode;\n cause?: unknown;\n}\n\nexport type DaydreamErrorCode =\n | \"NETWORK_ERROR\"\n | \"CONNECTION_FAILED\"\n | \"STREAM_NOT_FOUND\"\n | \"UNAUTHORIZED\"\n | \"UNKNOWN\";\n\nexport const DEFAULT_ICE_SERVERS: RTCIceServer[] = [\n { urls: \"stun:stun.l.google.com:19302\" },\n { urls: \"stun:stun1.l.google.com:19302\" },\n { urls: \"stun:stun.cloudflare.com:3478\" },\n];\n\nexport const DEFAULT_VIDEO_BITRATE = 300_000;\nexport const DEFAULT_AUDIO_BITRATE = 64_000;\n\n// ============================================================================\n// Compositor Types\n// ============================================================================\n\nexport type Ctx2D =\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D;\n\nexport type FitMode = \"contain\" | \"cover\";\n\nexport type ContentHint = \"detail\" | \"motion\" | \"\";\n\nexport type VideoSource = {\n kind: \"video\";\n element: HTMLVideoElement;\n fit?: FitMode;\n contentHint?: ContentHint;\n};\n\nexport type CanvasSource = {\n kind: \"canvas\";\n element: HTMLCanvasElement;\n fit?: FitMode;\n contentHint?: ContentHint;\n};\n\nexport type CustomSource = {\n kind: \"custom\";\n onStart?: (ctx: Ctx2D) => void | (() => void);\n onFrame?: (ctx: Ctx2D, timestamp: number) => void;\n};\n\nexport type Source = VideoSource | CanvasSource | CustomSource;\n\nexport type Size = {\n width: number;\n height: number;\n dpr: number;\n};\n\nexport interface CompositorOptions {\n width?: number;\n height?: number;\n fps?: number;\n dpr?: number;\n crossfadeMs?: number;\n sendFps?: number;\n keepalive?: boolean;\n autoUnlockAudio?: boolean;\n unlockEvents?: string[];\n disableSilentAudio?: boolean;\n onSendFpsChange?: (fps: number) => void;\n}\n\nexport type CompositorEvent = \"activated\" | \"registered\" | \"unregistered\";\n\nexport interface CompositorEventMap {\n activated: (id: string | null, source: Source | undefined) => void;\n registered: (id: string, source: Source) => void;\n unregistered: (id: string) => void;\n}\n\nexport interface Compositor {\n // Source Registry\n register(id: string, source: Source): void;\n unregister(id: string): void;\n get(id: string): Source | undefined;\n has(id: string): boolean;\n list(): Array<{ id: string; source: Source }>;\n\n // Active source management\n activate(id: string): void;\n deactivate(): void;\n readonly activeId: string | null;\n\n // Output stream\n readonly stream: MediaStream;\n\n // Settings\n resize(width: number, height: number, dpr?: number): void;\n readonly size: Size;\n setFps(fps: number): void;\n readonly fps: number;\n setSendFps(fps: number): void;\n readonly sendFps: number;\n\n // Audio\n addAudioTrack(track: MediaStreamTrack): void;\n removeAudioTrack(trackId: string): void;\n unlockAudio(): Promise<boolean>;\n\n // Lifecycle\n destroy(): void;\n\n // Events\n on<E extends CompositorEvent>(\n event: E,\n cb: CompositorEventMap[E],\n ): () => void;\n}\n","import type { DaydreamError, DaydreamErrorCode } from \"./types\";\n\nexport class BaseDaydreamError extends Error implements DaydreamError {\n readonly code: DaydreamErrorCode;\n readonly cause?: unknown;\n\n constructor(code: DaydreamErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = \"DaydreamError\";\n this.code = code;\n this.cause = cause;\n }\n}\n\nexport class NetworkError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"NETWORK_ERROR\", message, cause);\n this.name = \"NetworkError\";\n }\n}\n\nexport class ConnectionError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"CONNECTION_FAILED\", message, cause);\n this.name = \"ConnectionError\";\n }\n}\n\nexport class StreamNotFoundError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"STREAM_NOT_FOUND\", message, cause);\n this.name = \"StreamNotFoundError\";\n }\n}\n\nexport class UnauthorizedError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"UNAUTHORIZED\", message, cause);\n this.name = \"UnauthorizedError\";\n }\n}\n","export interface PeerConnectionFactory {\n create(config: RTCConfiguration): RTCPeerConnection;\n}\n\nexport interface FetchFn {\n (input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\n}\n\nexport interface TimerProvider {\n setTimeout(callback: () => void, ms: number): number;\n clearTimeout(id: number): void;\n setInterval(callback: () => void, ms: number): number;\n clearInterval(id: number): void;\n}\n\nexport interface MediaStreamFactory {\n create(): MediaStream;\n}\n\nexport const defaultMediaStreamFactory: MediaStreamFactory = {\n create: () => new MediaStream(),\n};\n\nexport const defaultPeerConnectionFactory: PeerConnectionFactory = {\n create: (config) => new RTCPeerConnection(config),\n};\n\nexport const defaultFetch: FetchFn = globalThis.fetch.bind(globalThis);\n\nexport const defaultTimerProvider: TimerProvider = {\n setTimeout: (cb, ms) => globalThis.setTimeout(cb, ms) as unknown as number,\n clearTimeout: (id) => globalThis.clearTimeout(id),\n setInterval: (cb, ms) => globalThis.setInterval(cb, ms) as unknown as number,\n clearInterval: (id) => globalThis.clearInterval(id),\n};\n\n","import {\n DEFAULT_ICE_SERVERS,\n DEFAULT_VIDEO_BITRATE,\n DEFAULT_AUDIO_BITRATE,\n type WHIPResponseResult,\n} from \"../types\";\nimport { ConnectionError, NetworkError } from \"../errors\";\nimport {\n type PeerConnectionFactory,\n type FetchFn,\n type TimerProvider,\n defaultPeerConnectionFactory,\n defaultFetch,\n defaultTimerProvider,\n} from \"./dependencies\";\n\nconst PLAYBACK_ID_PATTERN = /([/+])([^/+?]+)$/;\nconst PLAYBACK_ID_PLACEHOLDER = \"__PLAYBACK_ID__\";\n\nexport interface RedirectCache {\n get(key: string): URL | undefined;\n set(key: string, value: URL): void;\n}\n\nclass LRURedirectCache implements RedirectCache {\n private cache = new Map<string, URL>();\n private readonly maxSize: number;\n\n constructor(maxSize = 10) {\n this.maxSize = maxSize;\n }\n\n get(key: string): URL | undefined {\n const cached = this.cache.get(key);\n if (cached) {\n this.cache.delete(key);\n this.cache.set(key, cached);\n }\n return cached;\n }\n\n set(key: string, value: URL): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey) this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n}\n\nexport interface WHIPClientConfig {\n url: string;\n iceServers?: RTCIceServer[];\n videoBitrate?: number;\n audioBitrate?: number;\n maxFramerate?: number;\n connectionTimeout?: number;\n skipIceGathering?: boolean;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n onResponse?: (response: Response) => WHIPResponseResult | void;\n peerConnectionFactory?: PeerConnectionFactory;\n fetch?: FetchFn;\n timers?: TimerProvider;\n redirectCache?: RedirectCache;\n}\n\nfunction preferH264(sdp: string): string {\n const lines = sdp.split(\"\\r\\n\");\n const mLineIndex = lines.findIndex((line) => line.startsWith(\"m=video\"));\n if (mLineIndex === -1) return sdp;\n\n const codecRegex = /a=rtpmap:(\\d+) H264(\\/\\d+)+/;\n const codecLine = lines.find((line) => codecRegex.test(line));\n if (!codecLine) return sdp;\n\n const match = codecRegex.exec(codecLine);\n const codecPayload = match?.[1];\n if (!codecPayload) return sdp;\n\n const mLine = lines[mLineIndex];\n if (!mLine) return sdp;\n\n const mLineElements = mLine.split(\" \");\n const reorderedMLine = [\n ...mLineElements.slice(0, 3),\n codecPayload,\n ...mLineElements.slice(3).filter((payload) => payload !== codecPayload),\n ];\n lines[mLineIndex] = reorderedMLine.join(\" \");\n return lines.join(\"\\r\\n\");\n}\n\nconst sharedRedirectCache = new LRURedirectCache();\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nexport class WHIPClient {\n private readonly url: string;\n private readonly iceServers: RTCIceServer[];\n private readonly videoBitrate: number;\n private readonly audioBitrate: number;\n private readonly connectionTimeout: number;\n private readonly onStats?: (report: RTCStatsReport) => void;\n private readonly statsIntervalMs: number;\n private readonly onResponse?: (\n response: Response,\n ) => WHIPResponseResult | void;\n private readonly pcFactory: PeerConnectionFactory;\n private readonly fetch: FetchFn;\n private readonly timers: TimerProvider;\n private readonly redirectCache: RedirectCache;\n private readonly skipIceGathering: boolean;\n\n private maxFramerate?: number;\n private pc: RTCPeerConnection | null = null;\n private resourceUrl: string | null = null;\n private abortController: AbortController | null = null;\n private statsTimer: number | null = null;\n private videoSender: RTCRtpSender | null = null;\n private audioSender: RTCRtpSender | null = null;\n private videoTransceiver: RTCRtpTransceiver | null = null;\n private audioTransceiver: RTCRtpTransceiver | null = null;\n private iceGatheringTimer: number | null = null;\n\n constructor(config: WHIPClientConfig) {\n this.url = config.url;\n this.iceServers = config.iceServers ?? DEFAULT_ICE_SERVERS;\n this.videoBitrate = config.videoBitrate ?? DEFAULT_VIDEO_BITRATE;\n this.audioBitrate = config.audioBitrate ?? DEFAULT_AUDIO_BITRATE;\n this.connectionTimeout = config.connectionTimeout ?? DEFAULT_CONNECTION_TIMEOUT;\n this.maxFramerate = config.maxFramerate;\n this.onStats = config.onStats;\n this.statsIntervalMs = config.statsIntervalMs ?? 5000;\n this.onResponse = config.onResponse;\n this.pcFactory =\n config.peerConnectionFactory ?? defaultPeerConnectionFactory;\n this.fetch = config.fetch ?? defaultFetch;\n this.timers = config.timers ?? defaultTimerProvider;\n this.redirectCache = config.redirectCache ?? sharedRedirectCache;\n this.skipIceGathering = config.skipIceGathering ?? true;\n }\n\n async connect(stream: MediaStream): Promise<{ whepUrl: string | null }> {\n this.cleanup();\n\n this.pc = this.pcFactory.create({\n iceServers: this.iceServers,\n iceCandidatePoolSize: 10,\n });\n\n this.videoTransceiver = this.pc.addTransceiver(\"video\", {\n direction: \"sendonly\",\n });\n this.audioTransceiver = this.pc.addTransceiver(\"audio\", {\n direction: \"sendonly\",\n });\n this.videoSender = this.videoTransceiver.sender;\n this.audioSender = this.audioTransceiver.sender;\n\n const videoTrack = stream.getVideoTracks()[0];\n const audioTrack = stream.getAudioTracks()[0];\n\n if (videoTrack) {\n if (videoTrack.contentHint === \"\") {\n videoTrack.contentHint = \"motion\";\n }\n await this.videoSender.replaceTrack(videoTrack);\n }\n\n if (audioTrack) {\n await this.audioSender.replaceTrack(audioTrack);\n }\n\n this.setCodecPreferences();\n await this.applyBitrateConstraints();\n\n const offer = await this.pc.createOffer({\n offerToReceiveAudio: false,\n offerToReceiveVideo: false,\n });\n const enhancedSdp = preferH264(offer.sdp ?? \"\");\n await this.pc.setLocalDescription({ type: \"offer\", sdp: enhancedSdp });\n\n if (!this.skipIceGathering) {\n await this.waitForIceGathering();\n }\n\n this.abortController = new AbortController();\n const timeoutId = this.timers.setTimeout(\n () => this.abortController?.abort(),\n this.connectionTimeout,\n );\n\n try {\n const fetchUrl = this.getUrlWithCachedRedirect();\n\n const response = await this.fetch(fetchUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/sdp\" },\n body: this.pc.localDescription!.sdp,\n signal: this.abortController.signal,\n });\n\n this.timers.clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new ConnectionError(\n `WHIP connection failed: ${response.status} ${response.statusText} ${errorText}`,\n );\n }\n\n this.cacheRedirectIfNeeded(fetchUrl, response.url);\n\n const location = response.headers.get(\"location\");\n if (location) {\n this.resourceUrl = new URL(location, this.url).toString();\n }\n\n const responseResult = this.onResponse?.(response);\n\n const answerSdp = await response.text();\n await this.pc.setRemoteDescription({ type: \"answer\", sdp: answerSdp });\n\n await this.applyBitrateConstraints();\n this.startStatsTimer();\n\n return { whepUrl: responseResult?.whepUrl ?? null };\n } catch (error) {\n this.timers.clearTimeout(timeoutId);\n if (error instanceof ConnectionError) {\n throw error;\n }\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new NetworkError(\"Connection timeout\");\n }\n throw new NetworkError(\"Failed to establish connection\", error);\n }\n }\n\n private setCodecPreferences(): void {\n if (!this.videoTransceiver?.setCodecPreferences) return;\n\n try {\n const caps = RTCRtpSender.getCapabilities(\"video\");\n if (!caps?.codecs?.length) return;\n\n const h264Codecs = caps.codecs.filter((c) =>\n c.mimeType.toLowerCase().includes(\"h264\"),\n );\n if (h264Codecs.length) {\n this.videoTransceiver.setCodecPreferences(h264Codecs);\n }\n } catch {\n // Codec preferences not supported\n }\n }\n\n private async applyBitrateConstraints(): Promise<void> {\n if (!this.pc) return;\n\n const senders = this.pc.getSenders();\n for (const sender of senders) {\n if (!sender.track) continue;\n\n const params = sender.getParameters();\n if (!params.encodings) params.encodings = [{}];\n\n const encoding = params.encodings[0];\n if (!encoding) continue;\n\n if (sender.track.kind === \"video\") {\n encoding.maxBitrate = this.videoBitrate;\n if (this.maxFramerate && this.maxFramerate > 0) {\n encoding.maxFramerate = this.maxFramerate;\n }\n encoding.scaleResolutionDownBy = 1.0;\n encoding.priority = \"high\";\n encoding.networkPriority = \"high\";\n params.degradationPreference = \"maintain-resolution\";\n } else if (sender.track.kind === \"audio\") {\n encoding.maxBitrate = this.audioBitrate;\n encoding.priority = \"medium\";\n encoding.networkPriority = \"medium\";\n }\n\n try {\n await sender.setParameters(params);\n } catch {\n // Parameters not supported\n }\n }\n }\n\n private waitForIceGathering(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.pc) {\n resolve();\n return;\n }\n\n if (this.pc.iceGatheringState === \"complete\") {\n resolve();\n return;\n }\n\n const onStateChange = () => {\n if (this.pc?.iceGatheringState === \"complete\") {\n this.pc.removeEventListener(\"icegatheringstatechange\", onStateChange);\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n resolve();\n }\n };\n\n this.pc.addEventListener(\"icegatheringstatechange\", onStateChange);\n\n this.iceGatheringTimer = this.timers.setTimeout(() => {\n this.pc?.removeEventListener(\"icegatheringstatechange\", onStateChange);\n this.iceGatheringTimer = null;\n resolve();\n }, 1000);\n });\n }\n\n private startStatsTimer(): void {\n if (!this.onStats || !this.pc) return;\n\n this.stopStatsTimer();\n\n this.statsTimer = this.timers.setInterval(async () => {\n if (!this.pc) return;\n try {\n const report = await this.pc.getStats();\n this.onStats?.(report);\n } catch {\n // Stats collection failed\n }\n }, this.statsIntervalMs);\n }\n\n private stopStatsTimer(): void {\n if (this.statsTimer !== null) {\n this.timers.clearInterval(this.statsTimer);\n this.statsTimer = null;\n }\n }\n\n async replaceTrack(track: MediaStreamTrack): Promise<void> {\n if (!this.pc) {\n throw new ConnectionError(\"Not connected\");\n }\n\n const sender = track.kind === \"video\" ? this.videoSender : this.audioSender;\n if (!sender) {\n throw new ConnectionError(\n `No sender found for track kind: ${track.kind}`,\n );\n }\n\n await sender.replaceTrack(track);\n await this.applyBitrateConstraints();\n }\n\n setMaxFramerate(fps?: number): void {\n this.maxFramerate = fps;\n void this.applyBitrateConstraints();\n }\n\n private cleanup(): void {\n this.stopStatsTimer();\n\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n\n if (this.abortController) {\n try {\n this.abortController.abort();\n } catch {\n // Ignore abort errors\n }\n this.abortController = null;\n }\n\n if (this.pc) {\n try {\n this.pc.getTransceivers().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Ignore stop errors\n }\n });\n } catch {\n // Ignore transceiver errors\n }\n\n try {\n this.pc.close();\n } catch {\n // Ignore close errors\n }\n this.pc = null;\n }\n\n this.videoSender = null;\n this.audioSender = null;\n this.videoTransceiver = null;\n this.audioTransceiver = null;\n }\n\n async disconnect(): Promise<void> {\n if (this.resourceUrl) {\n try {\n await this.fetch(this.resourceUrl, { method: \"DELETE\" });\n } catch {\n // Ignore delete errors\n }\n }\n\n this.cleanup();\n this.resourceUrl = null;\n }\n\n getPeerConnection(): RTCPeerConnection | null {\n return this.pc;\n }\n\n restartIce(): void {\n if (this.pc) {\n try {\n this.pc.restartIce();\n } catch {\n // ICE restart not supported\n }\n }\n }\n\n isConnected(): boolean {\n return this.pc !== null && this.pc.connectionState === \"connected\";\n }\n\n private getUrlWithCachedRedirect(): string {\n const originalUrl = new URL(this.url);\n const playbackIdMatch = originalUrl.pathname.match(PLAYBACK_ID_PATTERN);\n const playbackId = playbackIdMatch?.[2];\n\n const cachedTemplate = this.redirectCache.get(this.url);\n if (!cachedTemplate || !playbackId) {\n return this.url;\n }\n\n const redirectedUrl = new URL(cachedTemplate);\n redirectedUrl.pathname = cachedTemplate.pathname.replace(\n PLAYBACK_ID_PLACEHOLDER,\n playbackId,\n );\n return redirectedUrl.toString();\n }\n\n private cacheRedirectIfNeeded(requestUrl: string, responseUrl: string): void {\n if (requestUrl === responseUrl) return;\n\n try {\n const actualRedirect = new URL(responseUrl);\n const template = new URL(actualRedirect);\n template.pathname = template.pathname.replace(\n PLAYBACK_ID_PATTERN,\n `$1${PLAYBACK_ID_PLACEHOLDER}`,\n );\n this.redirectCache.set(this.url, template);\n } catch {\n // Invalid URL, skip caching\n }\n }\n}\n","export class TypedEventEmitter<EventMap extends { [K in keyof EventMap]: (...args: any[]) => void }> {\n private listeners = new Map<keyof EventMap, Set<(...args: any[]) => void>>();\n\n on<E extends keyof EventMap>(event: E, handler: EventMap[E]): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler);\n return this;\n }\n\n off<E extends keyof EventMap>(event: E, handler: EventMap[E]): this {\n this.listeners.get(event)?.delete(handler);\n return this;\n }\n\n protected emit<E extends keyof EventMap>(\n event: E,\n ...args: Parameters<EventMap[E]>\n ): void {\n this.listeners.get(event)?.forEach((handler) => {\n (handler as (...args: Parameters<EventMap[E]>) => void)(...args);\n });\n }\n\n protected clearListeners(): void {\n this.listeners.clear();\n }\n}\n\n","type TransitionMap<S extends string> = Record<S, S[]>;\n\nexport interface StateMachine<S extends string> {\n readonly current: S;\n can(next: S): boolean;\n transition(next: S): boolean;\n force(next: S): void;\n}\n\nexport function createStateMachine<S extends string>(\n initial: S,\n transitions: TransitionMap<S>,\n onChange?: (from: S, to: S) => void,\n): StateMachine<S> {\n let current = initial;\n\n return {\n get current() {\n return current;\n },\n can(next: S) {\n return transitions[current].includes(next);\n },\n transition(next: S): boolean {\n if (!transitions[current].includes(next)) return false;\n const prev = current;\n current = next;\n onChange?.(prev, next);\n return true;\n },\n force(next: S) {\n const prev = current;\n current = next;\n onChange?.(prev, next);\n },\n };\n}\n","import type {\n BroadcastState,\n BroadcastEventMap,\n BroadcastOptions,\n ReconnectConfig,\n ReconnectInfo,\n DaydreamError,\n} from \"./types\";\nimport { WHIPClient, type WHIPClientConfig } from \"./internal/WHIPClient\";\nimport { ConnectionError } from \"./errors\";\nimport { TypedEventEmitter } from \"./internal/TypedEventEmitter\";\nimport { createStateMachine, type StateMachine } from \"./internal/StateMachine\";\n\nconst BROADCAST_TRANSITIONS: Record<BroadcastState, BroadcastState[]> = {\n connecting: [\"live\", \"error\"],\n live: [\"reconnecting\", \"ended\"],\n reconnecting: [\"live\", \"ended\"],\n ended: [],\n error: [\"connecting\"],\n};\n\nexport interface BroadcastConfig {\n whipUrl: string;\n stream: MediaStream;\n reconnect?: ReconnectConfig;\n whipConfig?: Partial<WHIPClientConfig>;\n}\n\nexport class Broadcast extends TypedEventEmitter<BroadcastEventMap> {\n private _whepUrl: string | null = null;\n private readonly stateMachine: StateMachine<BroadcastState>;\n private currentStream: MediaStream;\n private readonly reconnectConfig: ReconnectConfig;\n private readonly whipClient: WHIPClient;\n\n private reconnectAttempts = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n private disconnectedGraceTimeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: BroadcastConfig) {\n super();\n this.currentStream = config.stream;\n this.reconnectConfig = {\n enabled: config.reconnect?.enabled ?? true,\n maxAttempts: config.reconnect?.maxAttempts ?? 5,\n baseDelayMs: config.reconnect?.baseDelayMs ?? 1000,\n };\n\n this.whipClient = new WHIPClient({\n url: config.whipUrl,\n ...config.whipConfig,\n });\n\n this.stateMachine = createStateMachine<BroadcastState>(\n \"connecting\",\n BROADCAST_TRANSITIONS,\n (_from, to) => this.emit(\"stateChange\", to),\n );\n }\n\n get state(): BroadcastState {\n return this.stateMachine.current;\n }\n\n get whepUrl(): string | null {\n return this._whepUrl;\n }\n\n get stream(): MediaStream {\n return this.currentStream;\n }\n\n get reconnectInfo(): ReconnectInfo | null {\n if (this.state !== \"reconnecting\") return null;\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 1000;\n const delay = baseDelay * Math.pow(2, this.reconnectAttempts - 1);\n return {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 5,\n delayMs: delay,\n };\n }\n\n async connect(): Promise<void> {\n try {\n const result = await this.whipClient.connect(this.currentStream);\n if (result.whepUrl) {\n this._whepUrl = result.whepUrl;\n }\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"live\");\n } catch (error) {\n this.stateMachine.transition(\"error\");\n const daydreamError =\n error instanceof Error\n ? error\n : new ConnectionError(\"Failed to connect\", error);\n this.emit(\"error\", daydreamError as DaydreamError);\n throw daydreamError;\n }\n }\n\n async stop(): Promise<void> {\n this.stateMachine.force(\"ended\");\n this.clearTimeouts();\n\n await this.whipClient.disconnect();\n this.clearListeners();\n }\n\n setMaxFramerate(fps?: number): void {\n this.whipClient.setMaxFramerate(fps);\n }\n\n async replaceStream(newStream: MediaStream): Promise<void> {\n if (!this.whipClient.isConnected()) {\n this.currentStream = newStream;\n return;\n }\n\n const videoTrack = newStream.getVideoTracks()[0];\n const audioTrack = newStream.getAudioTracks()[0];\n\n try {\n if (videoTrack) {\n await this.whipClient.replaceTrack(videoTrack);\n }\n if (audioTrack) {\n await this.whipClient.replaceTrack(audioTrack);\n }\n this.currentStream = newStream;\n } catch {\n this.currentStream = newStream;\n this.scheduleReconnect();\n }\n }\n\n private setupConnectionMonitoring(): void {\n const pc = this.whipClient.getPeerConnection();\n if (!pc) return;\n\n pc.onconnectionstatechange = () => {\n if (this.state === \"ended\") return;\n\n const connState = pc.connectionState;\n\n if (connState === \"connected\") {\n this.clearGraceTimeout();\n if (this.state === \"reconnecting\") {\n this.stateMachine.transition(\"live\");\n this.reconnectAttempts = 0;\n }\n return;\n }\n\n if (connState === \"disconnected\") {\n this.clearGraceTimeout();\n this.whipClient.restartIce();\n\n this.disconnectedGraceTimeout = setTimeout(() => {\n if (this.state === \"ended\") return;\n const currentState = pc.connectionState;\n if (currentState === \"disconnected\") {\n this.scheduleReconnect();\n }\n }, 2000);\n return;\n }\n\n if (connState === \"failed\" || connState === \"closed\") {\n this.clearGraceTimeout();\n this.scheduleReconnect();\n }\n };\n }\n\n private clearGraceTimeout(): void {\n if (this.disconnectedGraceTimeout) {\n clearTimeout(this.disconnectedGraceTimeout);\n this.disconnectedGraceTimeout = null;\n }\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n }\n\n private clearTimeouts(): void {\n this.clearGraceTimeout();\n this.clearReconnectTimeout();\n }\n\n private scheduleReconnect(): void {\n if (this.state === \"ended\") return;\n\n if (!this.reconnectConfig.enabled) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n const maxAttempts = this.reconnectConfig.maxAttempts ?? 5;\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n this.clearReconnectTimeout();\n this.stateMachine.transition(\"reconnecting\");\n\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 1000;\n const delay = baseDelay * Math.pow(2, this.reconnectAttempts);\n this.reconnectAttempts++;\n\n this.emit(\"reconnect\", {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 5,\n delayMs: delay,\n });\n\n this.reconnectTimeout = setTimeout(async () => {\n if (this.state === \"ended\") return;\n\n try {\n await this.whipClient.disconnect();\n const result = await this.whipClient.connect(this.currentStream);\n if (result.whepUrl) {\n this._whepUrl = result.whepUrl;\n }\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"live\");\n this.reconnectAttempts = 0;\n } catch {\n this.scheduleReconnect();\n }\n }, delay);\n }\n}\n\nexport function createBroadcast(options: BroadcastOptions): Broadcast {\n const {\n whipUrl,\n stream,\n reconnect,\n video,\n audio,\n iceServers,\n connectionTimeout,\n onStats,\n statsIntervalMs,\n onResponse,\n } = options;\n\n return new Broadcast({\n whipUrl,\n stream,\n reconnect,\n whipConfig: {\n iceServers,\n videoBitrate: video?.bitrate,\n audioBitrate: audio?.bitrate,\n maxFramerate: video?.maxFramerate,\n connectionTimeout,\n onStats,\n statsIntervalMs,\n onResponse,\n },\n });\n}\n","import { DEFAULT_ICE_SERVERS } from \"../types\";\nimport { ConnectionError, NetworkError } from \"../errors\";\nimport {\n type PeerConnectionFactory,\n type FetchFn,\n type TimerProvider,\n type MediaStreamFactory,\n defaultPeerConnectionFactory,\n defaultFetch,\n defaultTimerProvider,\n defaultMediaStreamFactory,\n} from \"./dependencies\";\n\nexport interface WHEPClientConfig {\n url: string;\n iceServers?: RTCIceServer[];\n connectionTimeout?: number;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n peerConnectionFactory?: PeerConnectionFactory;\n fetch?: FetchFn;\n timers?: TimerProvider;\n mediaStreamFactory?: MediaStreamFactory;\n}\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nexport class WHEPClient {\n private readonly url: string;\n private readonly iceServers: RTCIceServer[];\n private readonly connectionTimeout: number;\n private readonly onStats?: (report: RTCStatsReport) => void;\n private readonly statsIntervalMs: number;\n private readonly pcFactory: PeerConnectionFactory;\n private readonly fetch: FetchFn;\n private readonly timers: TimerProvider;\n private readonly mediaStreamFactory: MediaStreamFactory;\n\n private pc: RTCPeerConnection | null = null;\n private resourceUrl: string | null = null;\n private stream: MediaStream | null = null;\n private abortController: AbortController | null = null;\n private statsTimer: number | null = null;\n private iceGatheringTimer: number | null = null;\n\n constructor(config: WHEPClientConfig) {\n this.url = config.url;\n this.iceServers = config.iceServers ?? DEFAULT_ICE_SERVERS;\n this.connectionTimeout = config.connectionTimeout ?? DEFAULT_CONNECTION_TIMEOUT;\n this.onStats = config.onStats;\n this.statsIntervalMs = config.statsIntervalMs ?? 5000;\n this.pcFactory =\n config.peerConnectionFactory ?? defaultPeerConnectionFactory;\n this.fetch = config.fetch ?? defaultFetch;\n this.timers = config.timers ?? defaultTimerProvider;\n this.mediaStreamFactory =\n config.mediaStreamFactory ?? defaultMediaStreamFactory;\n }\n\n async connect(): Promise<MediaStream> {\n this.cleanup();\n\n this.pc = this.pcFactory.create({\n iceServers: this.iceServers,\n });\n\n this.pc.addTransceiver(\"video\", { direction: \"recvonly\" });\n this.pc.addTransceiver(\"audio\", { direction: \"recvonly\" });\n\n this.stream = this.mediaStreamFactory.create();\n\n this.pc.ontrack = (event) => {\n const [remoteStream] = event.streams;\n if (remoteStream) {\n this.stream = remoteStream;\n } else if (this.stream) {\n this.stream.addTrack(event.track);\n }\n };\n\n const offer = await this.pc.createOffer();\n await this.pc.setLocalDescription(offer);\n\n await this.waitForIceGathering();\n\n this.abortController = new AbortController();\n const timeoutId = this.timers.setTimeout(\n () => this.abortController?.abort(),\n this.connectionTimeout,\n );\n\n try {\n const response = await this.fetch(this.url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/sdp\" },\n body: this.pc.localDescription!.sdp,\n signal: this.abortController.signal,\n });\n\n this.timers.clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new ConnectionError(\n `WHEP connection failed: ${response.status} ${response.statusText} ${errorText}`,\n );\n }\n\n const location = response.headers.get(\"location\");\n if (location) {\n this.resourceUrl = new URL(location, this.url).toString();\n }\n\n const answerSdp = await response.text();\n await this.pc.setRemoteDescription({ type: \"answer\", sdp: answerSdp });\n\n this.startStatsTimer();\n\n return this.stream;\n } catch (error) {\n this.timers.clearTimeout(timeoutId);\n if (error instanceof ConnectionError) {\n throw error;\n }\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new NetworkError(\"Connection timeout\");\n }\n throw new NetworkError(\"Failed to establish connection\", error);\n }\n }\n\n private waitForIceGathering(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.pc) {\n resolve();\n return;\n }\n\n if (this.pc.iceGatheringState === \"complete\") {\n resolve();\n return;\n }\n\n const onStateChange = () => {\n if (this.pc?.iceGatheringState === \"complete\") {\n this.pc.removeEventListener(\"icegatheringstatechange\", onStateChange);\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n resolve();\n }\n };\n\n this.pc.addEventListener(\"icegatheringstatechange\", onStateChange);\n\n this.iceGatheringTimer = this.timers.setTimeout(() => {\n this.pc?.removeEventListener(\"icegatheringstatechange\", onStateChange);\n this.iceGatheringTimer = null;\n resolve();\n }, 1000);\n });\n }\n\n private startStatsTimer(): void {\n if (!this.onStats || !this.pc) return;\n\n this.stopStatsTimer();\n\n this.statsTimer = this.timers.setInterval(async () => {\n if (!this.pc) return;\n try {\n const report = await this.pc.getStats();\n this.onStats?.(report);\n } catch {\n // Stats collection failed\n }\n }, this.statsIntervalMs);\n }\n\n private stopStatsTimer(): void {\n if (this.statsTimer !== null) {\n this.timers.clearInterval(this.statsTimer);\n this.statsTimer = null;\n }\n }\n\n private cleanup(): void {\n this.stopStatsTimer();\n\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n\n if (this.abortController) {\n try {\n this.abortController.abort();\n } catch {\n // Ignore abort errors\n }\n this.abortController = null;\n }\n\n if (this.pc) {\n try {\n this.pc.getTransceivers().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Ignore stop errors\n }\n });\n } catch {\n // Ignore transceiver errors\n }\n\n try {\n this.pc.close();\n } catch {\n // Ignore close errors\n }\n this.pc = null;\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.resourceUrl) {\n try {\n await this.fetch(this.resourceUrl, { method: \"DELETE\" });\n } catch {\n // Ignore delete errors\n }\n }\n\n this.cleanup();\n this.stream = null;\n this.resourceUrl = null;\n }\n\n getStream(): MediaStream | null {\n return this.stream;\n }\n\n getPeerConnection(): RTCPeerConnection | null {\n return this.pc;\n }\n\n restartIce(): void {\n if (this.pc) {\n try {\n this.pc.restartIce();\n } catch {\n // ICE restart not supported\n }\n }\n }\n}\n","import type {\n PlayerState,\n PlayerEventMap,\n PlayerOptions,\n ReconnectConfig,\n ReconnectInfo,\n DaydreamError,\n} from \"./types\";\nimport { WHEPClient, type WHEPClientConfig } from \"./internal/WHEPClient\";\nimport { ConnectionError } from \"./errors\";\nimport { TypedEventEmitter } from \"./internal/TypedEventEmitter\";\nimport { createStateMachine, type StateMachine } from \"./internal/StateMachine\";\n\nconst PLAYER_TRANSITIONS: Record<PlayerState, PlayerState[]> = {\n connecting: [\"playing\", \"buffering\", \"error\"],\n playing: [\"buffering\", \"ended\"],\n buffering: [\"playing\", \"ended\"],\n ended: [],\n error: [\"connecting\"],\n};\n\nexport interface PlayerConfig {\n whepUrl: string;\n reconnect?: ReconnectConfig;\n whepConfig?: Partial<WHEPClientConfig>;\n}\n\nexport class Player extends TypedEventEmitter<PlayerEventMap> {\n private readonly stateMachine: StateMachine<PlayerState>;\n private _stream: MediaStream | null = null;\n private readonly whepUrl: string;\n private readonly reconnectConfig: ReconnectConfig;\n private readonly whepConfig: Partial<WHEPClientConfig> | undefined;\n private whepClient: WHEPClient;\n\n private reconnectAttempts = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n private disconnectedGraceTimeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: PlayerConfig) {\n super();\n this.whepUrl = config.whepUrl;\n this.whepConfig = config.whepConfig;\n this.reconnectConfig = {\n enabled: config.reconnect?.enabled ?? true,\n maxAttempts: config.reconnect?.maxAttempts ?? 30,\n baseDelayMs: config.reconnect?.baseDelayMs ?? 200,\n };\n\n this.whepClient = new WHEPClient({\n url: config.whepUrl,\n ...this.whepConfig,\n });\n\n this.stateMachine = createStateMachine<PlayerState>(\n \"connecting\",\n PLAYER_TRANSITIONS,\n (_from, to) => this.emit(\"stateChange\", to),\n );\n }\n\n get state(): PlayerState {\n return this.stateMachine.current;\n }\n\n get stream(): MediaStream | null {\n return this._stream;\n }\n\n get reconnectInfo(): ReconnectInfo | null {\n if (this.state !== \"buffering\") return null;\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 200;\n const delay = this.calculateReconnectDelay(this.reconnectAttempts - 1, baseDelay);\n return {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 30,\n delayMs: delay,\n };\n }\n\n async connect(): Promise<void> {\n try {\n this._stream = await this.whepClient.connect();\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"playing\");\n this.reconnectAttempts = 0;\n } catch (error) {\n if (this.reconnectConfig.enabled && this.reconnectAttempts < (this.reconnectConfig.maxAttempts ?? 30)) {\n this.scheduleReconnect();\n return;\n }\n this.stateMachine.transition(\"error\");\n const daydreamError =\n error instanceof Error\n ? error\n : new ConnectionError(\"Failed to connect\", error);\n this.emit(\"error\", daydreamError as DaydreamError);\n throw daydreamError;\n }\n }\n\n attachTo(video: HTMLVideoElement): void {\n if (this._stream) {\n video.srcObject = this._stream;\n }\n }\n\n async stop(): Promise<void> {\n this.stateMachine.force(\"ended\");\n this.clearTimeouts();\n\n await this.whepClient.disconnect();\n this._stream = null;\n this.clearListeners();\n }\n\n private setupConnectionMonitoring(): void {\n const pc = this.whepClient.getPeerConnection();\n if (!pc) return;\n\n pc.oniceconnectionstatechange = () => {\n if (this.state === \"ended\") return;\n\n const iceState = pc.iceConnectionState;\n\n if (iceState === \"connected\" || iceState === \"completed\") {\n this.clearGraceTimeout();\n if (this.state === \"buffering\") {\n this.stateMachine.transition(\"playing\");\n this.reconnectAttempts = 0;\n }\n return;\n }\n\n if (iceState === \"disconnected\") {\n this.clearGraceTimeout();\n this.whepClient.restartIce();\n\n this.disconnectedGraceTimeout = setTimeout(() => {\n if (this.state === \"ended\") return;\n const currentState = pc.iceConnectionState;\n if (currentState === \"disconnected\") {\n this.scheduleReconnect();\n }\n }, 2000);\n return;\n }\n\n if (iceState === \"failed\" || iceState === \"closed\") {\n this.clearGraceTimeout();\n this.scheduleReconnect();\n }\n };\n }\n\n private clearGraceTimeout(): void {\n if (this.disconnectedGraceTimeout) {\n clearTimeout(this.disconnectedGraceTimeout);\n this.disconnectedGraceTimeout = null;\n }\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n }\n\n private clearTimeouts(): void {\n this.clearGraceTimeout();\n this.clearReconnectTimeout();\n }\n\n private scheduleReconnect(): void {\n if (this.state === \"ended\") return;\n\n if (!this.reconnectConfig.enabled) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n const maxAttempts = this.reconnectConfig.maxAttempts ?? 10;\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n this.clearReconnectTimeout();\n this.stateMachine.transition(\"buffering\");\n\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 300;\n const delay = this.calculateReconnectDelay(\n this.reconnectAttempts,\n baseDelay,\n );\n this.reconnectAttempts++;\n\n this.emit(\"reconnect\", {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 30,\n delayMs: delay,\n });\n\n this.reconnectTimeout = setTimeout(async () => {\n if (this.state === \"ended\") return;\n\n try {\n await this.whepClient.disconnect();\n this.whepClient = new WHEPClient({\n url: this.whepUrl,\n ...this.whepConfig,\n });\n this._stream = await this.whepClient.connect();\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"playing\");\n this.reconnectAttempts = 0;\n } catch {\n this.scheduleReconnect();\n }\n }, delay);\n }\n\n private calculateReconnectDelay(attempt: number, baseDelay: number): number {\n const linearPhaseEndCount = 10;\n const maxDelay = 60000;\n\n if (attempt === 0) return 0;\n if (attempt <= linearPhaseEndCount) return baseDelay;\n\n const exponentialAttempt = attempt - linearPhaseEndCount;\n const delay = 500 * Math.pow(2, exponentialAttempt - 1);\n return Math.min(delay, maxDelay);\n }\n}\n\nexport function createPlayer(whepUrl: string, options?: PlayerOptions): Player {\n return new Player({\n whepUrl,\n reconnect: options?.reconnect,\n whepConfig: {\n iceServers: options?.iceServers,\n connectionTimeout: options?.connectionTimeout,\n onStats: options?.onStats,\n statsIntervalMs: options?.statsIntervalMs,\n },\n });\n}\n","import type { Source } from \"../../types\";\n\nexport type RegistryEntry = {\n id: string;\n source: Source;\n registeredAt: number;\n};\n\nexport type RegistryEvents = {\n onRegister?: (id: string, source: Source) => void;\n onUnregister?: (id: string) => void;\n};\n\nexport interface SourceRegistry {\n register(id: string, source: Source): void;\n unregister(id: string): Source | undefined;\n get(id: string): Source | undefined;\n has(id: string): boolean;\n list(): Array<{ id: string; source: Source }>;\n clear(): void;\n}\n\nexport function createRegistry(events?: RegistryEvents): SourceRegistry {\n const sources = new Map<string, RegistryEntry>();\n\n return {\n register(id: string, source: Source): void {\n if (!id) throw new Error(\"Source id is required\");\n if (!source) throw new Error(\"Source is required\");\n\n sources.set(id, {\n id,\n source,\n registeredAt: Date.now(),\n });\n\n events?.onRegister?.(id, source);\n },\n\n unregister(id: string): Source | undefined {\n const entry = sources.get(id);\n if (!entry) return undefined;\n\n sources.delete(id);\n events?.onUnregister?.(id);\n\n return entry.source;\n },\n\n get(id: string): Source | undefined {\n return sources.get(id)?.source;\n },\n\n has(id: string): boolean {\n return sources.has(id);\n },\n\n list(): Array<{ id: string; source: Source }> {\n return Array.from(sources.values()).map((entry) => ({\n id: entry.id,\n source: entry.source,\n }));\n },\n\n clear(): void {\n const ids = Array.from(sources.keys());\n sources.clear();\n ids.forEach((id) => events?.onUnregister?.(id));\n },\n };\n}\n","import type { Ctx2D, FitMode, Size, Source } from \"../../types\";\n\nexport interface RendererOptions {\n width: number;\n height: number;\n dpr: number;\n crossfadeMs: number;\n keepalive: boolean;\n}\n\nexport interface Renderer {\n readonly captureCanvas: HTMLCanvasElement;\n readonly offscreenCtx: Ctx2D;\n readonly size: Size;\n\n setActiveSource(source: Source | null): (() => void) | void;\n renderFrame(timestamp: number): void;\n resize(width: number, height: number, dpr: number): void;\n setCrossfadeMs(ms: number): void;\n setKeepalive(enabled: boolean): void;\n isSourceReady(source: Source): boolean;\n destroy(): void;\n}\n\ntype RectCache = {\n canvasW: number;\n canvasH: number;\n sourceW: number;\n sourceH: number;\n dx: number;\n dy: number;\n dw: number;\n dh: number;\n fit: FitMode;\n};\n\nexport function createRenderer(options: RendererOptions): Renderer {\n let size: Size = {\n width: options.width,\n height: options.height,\n dpr: Math.min(2, options.dpr),\n };\n let crossfadeMs = options.crossfadeMs;\n let keepalive = options.keepalive;\n\n // Canvases\n let captureCanvas: HTMLCanvasElement | null = null;\n let captureCtx: Ctx2D | null = null;\n let offscreen: OffscreenCanvas | HTMLCanvasElement | null = null;\n let offscreenCtx: Ctx2D | null = null;\n // Secondary canvas for crossfade blending (custom sources)\n let crossfadeCanvas: OffscreenCanvas | HTMLCanvasElement | null = null;\n let crossfadeCtx: Ctx2D | null = null;\n\n // Source state\n let currentSource: Source | null = null;\n let pendingSource: Source | null = null;\n let crossfadeStart: number | null = null;\n let cleanupFn: (() => void) | void = undefined;\n\n // Rendering state\n let frameIndex = 0;\n let rectCache = new WeakMap<\n HTMLCanvasElement | HTMLVideoElement,\n RectCache\n >();\n\n function initCanvas(): void {\n const canvas = document.createElement(\"canvas\");\n canvas.style.display = \"none\";\n\n const pxW = Math.round(size.width * size.dpr);\n const pxH = Math.round(size.height * size.dpr);\n const outW = Math.round(size.width);\n const outH = Math.round(size.height);\n\n canvas.width = outW;\n canvas.height = outH;\n\n const ctx = canvas.getContext(\"2d\", {\n alpha: false,\n desynchronized: true,\n }) as Ctx2D | null;\n\n if (!ctx) throw new Error(\"2D context not available\");\n\n captureCanvas = canvas;\n captureCtx = ctx;\n\n // Create offscreen canvas for DPR scaling\n try {\n const off = new OffscreenCanvas(pxW, pxH);\n offscreen = off;\n const offCtx = off.getContext(\"2d\", { alpha: false }) as Ctx2D | null;\n if (!offCtx) throw new Error(\"2D context not available for Offscreen\");\n offCtx.imageSmoothingEnabled = true;\n offscreenCtx = offCtx;\n } catch {\n // Fallback to HTMLCanvasElement\n const off = document.createElement(\"canvas\");\n off.width = pxW;\n off.height = pxH;\n const offCtx = off.getContext(\"2d\", { alpha: false }) as Ctx2D | null;\n if (!offCtx)\n throw new Error(\"2D context not available for Offscreen fallback\");\n offCtx.imageSmoothingEnabled = true;\n offscreen = off;\n offscreenCtx = offCtx;\n }\n\n // Create crossfade canvas for blending custom sources\n try {\n const cfCanvas = new OffscreenCanvas(pxW, pxH);\n crossfadeCanvas = cfCanvas;\n const cfCtx = cfCanvas.getContext(\"2d\", { alpha: true }) as Ctx2D | null;\n if (cfCtx) {\n cfCtx.imageSmoothingEnabled = true;\n crossfadeCtx = cfCtx;\n }\n } catch {\n const cfCanvas = document.createElement(\"canvas\");\n cfCanvas.width = pxW;\n cfCanvas.height = pxH;\n const cfCtx = cfCanvas.getContext(\"2d\", { alpha: true }) as Ctx2D | null;\n if (cfCtx) {\n cfCtx.imageSmoothingEnabled = true;\n crossfadeCanvas = cfCanvas;\n crossfadeCtx = cfCtx;\n }\n }\n\n // Initial fill\n offscreenCtx!.fillStyle = \"#111\";\n offscreenCtx!.fillRect(0, 0, pxW, pxH);\n captureCtx!.drawImage(\n offscreen as CanvasImageSource,\n 0,\n 0,\n pxW,\n pxH,\n 0,\n 0,\n outW,\n outH,\n );\n }\n\n function isSourceReady(source: Source): boolean {\n if (source.kind === \"video\") {\n const v = source.element;\n return (\n typeof v.readyState === \"number\" &&\n v.readyState >= 2 &&\n (v.videoWidth || 0) > 0 &&\n (v.videoHeight || 0) > 0\n );\n }\n if (source.kind === \"canvas\") {\n const c = source.element;\n return (c.width || 0) > 0 && (c.height || 0) > 0;\n }\n return true; // custom sources are always ready\n }\n\n function getDrawRect(\n el: HTMLCanvasElement | HTMLVideoElement,\n fit: FitMode,\n ): { dx: number; dy: number; dw: number; dh: number } | null {\n const canvas = offscreenCtx?.canvas;\n if (!canvas) return null;\n\n const canvasW = canvas.width;\n const canvasH = canvas.height;\n const sourceW = (el as HTMLVideoElement).videoWidth ?? el.width;\n const sourceH = (el as HTMLVideoElement).videoHeight ?? el.height;\n\n if (!sourceW || !sourceH) return null;\n\n const cached = rectCache.get(el);\n if (\n cached &&\n cached.canvasW === canvasW &&\n cached.canvasH === canvasH &&\n cached.sourceW === sourceW &&\n cached.sourceH === sourceH &&\n cached.fit === fit\n ) {\n return { dx: cached.dx, dy: cached.dy, dw: cached.dw, dh: cached.dh };\n }\n\n const scale =\n fit === \"cover\"\n ? Math.max(canvasW / sourceW, canvasH / sourceH)\n : Math.min(canvasW / sourceW, canvasH / sourceH);\n\n const dw = Math.floor(sourceW * scale);\n const dh = Math.floor(sourceH * scale);\n const dx = Math.floor((canvasW - dw) / 2);\n const dy = Math.floor((canvasH - dh) / 2);\n\n rectCache.set(el, {\n canvasW,\n canvasH,\n sourceW,\n sourceH,\n dx,\n dy,\n dw,\n dh,\n fit,\n });\n\n return { dx, dy, dw, dh };\n }\n\n function blitSource(source: Source, alpha: number, timestamp: number): void {\n if (!offscreenCtx) return;\n const ctx = offscreenCtx;\n\n if (source.kind === \"custom\") {\n // For custom sources during crossfade, render to secondary canvas then blend\n if (alpha < 1 && crossfadeCtx && crossfadeCanvas) {\n // Clear crossfade canvas\n crossfadeCtx.clearRect(\n 0,\n 0,\n crossfadeCtx.canvas.width,\n crossfadeCtx.canvas.height,\n );\n // Render custom source to crossfade canvas\n if (source.onFrame) source.onFrame(crossfadeCtx, timestamp);\n // Blend onto main canvas with alpha\n const prev = ctx.globalAlpha;\n try {\n ctx.globalAlpha = Math.max(0, Math.min(1, alpha));\n ctx.drawImage(crossfadeCanvas as CanvasImageSource, 0, 0);\n } finally {\n ctx.globalAlpha = prev;\n }\n } else {\n // Full opacity - render directly\n if (source.onFrame) source.onFrame(ctx, timestamp);\n }\n return;\n }\n\n const el = source.element;\n const rect = getDrawRect(el, source.fit ?? \"contain\");\n if (!rect) return;\n\n const prev = ctx.globalAlpha;\n try {\n ctx.globalAlpha = Math.max(0, Math.min(1, alpha));\n ctx.drawImage(\n el as CanvasImageSource,\n rect.dx,\n rect.dy,\n rect.dw,\n rect.dh,\n );\n } finally {\n ctx.globalAlpha = prev;\n }\n }\n\n // Initialize canvas on creation\n initCanvas();\n\n return {\n get captureCanvas(): HTMLCanvasElement {\n return captureCanvas!;\n },\n\n get offscreenCtx(): Ctx2D {\n return offscreenCtx!;\n },\n\n get size(): Size {\n return { ...size };\n },\n\n isSourceReady,\n\n setActiveSource(source: Source | null): (() => void) | void {\n // Cleanup previous custom source\n if (cleanupFn) {\n cleanupFn();\n cleanupFn = undefined;\n }\n\n if (source === null) {\n currentSource = null;\n pendingSource = null;\n crossfadeStart = null;\n return;\n }\n\n pendingSource = source;\n crossfadeStart = null;\n\n // Initialize custom source\n if (source.kind === \"custom\" && source.onStart) {\n const cleanup = source.onStart(offscreenCtx!);\n cleanupFn = cleanup || undefined;\n return cleanupFn;\n }\n },\n\n renderFrame(timestamp: number): void {\n const off = offscreenCtx;\n const cap = captureCtx;\n const capCanvas = captureCanvas;\n if (!off || !cap || !capCanvas) return;\n\n // Check if pending source is ready to start crossfade\n if (pendingSource && isSourceReady(pendingSource)) {\n if (crossfadeStart === null) crossfadeStart = timestamp;\n }\n\n off.globalCompositeOperation = \"source-over\";\n\n const willDraw = !!(\n (pendingSource && isSourceReady(pendingSource)) ||\n currentSource\n );\n\n if (willDraw) {\n off.fillStyle = \"#000\";\n off.fillRect(0, 0, off.canvas.width, off.canvas.height);\n }\n\n // Handle crossfade\n const fading = pendingSource && crossfadeStart !== null && currentSource;\n if (fading) {\n const t = Math.min(1, (timestamp - crossfadeStart!) / crossfadeMs);\n blitSource(currentSource!, 1 - t, timestamp);\n blitSource(pendingSource!, t, timestamp);\n\n if (t >= 1) {\n currentSource = pendingSource;\n pendingSource = null;\n crossfadeStart = null;\n }\n } else if (pendingSource && !currentSource) {\n if (isSourceReady(pendingSource)) {\n blitSource(pendingSource, 1, timestamp);\n currentSource = pendingSource;\n pendingSource = null;\n crossfadeStart = null;\n }\n } else if (currentSource) {\n blitSource(currentSource, 1, timestamp);\n }\n\n // Keepalive pixel flicker\n if (keepalive) {\n const w = off.canvas.width;\n const h = off.canvas.height;\n const prevAlpha = off.globalAlpha;\n const prevFill = off.fillStyle;\n try {\n off.globalAlpha = 0.08;\n off.fillStyle = frameIndex % 2 ? \"#101010\" : \"#0e0e0e\";\n off.fillRect(w - 16, h - 16, 16, 16);\n } finally {\n off.globalAlpha = prevAlpha;\n off.fillStyle = prevFill;\n }\n }\n\n frameIndex++;\n\n // Blit offscreen to capture canvas\n cap.drawImage(\n off.canvas,\n 0,\n 0,\n off.canvas.width,\n off.canvas.height,\n 0,\n 0,\n capCanvas.width,\n capCanvas.height,\n );\n },\n\n resize(width: number, height: number, dpr: number): void {\n const nextDpr = Math.min(2, dpr);\n if (\n size.width === width &&\n size.height === height &&\n size.dpr === nextDpr\n ) {\n return;\n }\n\n size = { width, height, dpr: nextDpr };\n\n const pxW = Math.round(width * nextDpr);\n const pxH = Math.round(height * nextDpr);\n const outW = Math.round(width);\n const outH = Math.round(height);\n\n if (captureCanvas) {\n captureCanvas.width = outW;\n captureCanvas.height = outH;\n }\n\n if (offscreen instanceof HTMLCanvasElement) {\n offscreen.width = pxW;\n offscreen.height = pxH;\n } else if (offscreen instanceof OffscreenCanvas) {\n offscreen.width = pxW;\n offscreen.height = pxH;\n }\n\n if (crossfadeCanvas instanceof HTMLCanvasElement) {\n crossfadeCanvas.width = pxW;\n crossfadeCanvas.height = pxH;\n } else if (crossfadeCanvas instanceof OffscreenCanvas) {\n crossfadeCanvas.width = pxW;\n crossfadeCanvas.height = pxH;\n }\n\n rectCache = new WeakMap();\n },\n\n setCrossfadeMs(ms: number): void {\n crossfadeMs = Math.max(0, ms);\n },\n\n setKeepalive(enabled: boolean): void {\n keepalive = enabled;\n },\n\n destroy(): void {\n if (cleanupFn) {\n cleanupFn();\n cleanupFn = undefined;\n }\n currentSource = null;\n pendingSource = null;\n captureCanvas = null;\n captureCtx = null;\n offscreen = null;\n offscreenCtx = null;\n crossfadeCanvas = null;\n crossfadeCtx = null;\n },\n };\n}\n","export interface SchedulerOptions {\n fps: number;\n sendFps: number;\n onFrame: (timestamp: number) => void;\n onSendFpsChange?: (fps: number) => void;\n}\n\nexport interface Scheduler {\n start(videoElement?: HTMLVideoElement): void;\n stop(): void;\n setFps(fps: number): void;\n setSendFps(fps: number): void;\n readonly isRunning: boolean;\n readonly fps: number;\n readonly sendFps: number;\n}\n\nexport function createScheduler(options: SchedulerOptions): Scheduler {\n let fps = Math.max(1, options.fps);\n let sendFps = Math.max(1, options.sendFps);\n const onFrame = options.onFrame;\n const onSendFpsChange = options.onSendFpsChange;\n\n let isRunning = false;\n let lastFrameAt = 0;\n\n // RAF scheduling\n let rafId: number | null = null;\n let rafFallbackActive = false;\n\n // Video frame callback scheduling\n let videoFrameRequestId: number | null = null;\n let videoFrameSource: HTMLVideoElement | null = null;\n\n function getTimestamp(): number {\n return typeof performance !== \"undefined\" ? performance.now() : Date.now();\n }\n\n function shouldRenderFrame(): boolean {\n const now = getTimestamp();\n const minIntervalMs = 1000 / Math.max(1, sendFps);\n if (lastFrameAt !== 0 && now - lastFrameAt < minIntervalMs) {\n return false;\n }\n return true;\n }\n\n function renderIfNeeded(): void {\n if (!shouldRenderFrame()) return;\n const timestamp = getTimestamp();\n onFrame(timestamp);\n lastFrameAt = timestamp;\n }\n\n function scheduleWithRaf(isFallback: boolean): void {\n if (isFallback) {\n if (rafFallbackActive) return;\n rafFallbackActive = true;\n }\n\n const loop = (): void => {\n renderIfNeeded();\n rafId = requestAnimationFrame(loop);\n };\n\n rafId = requestAnimationFrame(loop);\n }\n\n function scheduleWithVideoFrame(videoEl: HTMLVideoElement): void {\n if (typeof videoEl.requestVideoFrameCallback !== \"function\") {\n scheduleWithRaf(false);\n return;\n }\n\n videoFrameSource = videoEl;\n\n const cb = (): void => {\n renderIfNeeded();\n if (videoFrameSource === videoEl) {\n try {\n videoFrameRequestId = videoEl.requestVideoFrameCallback(cb);\n } catch {\n // Failed to request video frame callback\n }\n }\n };\n\n try {\n videoFrameRequestId = videoEl.requestVideoFrameCallback(cb);\n } catch {\n // Failed to start video frame callback\n }\n\n // Also schedule RAF as fallback for non-video frames\n scheduleWithRaf(true);\n }\n\n function cancelSchedulers(): void {\n if (rafId != null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n rafFallbackActive = false;\n\n if (videoFrameRequestId && videoFrameSource) {\n try {\n if (typeof videoFrameSource.cancelVideoFrameCallback === \"function\") {\n videoFrameSource.cancelVideoFrameCallback(videoFrameRequestId);\n }\n } catch {\n // Failed to cancel video frame callback\n }\n }\n videoFrameRequestId = null;\n videoFrameSource = null;\n }\n\n return {\n get isRunning(): boolean {\n return isRunning;\n },\n\n get fps(): number {\n return fps;\n },\n\n get sendFps(): number {\n return sendFps;\n },\n\n start(videoElement?: HTMLVideoElement): void {\n if (isRunning) {\n cancelSchedulers();\n }\n\n isRunning = true;\n lastFrameAt = 0;\n\n if (\n videoElement &&\n typeof videoElement.requestVideoFrameCallback === \"function\"\n ) {\n scheduleWithVideoFrame(videoElement);\n } else {\n scheduleWithRaf(false);\n }\n },\n\n stop(): void {\n isRunning = false;\n cancelSchedulers();\n },\n\n setFps(newFps: number): void {\n fps = Math.max(1, newFps);\n },\n\n setSendFps(newSendFps: number): void {\n const next = Math.max(1, newSendFps);\n if (sendFps === next) return;\n sendFps = next;\n onSendFpsChange?.(sendFps);\n },\n };\n}\n","export interface AudioManagerOptions {\n autoUnlock: boolean;\n unlockEvents: string[];\n disableSilentAudio: boolean;\n}\n\nexport interface AudioManager {\n setOutputStream(stream: MediaStream): void;\n addTrack(track: MediaStreamTrack): void;\n removeTrack(trackId: string): void;\n unlock(): Promise<boolean>;\n destroy(): void;\n}\n\ndeclare global {\n interface Window {\n webkitAudioContext?: typeof AudioContext;\n }\n}\n\nexport function createAudioManager(options: AudioManagerOptions): AudioManager {\n let outputStream: MediaStream | null = null;\n\n // Audio context and silent track\n let audioCtx: AudioContext | null = null;\n let silentOsc: OscillatorNode | null = null;\n let silentGain: GainNode | null = null;\n let audioDst: MediaStreamAudioDestinationNode | null = null;\n let silentAudioTrack: MediaStreamTrack | null = null;\n\n // External tracks\n const externalAudioTrackIds = new Set<string>();\n const externalAudioEndHandlers = new Map<string, (ev: Event) => void>();\n\n // Auto unlock\n let audioUnlockHandler: ((ev: Event) => void) | null = null;\n let audioUnlockAttached = false;\n let audioStateListenerAttached = false;\n\n function ensureSilentAudioTrack(): void {\n if (options.disableSilentAudio) return;\n if (!outputStream) return;\n\n const alreadyHasAudio = outputStream.getAudioTracks().length > 0;\n if (alreadyHasAudio) return;\n\n if (silentAudioTrack && silentAudioTrack.readyState === \"live\") {\n try {\n outputStream.addTrack(silentAudioTrack);\n } catch {\n // Failed to add silent track\n }\n return;\n }\n\n if (!audioCtx) {\n const AudioContextClass = window.AudioContext || window.webkitAudioContext;\n if (!AudioContextClass) return;\n\n audioCtx = new AudioContextClass({\n sampleRate: 48000,\n });\n try {\n audioCtx.resume().catch(() => {\n // Failed to resume AudioContext\n });\n } catch {\n // Error calling resume\n }\n attachAudioCtxStateListener();\n }\n\n const ac = audioCtx;\n if (!ac) return;\n\n silentOsc = ac.createOscillator();\n silentGain = ac.createGain();\n audioDst = ac.createMediaStreamDestination();\n\n silentGain.gain.setValueAtTime(0.0001, ac.currentTime);\n silentOsc.frequency.setValueAtTime(440, ac.currentTime);\n silentOsc.type = \"sine\";\n silentOsc.connect(silentGain);\n silentGain.connect(audioDst);\n silentOsc.start();\n\n const track = audioDst.stream.getAudioTracks()[0];\n if (track) {\n silentAudioTrack = track;\n try {\n outputStream.addTrack(track);\n } catch {\n // Failed to add track to stream\n }\n }\n }\n\n function removeSilentAudioTrack(): void {\n try {\n if (outputStream && silentAudioTrack) {\n try {\n outputStream.removeTrack(silentAudioTrack);\n } catch {\n // Failed to remove silent track\n }\n }\n if (silentOsc) {\n try {\n silentOsc.stop();\n } catch {\n // Failed to stop oscillator\n }\n try {\n silentOsc.disconnect();\n } catch {\n // Failed to disconnect oscillator\n }\n }\n if (silentGain) {\n try {\n silentGain.disconnect();\n } catch {\n // Failed to disconnect gain\n }\n }\n silentOsc = null;\n silentGain = null;\n audioDst = null;\n silentAudioTrack = null;\n if (audioCtx) {\n try {\n audioCtx.close();\n } catch {\n // Failed to close AudioContext\n }\n }\n audioCtx = null;\n } catch {\n // Error in removeSilentAudioTrack\n }\n }\n\n function rebuildSilentAudioTrack(): void {\n if (options.disableSilentAudio) return;\n if (!outputStream) return;\n if (externalAudioTrackIds.size > 0) return;\n\n if (silentAudioTrack) {\n try {\n outputStream.removeTrack(silentAudioTrack);\n } catch {\n // Failed to remove silent track\n }\n }\n\n if (silentOsc) {\n try {\n silentOsc.stop();\n } catch {\n // Failed to stop oscillator\n }\n try {\n silentOsc.disconnect();\n } catch {\n // Failed to disconnect oscillator\n }\n }\n if (silentGain) {\n try {\n silentGain.disconnect();\n } catch {\n // Failed to disconnect gain\n }\n }\n silentOsc = null;\n silentGain = null;\n audioDst = null;\n silentAudioTrack = null;\n\n const ac = audioCtx;\n if (!ac || ac.state !== \"running\") return;\n\n attachAudioCtxStateListener();\n\n silentOsc = ac.createOscillator();\n silentGain = ac.createGain();\n audioDst = ac.createMediaStreamDestination();\n\n silentGain.gain.setValueAtTime(0.0001, ac.currentTime);\n silentOsc.frequency.setValueAtTime(440, ac.currentTime);\n silentOsc.type = \"sine\";\n silentOsc.connect(silentGain);\n silentGain.connect(audioDst);\n silentOsc.start();\n\n const track = audioDst.stream.getAudioTracks()[0];\n if (track) {\n silentAudioTrack = track;\n try {\n outputStream.addTrack(track);\n } catch {\n // Failed to add track to stream\n }\n }\n }\n\n function attachAudioCtxStateListener(): void {\n const ac = audioCtx;\n if (!ac || audioStateListenerAttached) return;\n\n const onStateChange = (): void => {\n try {\n if (audioCtx && audioCtx.state === \"running\") {\n rebuildSilentAudioTrack();\n cleanupAudioAutoUnlock();\n }\n } catch {\n // Error in state change handler\n }\n };\n\n try {\n (ac as AudioContext & { onstatechange: (() => void) | null }).onstatechange = onStateChange;\n audioStateListenerAttached = true;\n } catch {\n // Failed to attach state listener\n }\n }\n\n function setupAudioAutoUnlock(): void {\n if (!options.autoUnlock) return;\n if (typeof document === \"undefined\") return;\n if (audioUnlockAttached) return;\n\n const handler = (): void => {\n unlock();\n };\n\n audioUnlockHandler = handler;\n options.unlockEvents.forEach((evt) => {\n try {\n document.addEventListener(evt, handler, { capture: true });\n } catch {\n // Failed to add unlock listener\n }\n });\n audioUnlockAttached = true;\n }\n\n function cleanupAudioAutoUnlock(): void {\n if (!audioUnlockAttached) return;\n if (typeof document !== \"undefined\" && audioUnlockHandler) {\n options.unlockEvents.forEach((evt) => {\n try {\n document.removeEventListener(evt, audioUnlockHandler!, {\n capture: true,\n });\n } catch {\n // Failed to remove unlock listener\n }\n });\n }\n audioUnlockAttached = false;\n audioUnlockHandler = null;\n }\n\n async function unlock(): Promise<boolean> {\n try {\n if (typeof window === \"undefined\") return false;\n\n if (!audioCtx || audioCtx.state === \"closed\") {\n const AudioContextClass = window.AudioContext || window.webkitAudioContext;\n if (!AudioContextClass) return false;\n\n audioCtx = new AudioContextClass({\n sampleRate: 48000,\n });\n }\n\n const ac = audioCtx;\n if (!ac) return false;\n\n try {\n await ac.resume();\n } catch {\n // Failed to resume AudioContext\n }\n\n attachAudioCtxStateListener();\n\n if (ac.state === \"running\") {\n rebuildSilentAudioTrack();\n cleanupAudioAutoUnlock();\n return true;\n }\n\n return false;\n } catch {\n // Error in unlock\n return false;\n }\n }\n\n // Setup auto unlock on creation\n setupAudioAutoUnlock();\n\n return {\n setOutputStream(stream: MediaStream): void {\n outputStream = stream;\n ensureSilentAudioTrack();\n },\n\n addTrack(track: MediaStreamTrack): void {\n if (!outputStream) return;\n\n try {\n // Remove silent track when adding external audio\n if (silentAudioTrack) {\n try {\n outputStream.removeTrack(silentAudioTrack);\n } catch {\n // Failed to remove silent track\n }\n }\n\n const exists = outputStream\n .getAudioTracks()\n .some((t) => t.id === track.id);\n if (!exists) {\n outputStream.addTrack(track);\n }\n externalAudioTrackIds.add(track.id);\n\n // Setup ended handler\n const onEnded = (): void => {\n try {\n if (!outputStream) return;\n outputStream.getAudioTracks().forEach((t) => {\n if (t.id === track.id) {\n try {\n outputStream!.removeTrack(t);\n } catch {\n // Failed to remove ended track\n }\n }\n });\n externalAudioTrackIds.delete(track.id);\n externalAudioEndHandlers.delete(track.id);\n\n if (outputStream.getAudioTracks().length === 0) {\n ensureSilentAudioTrack();\n }\n } catch {\n // Error in track ended handler\n }\n try {\n track.removeEventListener(\"ended\", onEnded);\n } catch {\n // Failed to remove ended listener\n }\n };\n\n track.addEventListener(\"ended\", onEnded);\n externalAudioEndHandlers.set(track.id, onEnded);\n } catch {\n // Error in addTrack\n }\n },\n\n removeTrack(trackId: string): void {\n if (!outputStream) return;\n\n outputStream.getAudioTracks().forEach((t) => {\n if (t.id === trackId) {\n outputStream!.removeTrack(t);\n }\n });\n\n externalAudioTrackIds.delete(trackId);\n\n const handler = externalAudioEndHandlers.get(trackId);\n const tracks = outputStream.getAudioTracks();\n const tr = tracks.find((t) => t.id === trackId);\n if (tr && handler) {\n try {\n tr.removeEventListener(\"ended\", handler);\n } catch {\n // Failed to remove ended listener\n }\n }\n externalAudioEndHandlers.delete(trackId);\n\n if (outputStream.getAudioTracks().length === 0) {\n ensureSilentAudioTrack();\n }\n },\n\n unlock,\n\n destroy(): void {\n cleanupAudioAutoUnlock();\n\n try {\n if (audioCtx && (audioCtx as AudioContext & { onstatechange: (() => void) | null }).onstatechange) {\n (audioCtx as AudioContext & { onstatechange: (() => void) | null }).onstatechange = null;\n }\n } catch {\n // Failed to clear state change handler\n }\n audioStateListenerAttached = false;\n\n // Cleanup external track handlers\n externalAudioEndHandlers.forEach((handler, id) => {\n try {\n const tr = outputStream?.getAudioTracks().find((t) => t.id === id);\n if (tr) tr.removeEventListener(\"ended\", handler);\n } catch {\n // Failed to cleanup track handler\n }\n });\n externalAudioEndHandlers.clear();\n externalAudioTrackIds.clear();\n\n removeSilentAudioTrack();\n outputStream = null;\n },\n };\n}\n","export interface VisibilityHandlerOptions {\n onHidden: () => void;\n onVisible: () => void;\n backgroundRenderFn: () => void;\n}\n\nexport interface VisibilityHandler {\n start(): void;\n stop(): void;\n readonly isHidden: boolean;\n}\n\nexport function createVisibilityHandler(\n options: VisibilityHandlerOptions,\n): VisibilityHandler {\n let isHidden = false;\n let backgroundIntervalId: number | null = null;\n let visibilityListener: (() => void) | null = null;\n let started = false;\n\n function onVisibilityChange(): void {\n if (typeof document === \"undefined\") return;\n\n const hidden = document.visibilityState === \"hidden\";\n\n if (hidden && !isHidden) {\n isHidden = true;\n options.onHidden();\n\n // Start background interval rendering\n if (backgroundIntervalId == null) {\n backgroundIntervalId = setInterval(() => {\n options.backgroundRenderFn();\n }, 1000) as unknown as number;\n }\n } else if (!hidden && isHidden) {\n isHidden = false;\n\n // Stop background interval\n if (backgroundIntervalId != null) {\n clearInterval(backgroundIntervalId);\n backgroundIntervalId = null;\n }\n\n options.onVisible();\n }\n }\n\n return {\n get isHidden(): boolean {\n return isHidden;\n },\n\n start(): void {\n if (started) return;\n if (typeof document === \"undefined\") return;\n\n started = true;\n visibilityListener = onVisibilityChange;\n document.addEventListener(\"visibilitychange\", visibilityListener);\n\n // Check initial state\n onVisibilityChange();\n },\n\n stop(): void {\n if (!started) return;\n started = false;\n\n if (typeof document !== \"undefined\" && visibilityListener) {\n try {\n document.removeEventListener(\"visibilitychange\", visibilityListener);\n } catch {\n // Failed to remove visibility listener\n }\n visibilityListener = null;\n }\n\n if (backgroundIntervalId != null) {\n clearInterval(backgroundIntervalId);\n backgroundIntervalId = null;\n }\n\n isHidden = false;\n },\n };\n}\n","import { createRegistry } from \"./internal/compositor/Registry\";\nimport { createRenderer, type Renderer } from \"./internal/compositor/Renderer\";\nimport { createScheduler, type Scheduler } from \"./internal/compositor/Scheduler\";\nimport { createAudioManager, type AudioManager } from \"./internal/compositor/AudioManager\";\nimport { createVisibilityHandler, type VisibilityHandler } from \"./internal/compositor/VisibilityHandler\";\nimport type {\n Compositor as ICompositor,\n CompositorEvent,\n CompositorEventMap,\n CompositorOptions,\n Size,\n Source,\n} from \"./types\";\nimport type { SourceRegistry } from \"./internal/compositor/Registry\";\n\nclass CompositorEventEmitter {\n private listeners = new Map<CompositorEvent, Set<CompositorEventMap[CompositorEvent]>>();\n\n on<E extends CompositorEvent>(event: E, handler: CompositorEventMap[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as CompositorEventMap[CompositorEvent]);\n return () => this.off(event, handler);\n }\n\n off<E extends CompositorEvent>(event: E, handler: CompositorEventMap[E]): void {\n this.listeners.get(event)?.delete(handler as CompositorEventMap[CompositorEvent]);\n }\n\n protected emit<E extends CompositorEvent>(\n event: E,\n ...args: Parameters<CompositorEventMap[E]>\n ): void {\n this.listeners.get(event)?.forEach((handler) => {\n (handler as (...args: Parameters<CompositorEventMap[E]>) => void)(...args);\n });\n }\n\n protected clearListeners(): void {\n this.listeners.clear();\n }\n}\n\nexport class Compositor extends CompositorEventEmitter implements ICompositor {\n private readonly registry: SourceRegistry;\n private readonly renderer: Renderer;\n private readonly scheduler: Scheduler;\n private readonly audioManager: AudioManager;\n private readonly visibilityHandler: VisibilityHandler;\n\n private _activeId: string | null = null;\n private _fps: number;\n private _sendFps: number;\n private lastVisibleSendFps: number | null = null;\n private outputStream: MediaStream | null = null;\n private destroyed = false;\n\n constructor(options: CompositorOptions = {}) {\n super();\n\n const width = options.width ?? 512;\n const height = options.height ?? 512;\n this._fps = Math.max(1, options.fps ?? 30);\n this._sendFps = Math.max(1, options.sendFps ?? this._fps);\n const dpr = Math.min(\n 2,\n options.dpr ??\n (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1),\n );\n const crossfadeMs = options.crossfadeMs ?? 500;\n const keepalive = options.keepalive ?? true;\n\n // Create subsystems\n this.registry = createRegistry({\n onRegister: (id, source) => this.emit(\"registered\", id, source),\n onUnregister: (id) => this.emit(\"unregistered\", id),\n });\n\n this.renderer = createRenderer({\n width,\n height,\n dpr,\n crossfadeMs,\n keepalive,\n });\n\n this.scheduler = createScheduler({\n fps: this._fps,\n sendFps: this._sendFps,\n onFrame: (timestamp) => this.renderer.renderFrame(timestamp),\n onSendFpsChange: (fps) => {\n this._sendFps = fps;\n options.onSendFpsChange?.(fps);\n this.applyVideoTrackConstraints();\n },\n });\n\n this.audioManager = createAudioManager({\n autoUnlock: options.autoUnlockAudio ?? true,\n unlockEvents:\n options.unlockEvents && options.unlockEvents.length > 0\n ? options.unlockEvents\n : [\"pointerdown\", \"click\", \"touchstart\", \"keydown\"],\n disableSilentAudio: options.disableSilentAudio ?? false,\n });\n\n this.visibilityHandler = createVisibilityHandler({\n onHidden: () => {\n if (this.lastVisibleSendFps == null) this.lastVisibleSendFps = this._sendFps;\n if (this._sendFps !== 5) {\n this.scheduler.setSendFps(5);\n this._sendFps = 5;\n }\n },\n onVisible: () => {\n if (this.lastVisibleSendFps != null && this._sendFps !== this.lastVisibleSendFps) {\n this.scheduler.setSendFps(this.lastVisibleSendFps);\n this._sendFps = this.lastVisibleSendFps;\n }\n this.lastVisibleSendFps = null;\n },\n backgroundRenderFn: () => {\n this.renderer.renderFrame(performance.now());\n this.requestVideoTrackFrame();\n },\n });\n\n // Initialize\n this.outputStream = this.createOutputStream();\n this.audioManager.setOutputStream(this.outputStream);\n this.visibilityHandler.start();\n }\n\n // ============================================================================\n // Source Registry\n // ============================================================================\n\n register(id: string, source: Source): void {\n if (this.destroyed) return;\n this.registry.register(id, source);\n }\n\n unregister(id: string): void {\n if (this.destroyed) return;\n const wasActive = this._activeId === id;\n this.registry.unregister(id);\n\n if (wasActive) {\n this._activeId = null;\n this.renderer.setActiveSource(null);\n this.scheduler.stop();\n this.emit(\"activated\", null, undefined);\n }\n }\n\n get(id: string): Source | undefined {\n return this.registry.get(id);\n }\n\n has(id: string): boolean {\n return this.registry.has(id);\n }\n\n list(): Array<{ id: string; source: Source }> {\n return this.registry.list();\n }\n\n // ============================================================================\n // Active Source Management\n // ============================================================================\n\n activate(id: string): void {\n if (this.destroyed) return;\n\n const source = this.registry.get(id);\n if (!source) {\n throw new Error(`Source \"${id}\" not registered`);\n }\n\n this._activeId = id;\n this.renderer.setActiveSource(source);\n\n // Start scheduler with video element if applicable\n const videoEl = source.kind === \"video\" ? source.element : undefined;\n this.scheduler.start(videoEl);\n\n this.emit(\"activated\", id, source);\n }\n\n deactivate(): void {\n if (this.destroyed) return;\n\n this._activeId = null;\n this.renderer.setActiveSource(null);\n this.scheduler.stop();\n this.emit(\"activated\", null, undefined);\n }\n\n get activeId(): string | null {\n return this._activeId;\n }\n\n // ============================================================================\n // Output Stream\n // ============================================================================\n\n get stream(): MediaStream {\n return this.outputStream!;\n }\n\n // ============================================================================\n // Settings\n // ============================================================================\n\n resize(width: number, height: number, dpr?: number): void {\n if (this.destroyed) return;\n\n const effectiveDpr = Math.min(\n 2,\n dpr ??\n (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1),\n );\n\n this.renderer.resize(width, height, effectiveDpr);\n this.recreateStream();\n }\n\n get size(): Size {\n return this.renderer.size;\n }\n\n setFps(fps: number): void {\n if (this.destroyed) return;\n\n const next = Math.max(1, fps);\n if (this._fps === next) return;\n\n this._fps = next;\n this.scheduler.setFps(next);\n this.recreateStream();\n }\n\n get fps(): number {\n return this._fps;\n }\n\n setSendFps(fps: number): void {\n if (this.destroyed) return;\n\n const next = Math.max(1, fps);\n if (this._sendFps === next) return;\n\n this._sendFps = next;\n this.scheduler.setSendFps(next);\n }\n\n get sendFps(): number {\n return this._sendFps;\n }\n\n // ============================================================================\n // Audio\n // ============================================================================\n\n addAudioTrack(track: MediaStreamTrack): void {\n if (this.destroyed) return;\n this.audioManager.addTrack(track);\n }\n\n removeAudioTrack(trackId: string): void {\n if (this.destroyed) return;\n this.audioManager.removeTrack(trackId);\n }\n\n unlockAudio(): Promise<boolean> {\n if (this.destroyed) return Promise.resolve(false);\n return this.audioManager.unlock();\n }\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n\n this.scheduler.stop();\n this.visibilityHandler.stop();\n this.audioManager.destroy();\n this.renderer.destroy();\n this.registry.clear();\n\n // Stop video tracks\n if (this.outputStream) {\n try {\n this.outputStream.getVideoTracks().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Failed to stop video track\n }\n });\n } catch {\n // Failed to get video tracks\n }\n }\n\n this.outputStream = null;\n this.clearListeners();\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n private createOutputStream(): MediaStream {\n const stream = this.renderer.captureCanvas.captureStream(this._fps);\n\n // Set video track content hint\n try {\n const vtrack = stream.getVideoTracks()[0];\n if (vtrack && vtrack.contentHint !== undefined) {\n vtrack.contentHint = \"detail\";\n }\n } catch {\n // Failed to set video track content hint\n }\n\n return stream;\n }\n\n private recreateStream(): void {\n const newStream = this.createOutputStream();\n const prev = this.outputStream;\n\n // Transfer audio tracks\n if (prev && prev !== newStream) {\n try {\n prev.getAudioTracks().forEach((t) => {\n try {\n newStream.addTrack(t);\n } catch {\n // Failed to transfer audio track\n }\n });\n } catch {\n // Failed to get audio tracks\n }\n }\n\n this.outputStream = newStream;\n this.audioManager.setOutputStream(newStream);\n this.applyVideoTrackConstraints();\n\n // Stop old video tracks\n if (prev && prev !== newStream) {\n try {\n prev.getVideoTracks().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Failed to stop video track\n }\n });\n } catch {\n // Failed to get video tracks\n }\n }\n }\n\n private applyVideoTrackConstraints(): void {\n try {\n const track = this.outputStream?.getVideoTracks()[0];\n const canvas = this.renderer.captureCanvas;\n if (!track || !canvas) return;\n\n const constraints: MediaTrackConstraints = {\n width: canvas.width,\n height: canvas.height,\n frameRate: Math.max(1, this._sendFps || this._fps),\n };\n\n try {\n if ((track as MediaStreamTrack & { contentHint?: string }).contentHint !== undefined) {\n (track as MediaStreamTrack & { contentHint?: string }).contentHint = \"detail\";\n }\n } catch {\n // Failed to set content hint\n }\n\n track.applyConstraints(constraints).catch(() => {\n // Failed to apply constraints\n });\n } catch {\n // Error in applyVideoTrackConstraints\n }\n }\n\n private requestVideoTrackFrame(): void {\n const track = this.outputStream?.getVideoTracks()[0];\n if (track && typeof (track as MediaStreamTrack & { requestFrame?: () => void }).requestFrame === \"function\") {\n try {\n (track as MediaStreamTrack & { requestFrame: () => void }).requestFrame();\n } catch {\n // Failed to request video frame\n }\n }\n }\n}\n\nexport function createCompositor(options: CompositorOptions = {}): Compositor {\n return new Compositor(options);\n}\n"],"mappings":"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","names":["createBroadcast","createPlayer","DEFAULT_CONNECTION_TIMEOUT","prev","createBroadcast","createPlayer"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/errors.ts","../src/internal/dependencies.ts","../src/internal/WHIPClient.ts","../src/internal/TypedEventEmitter.ts","../src/internal/StateMachine.ts","../src/Broadcast.ts","../src/internal/WHEPClient.ts","../src/Player.ts","../src/internal/compositor/Registry.ts","../src/internal/compositor/Renderer.ts","../src/internal/compositor/Scheduler.ts","../src/internal/compositor/AudioManager.ts","../src/internal/compositor/VisibilityHandler.ts","../src/Compositor.ts"],"sourcesContent":["import type { BroadcastOptions, WHIPResponseResult } from \"./types\";\nimport { Broadcast, createBroadcast as baseCreateBroadcast } from \"./Broadcast\";\nimport { Player, createPlayer as baseCreatePlayer } from \"./Player\";\nimport type { PlayerOptions } from \"./types\";\n\nexport const livepeerResponseHandler = (\n response: Response,\n): WHIPResponseResult => ({\n whepUrl: response.headers.get(\"livepeer-playback-url\") ?? undefined,\n});\n\nexport type LivepeerBroadcastOptions = Omit<BroadcastOptions, \"onResponse\">;\n\nexport function createBroadcast(options: LivepeerBroadcastOptions): Broadcast {\n return baseCreateBroadcast({\n ...options,\n onResponse: livepeerResponseHandler,\n });\n}\n\nexport function createPlayer(whepUrl: string, options?: PlayerOptions): Player {\n return baseCreatePlayer(whepUrl, options);\n}\n\nexport {\n BaseDaydreamError,\n NetworkError,\n ConnectionError,\n StreamNotFoundError,\n UnauthorizedError,\n} from \"./errors\";\n\nexport type {\n AudioConfig,\n BroadcastOptions,\n PlayerOptions,\n BroadcastState,\n PlayerState,\n ReconnectConfig,\n ReconnectInfo,\n VideoConfig,\n BroadcastEventMap,\n PlayerEventMap,\n DaydreamError,\n DaydreamErrorCode,\n WHIPResponseResult,\n} from \"./types\";\n\nexport {\n DEFAULT_ICE_SERVERS,\n DEFAULT_VIDEO_BITRATE,\n DEFAULT_AUDIO_BITRATE,\n} from \"./types\";\n\nexport { Broadcast, type BroadcastConfig } from \"./Broadcast\";\nexport { Player, type PlayerConfig } from \"./Player\";\nexport { createCompositor } from \"./Compositor\";\n\nexport type {\n Compositor,\n CompositorOptions,\n CompositorEvent,\n CompositorEventMap,\n Source,\n VideoSource,\n CanvasSource,\n Size,\n FitMode,\n ContentHint,\n Ctx2D,\n} from \"./types\";\n","export type BroadcastState =\n | \"connecting\"\n | \"live\"\n | \"reconnecting\"\n | \"ended\"\n | \"error\";\n\nexport type PlayerState =\n | \"connecting\"\n | \"playing\"\n | \"buffering\"\n | \"ended\"\n | \"error\";\n\nexport interface WHIPResponseResult {\n whepUrl?: string;\n}\n\nexport interface BroadcastOptions {\n whipUrl: string;\n stream: MediaStream;\n reconnect?: ReconnectConfig;\n video?: VideoConfig;\n audio?: AudioConfig;\n iceServers?: RTCIceServer[];\n connectionTimeout?: number;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n onResponse?: (response: Response) => WHIPResponseResult | void;\n}\n\nexport interface PlayerOptions {\n reconnect?: ReconnectConfig;\n iceServers?: RTCIceServer[];\n connectionTimeout?: number;\n skipIceGathering?: boolean;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n}\n\nexport interface ReconnectConfig {\n enabled?: boolean;\n maxAttempts?: number;\n baseDelayMs?: number;\n}\n\nexport interface ReconnectInfo {\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n}\n\nexport interface VideoConfig {\n bitrate?: number;\n maxFramerate?: number;\n}\n\nexport interface AudioConfig {\n bitrate?: number;\n}\n\nexport interface BroadcastEventMap {\n stateChange: (state: BroadcastState) => void;\n error: (error: DaydreamError) => void;\n reconnect: (info: ReconnectInfo) => void;\n}\n\nexport interface PlayerEventMap {\n stateChange: (state: PlayerState) => void;\n error: (error: DaydreamError) => void;\n reconnect: (info: ReconnectInfo) => void;\n}\n\nexport interface DaydreamError extends Error {\n code: DaydreamErrorCode;\n cause?: unknown;\n}\n\nexport type DaydreamErrorCode =\n | \"NETWORK_ERROR\"\n | \"CONNECTION_FAILED\"\n | \"STREAM_NOT_FOUND\"\n | \"UNAUTHORIZED\"\n | \"UNKNOWN\";\n\nexport const DEFAULT_ICE_SERVERS: RTCIceServer[] = [\n { urls: \"stun:stun.l.google.com:19302\" },\n { urls: \"stun:stun1.l.google.com:19302\" },\n { urls: \"stun:stun.cloudflare.com:3478\" },\n];\n\nexport const DEFAULT_VIDEO_BITRATE = 300_000;\nexport const DEFAULT_AUDIO_BITRATE = 64_000;\n\n// ============================================================================\n// Compositor Types\n// ============================================================================\n\nexport type Ctx2D =\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D;\n\nexport type FitMode = \"contain\" | \"cover\";\n\nexport type ContentHint = \"detail\" | \"motion\" | \"\";\n\nexport type VideoSource = {\n kind: \"video\";\n element: HTMLVideoElement;\n fit?: FitMode;\n contentHint?: ContentHint;\n};\n\nexport type CanvasSource = {\n kind: \"canvas\";\n element: HTMLCanvasElement;\n fit?: FitMode;\n contentHint?: ContentHint;\n};\n\nexport type Source = VideoSource | CanvasSource;\n\nexport type Size = {\n width: number;\n height: number;\n dpr: number;\n};\n\nexport interface CompositorOptions {\n width?: number;\n height?: number;\n fps?: number;\n dpr?: number;\n sendFps?: number;\n keepalive?: boolean;\n autoUnlockAudio?: boolean;\n unlockEvents?: string[];\n disableSilentAudio?: boolean;\n onSendFpsChange?: (fps: number) => void;\n}\n\nexport type CompositorEvent = \"activated\" | \"registered\" | \"unregistered\";\n\nexport interface CompositorEventMap {\n activated: (id: string | null, source: Source | undefined) => void;\n registered: (id: string, source: Source) => void;\n unregistered: (id: string) => void;\n}\n\nexport interface Compositor {\n // Source Registry\n register(id: string, source: Source): void;\n unregister(id: string): void;\n get(id: string): Source | undefined;\n has(id: string): boolean;\n list(): Array<{ id: string; source: Source }>;\n\n // Active source management\n activate(id: string): void;\n deactivate(): void;\n readonly activeId: string | null;\n\n // Output stream\n readonly stream: MediaStream;\n\n // Settings\n resize(width: number, height: number, dpr?: number): void;\n readonly size: Size;\n setFps(fps: number): void;\n readonly fps: number;\n setSendFps(fps: number): void;\n readonly sendFps: number;\n\n // Audio\n addAudioTrack(track: MediaStreamTrack): void;\n removeAudioTrack(trackId: string): void;\n unlockAudio(): Promise<boolean>;\n\n // Lifecycle\n destroy(): void;\n\n // Events\n on<E extends CompositorEvent>(\n event: E,\n cb: CompositorEventMap[E],\n ): () => void;\n}\n","import type { DaydreamError, DaydreamErrorCode } from \"./types\";\n\nexport class BaseDaydreamError extends Error implements DaydreamError {\n readonly code: DaydreamErrorCode;\n readonly cause?: unknown;\n\n constructor(code: DaydreamErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = \"DaydreamError\";\n this.code = code;\n this.cause = cause;\n }\n}\n\nexport class NetworkError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"NETWORK_ERROR\", message, cause);\n this.name = \"NetworkError\";\n }\n}\n\nexport class ConnectionError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"CONNECTION_FAILED\", message, cause);\n this.name = \"ConnectionError\";\n }\n}\n\nexport class StreamNotFoundError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"STREAM_NOT_FOUND\", message, cause);\n this.name = \"StreamNotFoundError\";\n }\n}\n\nexport class UnauthorizedError extends BaseDaydreamError {\n constructor(message: string, cause?: unknown) {\n super(\"UNAUTHORIZED\", message, cause);\n this.name = \"UnauthorizedError\";\n }\n}\n","export interface PeerConnectionFactory {\n create(config: RTCConfiguration): RTCPeerConnection;\n}\n\nexport interface FetchFn {\n (input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\n}\n\nexport interface TimerProvider {\n setTimeout(callback: () => void, ms: number): number;\n clearTimeout(id: number): void;\n setInterval(callback: () => void, ms: number): number;\n clearInterval(id: number): void;\n}\n\nexport interface MediaStreamFactory {\n create(): MediaStream;\n}\n\nexport const defaultMediaStreamFactory: MediaStreamFactory = {\n create: () => new MediaStream(),\n};\n\nexport const defaultPeerConnectionFactory: PeerConnectionFactory = {\n create: (config) => new RTCPeerConnection(config),\n};\n\nexport const defaultFetch: FetchFn = globalThis.fetch.bind(globalThis);\n\nexport const defaultTimerProvider: TimerProvider = {\n setTimeout: (cb, ms) => globalThis.setTimeout(cb, ms) as unknown as number,\n clearTimeout: (id) => globalThis.clearTimeout(id),\n setInterval: (cb, ms) => globalThis.setInterval(cb, ms) as unknown as number,\n clearInterval: (id) => globalThis.clearInterval(id),\n};\n\n","import {\n DEFAULT_ICE_SERVERS,\n DEFAULT_VIDEO_BITRATE,\n DEFAULT_AUDIO_BITRATE,\n type WHIPResponseResult,\n} from \"../types\";\nimport { ConnectionError, NetworkError } from \"../errors\";\nimport {\n type PeerConnectionFactory,\n type FetchFn,\n type TimerProvider,\n defaultPeerConnectionFactory,\n defaultFetch,\n defaultTimerProvider,\n} from \"./dependencies\";\n\nconst PLAYBACK_ID_PATTERN = /([/+])([^/+?]+)$/;\nconst PLAYBACK_ID_PLACEHOLDER = \"__PLAYBACK_ID__\";\n\nexport interface RedirectCache {\n get(key: string): URL | undefined;\n set(key: string, value: URL): void;\n}\n\nclass LRURedirectCache implements RedirectCache {\n private cache = new Map<string, URL>();\n private readonly maxSize: number;\n\n constructor(maxSize = 10) {\n this.maxSize = maxSize;\n }\n\n get(key: string): URL | undefined {\n const cached = this.cache.get(key);\n if (cached) {\n this.cache.delete(key);\n this.cache.set(key, cached);\n }\n return cached;\n }\n\n set(key: string, value: URL): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey) this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n}\n\nexport interface WHIPClientConfig {\n url: string;\n iceServers?: RTCIceServer[];\n videoBitrate?: number;\n audioBitrate?: number;\n maxFramerate?: number;\n connectionTimeout?: number;\n skipIceGathering?: boolean;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n onResponse?: (response: Response) => WHIPResponseResult | void;\n peerConnectionFactory?: PeerConnectionFactory;\n fetch?: FetchFn;\n timers?: TimerProvider;\n redirectCache?: RedirectCache;\n}\n\nfunction preferH264(sdp: string): string {\n const lines = sdp.split(\"\\r\\n\");\n const mLineIndex = lines.findIndex((line) => line.startsWith(\"m=video\"));\n if (mLineIndex === -1) return sdp;\n\n const codecRegex = /a=rtpmap:(\\d+) H264(\\/\\d+)+/;\n const codecLine = lines.find((line) => codecRegex.test(line));\n if (!codecLine) return sdp;\n\n const match = codecRegex.exec(codecLine);\n const codecPayload = match?.[1];\n if (!codecPayload) return sdp;\n\n const mLine = lines[mLineIndex];\n if (!mLine) return sdp;\n\n const mLineElements = mLine.split(\" \");\n const reorderedMLine = [\n ...mLineElements.slice(0, 3),\n codecPayload,\n ...mLineElements.slice(3).filter((payload) => payload !== codecPayload),\n ];\n lines[mLineIndex] = reorderedMLine.join(\" \");\n return lines.join(\"\\r\\n\");\n}\n\nconst sharedRedirectCache = new LRURedirectCache();\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nexport class WHIPClient {\n private readonly url: string;\n private readonly iceServers: RTCIceServer[];\n private readonly videoBitrate: number;\n private readonly audioBitrate: number;\n private readonly connectionTimeout: number;\n private readonly onStats?: (report: RTCStatsReport) => void;\n private readonly statsIntervalMs: number;\n private readonly onResponse?: (\n response: Response,\n ) => WHIPResponseResult | void;\n private readonly pcFactory: PeerConnectionFactory;\n private readonly fetch: FetchFn;\n private readonly timers: TimerProvider;\n private readonly redirectCache: RedirectCache;\n private readonly skipIceGathering: boolean;\n\n private maxFramerate?: number;\n private pc: RTCPeerConnection | null = null;\n private resourceUrl: string | null = null;\n private abortController: AbortController | null = null;\n private statsTimer: number | null = null;\n private videoSender: RTCRtpSender | null = null;\n private audioSender: RTCRtpSender | null = null;\n private videoTransceiver: RTCRtpTransceiver | null = null;\n private audioTransceiver: RTCRtpTransceiver | null = null;\n private iceGatheringTimer: number | null = null;\n\n constructor(config: WHIPClientConfig) {\n this.url = config.url;\n this.iceServers = config.iceServers ?? DEFAULT_ICE_SERVERS;\n this.videoBitrate = config.videoBitrate ?? DEFAULT_VIDEO_BITRATE;\n this.audioBitrate = config.audioBitrate ?? DEFAULT_AUDIO_BITRATE;\n this.connectionTimeout =\n config.connectionTimeout ?? DEFAULT_CONNECTION_TIMEOUT;\n this.maxFramerate = config.maxFramerate;\n this.onStats = config.onStats;\n this.statsIntervalMs = config.statsIntervalMs ?? 5000;\n this.onResponse = config.onResponse;\n this.pcFactory =\n config.peerConnectionFactory ?? defaultPeerConnectionFactory;\n this.fetch = config.fetch ?? defaultFetch;\n this.timers = config.timers ?? defaultTimerProvider;\n this.redirectCache = config.redirectCache ?? sharedRedirectCache;\n this.skipIceGathering = config.skipIceGathering ?? true;\n }\n\n async connect(stream: MediaStream): Promise<{ whepUrl: string | null }> {\n this.cleanup();\n\n this.pc = this.pcFactory.create({\n iceServers: this.iceServers,\n iceCandidatePoolSize: 10,\n });\n\n this.videoTransceiver = this.pc.addTransceiver(\"video\", {\n direction: \"sendonly\",\n });\n this.audioTransceiver = this.pc.addTransceiver(\"audio\", {\n direction: \"sendonly\",\n });\n this.videoSender = this.videoTransceiver.sender;\n this.audioSender = this.audioTransceiver.sender;\n\n const videoTrack = stream.getVideoTracks()[0];\n const audioTrack = stream.getAudioTracks()[0];\n\n if (videoTrack) {\n if (videoTrack.contentHint === \"\") {\n videoTrack.contentHint = \"motion\";\n }\n await this.videoSender.replaceTrack(videoTrack);\n }\n\n if (audioTrack) {\n await this.audioSender.replaceTrack(audioTrack);\n }\n\n this.setCodecPreferences();\n\n const offer = await this.pc.createOffer({\n offerToReceiveAudio: false,\n offerToReceiveVideo: false,\n });\n const enhancedSdp = preferH264(offer.sdp ?? \"\");\n await this.pc.setLocalDescription({ type: \"offer\", sdp: enhancedSdp });\n\n if (!this.skipIceGathering) {\n await this.waitForIceGathering();\n }\n\n this.abortController = new AbortController();\n const timeoutId = this.timers.setTimeout(\n () => this.abortController?.abort(),\n this.connectionTimeout,\n );\n\n try {\n const fetchUrl = this.getUrlWithCachedRedirect();\n\n const response = await this.fetch(fetchUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/sdp\" },\n body: this.pc.localDescription!.sdp,\n signal: this.abortController.signal,\n });\n\n this.timers.clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new ConnectionError(\n `WHIP connection failed: ${response.status} ${response.statusText} ${errorText}`,\n );\n }\n\n this.cacheRedirectIfNeeded(fetchUrl, response.url);\n\n const location = response.headers.get(\"location\");\n if (location) {\n this.resourceUrl = new URL(location, this.url).toString();\n }\n\n const responseResult = this.onResponse?.(response);\n\n const answerSdp = await response.text();\n await this.pc.setRemoteDescription({ type: \"answer\", sdp: answerSdp });\n\n await this.applyBitrateConstraints();\n this.startStatsTimer();\n\n return { whepUrl: responseResult?.whepUrl ?? null };\n } catch (error) {\n this.timers.clearTimeout(timeoutId);\n if (error instanceof ConnectionError) {\n throw error;\n }\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new NetworkError(\"Connection timeout\");\n }\n throw new NetworkError(\"Failed to establish connection\", error);\n }\n }\n\n private setCodecPreferences(): void {\n if (!this.videoTransceiver?.setCodecPreferences) return;\n\n try {\n const caps = RTCRtpSender.getCapabilities(\"video\");\n if (!caps?.codecs?.length) return;\n\n const h264Codecs = caps.codecs.filter((c) =>\n c.mimeType.toLowerCase().includes(\"h264\"),\n );\n if (h264Codecs.length) {\n this.videoTransceiver.setCodecPreferences(h264Codecs);\n }\n } catch {\n // Codec preferences not supported\n }\n }\n\n private async applyBitrateConstraints(): Promise<void> {\n if (!this.pc) return;\n\n const senders = this.pc.getSenders();\n for (const sender of senders) {\n if (!sender.track) continue;\n\n const params = sender.getParameters();\n if (!params.encodings) params.encodings = [{}];\n\n const encoding = params.encodings[0];\n if (!encoding) continue;\n\n if (sender.track.kind === \"video\") {\n encoding.maxBitrate = this.videoBitrate;\n if (this.maxFramerate && this.maxFramerate > 0) {\n encoding.maxFramerate = this.maxFramerate;\n }\n encoding.scaleResolutionDownBy = 1.0;\n encoding.priority = \"high\";\n encoding.networkPriority = \"high\";\n params.degradationPreference = \"maintain-resolution\";\n } else if (sender.track.kind === \"audio\") {\n encoding.maxBitrate = this.audioBitrate;\n encoding.priority = \"medium\";\n encoding.networkPriority = \"medium\";\n }\n\n try {\n await sender.setParameters(params);\n } catch {\n // Parameters not supported\n }\n }\n }\n\n private waitForIceGathering(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.pc) {\n resolve();\n return;\n }\n\n if (this.pc.iceGatheringState === \"complete\") {\n resolve();\n return;\n }\n\n const onStateChange = () => {\n if (this.pc?.iceGatheringState === \"complete\") {\n this.pc.removeEventListener(\"icegatheringstatechange\", onStateChange);\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n resolve();\n }\n };\n\n this.pc.addEventListener(\"icegatheringstatechange\", onStateChange);\n\n this.iceGatheringTimer = this.timers.setTimeout(() => {\n this.pc?.removeEventListener(\"icegatheringstatechange\", onStateChange);\n this.iceGatheringTimer = null;\n resolve();\n }, 1000);\n });\n }\n\n private startStatsTimer(): void {\n if (!this.onStats || !this.pc) return;\n\n this.stopStatsTimer();\n\n this.statsTimer = this.timers.setInterval(async () => {\n if (!this.pc) return;\n try {\n const report = await this.pc.getStats();\n this.onStats?.(report);\n } catch {\n // Stats collection failed\n }\n }, this.statsIntervalMs);\n }\n\n private stopStatsTimer(): void {\n if (this.statsTimer !== null) {\n this.timers.clearInterval(this.statsTimer);\n this.statsTimer = null;\n }\n }\n\n async replaceTrack(track: MediaStreamTrack): Promise<void> {\n if (!this.pc) {\n throw new ConnectionError(\"Not connected\");\n }\n\n const sender = track.kind === \"video\" ? this.videoSender : this.audioSender;\n if (!sender) {\n throw new ConnectionError(\n `No sender found for track kind: ${track.kind}`,\n );\n }\n\n await sender.replaceTrack(track);\n await this.applyBitrateConstraints();\n }\n\n setMaxFramerate(fps?: number): void {\n this.maxFramerate = fps;\n void this.applyBitrateConstraints();\n }\n\n private cleanup(): void {\n this.stopStatsTimer();\n\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n\n if (this.abortController) {\n try {\n this.abortController.abort();\n } catch {\n // Ignore abort errors\n }\n this.abortController = null;\n }\n\n if (this.pc) {\n // Clear event handlers\n this.pc.oniceconnectionstatechange = null;\n this.pc.onconnectionstatechange = null;\n this.pc.ontrack = null;\n\n try {\n this.pc.getTransceivers().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Ignore stop errors\n }\n });\n } catch {\n // Ignore transceiver errors\n }\n\n try {\n this.pc.close();\n } catch {\n // Ignore close errors\n }\n this.pc = null;\n }\n\n this.videoSender = null;\n this.audioSender = null;\n this.videoTransceiver = null;\n this.audioTransceiver = null;\n }\n\n async disconnect(): Promise<void> {\n if (this.resourceUrl) {\n try {\n await this.fetch(this.resourceUrl, { method: \"DELETE\" });\n } catch {\n // Ignore delete errors\n }\n }\n\n this.cleanup();\n this.resourceUrl = null;\n }\n\n getPeerConnection(): RTCPeerConnection | null {\n return this.pc;\n }\n\n restartIce(): void {\n if (this.pc) {\n try {\n this.pc.restartIce();\n } catch {\n // ICE restart not supported\n }\n }\n }\n\n isConnected(): boolean {\n if (!this.pc) return false;\n const iceState = this.pc.iceConnectionState;\n return iceState === \"connected\" || iceState === \"completed\";\n }\n\n private getUrlWithCachedRedirect(): string {\n const originalUrl = new URL(this.url);\n const playbackIdMatch = originalUrl.pathname.match(PLAYBACK_ID_PATTERN);\n const playbackId = playbackIdMatch?.[2];\n\n const cachedTemplate = this.redirectCache.get(this.url);\n if (!cachedTemplate || !playbackId) {\n return this.url;\n }\n\n const redirectedUrl = new URL(cachedTemplate);\n redirectedUrl.pathname = cachedTemplate.pathname.replace(\n PLAYBACK_ID_PLACEHOLDER,\n playbackId,\n );\n return redirectedUrl.toString();\n }\n\n private cacheRedirectIfNeeded(requestUrl: string, responseUrl: string): void {\n if (requestUrl === responseUrl) return;\n\n try {\n const actualRedirect = new URL(responseUrl);\n const template = new URL(actualRedirect);\n template.pathname = template.pathname.replace(\n PLAYBACK_ID_PATTERN,\n `$1${PLAYBACK_ID_PLACEHOLDER}`,\n );\n this.redirectCache.set(this.url, template);\n } catch {\n // Invalid URL, skip caching\n }\n }\n}\n","export class TypedEventEmitter<EventMap extends { [K in keyof EventMap]: (...args: any[]) => void }> {\n private listeners = new Map<keyof EventMap, Set<(...args: any[]) => void>>();\n\n on<E extends keyof EventMap>(event: E, handler: EventMap[E]): this {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler);\n return this;\n }\n\n off<E extends keyof EventMap>(event: E, handler: EventMap[E]): this {\n this.listeners.get(event)?.delete(handler);\n return this;\n }\n\n protected emit<E extends keyof EventMap>(\n event: E,\n ...args: Parameters<EventMap[E]>\n ): void {\n this.listeners.get(event)?.forEach((handler) => {\n (handler as (...args: Parameters<EventMap[E]>) => void)(...args);\n });\n }\n\n protected clearListeners(): void {\n this.listeners.clear();\n }\n}\n\n","type TransitionMap<S extends string> = Record<S, S[]>;\n\nexport interface StateMachine<S extends string> {\n readonly current: S;\n can(next: S): boolean;\n transition(next: S): boolean;\n force(next: S): void;\n}\n\nexport function createStateMachine<S extends string>(\n initial: S,\n transitions: TransitionMap<S>,\n onChange?: (from: S, to: S) => void,\n): StateMachine<S> {\n let current = initial;\n\n return {\n get current() {\n return current;\n },\n can(next: S) {\n return transitions[current].includes(next);\n },\n transition(next: S): boolean {\n if (!transitions[current].includes(next)) return false;\n const prev = current;\n current = next;\n onChange?.(prev, next);\n return true;\n },\n force(next: S) {\n const prev = current;\n current = next;\n onChange?.(prev, next);\n },\n };\n}\n","import type {\n BroadcastState,\n BroadcastEventMap,\n BroadcastOptions,\n ReconnectConfig,\n ReconnectInfo,\n DaydreamError,\n} from \"./types\";\nimport { WHIPClient, type WHIPClientConfig } from \"./internal/WHIPClient\";\nimport { ConnectionError } from \"./errors\";\nimport { TypedEventEmitter } from \"./internal/TypedEventEmitter\";\nimport { createStateMachine, type StateMachine } from \"./internal/StateMachine\";\n\nconst BROADCAST_TRANSITIONS: Record<BroadcastState, BroadcastState[]> = {\n connecting: [\"live\", \"error\"],\n live: [\"reconnecting\", \"ended\"],\n reconnecting: [\"live\", \"ended\"],\n ended: [],\n error: [\"connecting\"],\n};\n\nexport interface BroadcastConfig {\n whipUrl: string;\n stream: MediaStream;\n reconnect?: ReconnectConfig;\n whipConfig?: Partial<WHIPClientConfig>;\n}\n\nexport class Broadcast extends TypedEventEmitter<BroadcastEventMap> {\n private _whepUrl: string | null = null;\n private readonly stateMachine: StateMachine<BroadcastState>;\n private currentStream: MediaStream;\n private readonly reconnectConfig: ReconnectConfig;\n private readonly whipClient: WHIPClient;\n\n private reconnectAttempts = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n private disconnectedGraceTimeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: BroadcastConfig) {\n super();\n this.currentStream = config.stream;\n this.reconnectConfig = {\n enabled: config.reconnect?.enabled ?? true,\n maxAttempts: config.reconnect?.maxAttempts ?? 5,\n baseDelayMs: config.reconnect?.baseDelayMs ?? 1000,\n };\n\n this.whipClient = new WHIPClient({\n url: config.whipUrl,\n ...config.whipConfig,\n });\n\n this.stateMachine = createStateMachine<BroadcastState>(\n \"connecting\",\n BROADCAST_TRANSITIONS,\n (_from, to) => this.emit(\"stateChange\", to),\n );\n }\n\n get state(): BroadcastState {\n return this.stateMachine.current;\n }\n\n get whepUrl(): string | null {\n return this._whepUrl;\n }\n\n get stream(): MediaStream {\n return this.currentStream;\n }\n\n get reconnectInfo(): ReconnectInfo | null {\n if (this.state !== \"reconnecting\") return null;\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 1000;\n const delay = baseDelay * Math.pow(2, this.reconnectAttempts - 1);\n return {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 5,\n delayMs: delay,\n };\n }\n\n async connect(): Promise<void> {\n try {\n const result = await this.whipClient.connect(this.currentStream);\n if (result.whepUrl) {\n this._whepUrl = result.whepUrl;\n }\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"live\");\n } catch (error) {\n this.stateMachine.transition(\"error\");\n const daydreamError =\n error instanceof Error\n ? error\n : new ConnectionError(\"Failed to connect\", error);\n this.emit(\"error\", daydreamError as DaydreamError);\n throw daydreamError;\n }\n }\n\n async stop(): Promise<void> {\n this.stateMachine.force(\"ended\");\n this.clearTimeouts();\n\n await this.whipClient.disconnect();\n this.clearListeners();\n }\n\n setMaxFramerate(fps?: number): void {\n this.whipClient.setMaxFramerate(fps);\n }\n\n async replaceStream(newStream: MediaStream): Promise<void> {\n if (!this.whipClient.isConnected()) {\n this.currentStream = newStream;\n return;\n }\n\n const videoTrack = newStream.getVideoTracks()[0];\n const audioTrack = newStream.getAudioTracks()[0];\n\n try {\n if (videoTrack) {\n await this.whipClient.replaceTrack(videoTrack);\n }\n if (audioTrack) {\n await this.whipClient.replaceTrack(audioTrack);\n }\n this.currentStream = newStream;\n } catch {\n this.currentStream = newStream;\n this.scheduleReconnect();\n }\n }\n\n private setupConnectionMonitoring(): void {\n const pc = this.whipClient.getPeerConnection();\n if (!pc) return;\n\n pc.oniceconnectionstatechange = () => {\n if (this.state === \"ended\") return;\n\n const iceState = pc.iceConnectionState;\n\n if (iceState === \"connected\" || iceState === \"completed\") {\n this.clearGraceTimeout();\n if (this.state === \"reconnecting\") {\n this.stateMachine.transition(\"live\");\n this.reconnectAttempts = 0;\n }\n return;\n }\n\n if (iceState === \"disconnected\") {\n this.clearGraceTimeout();\n this.whipClient.restartIce();\n\n this.disconnectedGraceTimeout = setTimeout(() => {\n if (this.state === \"ended\") return;\n const currentState = pc.iceConnectionState;\n if (currentState === \"disconnected\") {\n this.scheduleReconnect();\n }\n }, 2000);\n return;\n }\n\n if (iceState === \"failed\" || iceState === \"closed\") {\n this.clearGraceTimeout();\n this.scheduleReconnect();\n }\n };\n }\n\n private clearGraceTimeout(): void {\n if (this.disconnectedGraceTimeout) {\n clearTimeout(this.disconnectedGraceTimeout);\n this.disconnectedGraceTimeout = null;\n }\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n }\n\n private clearTimeouts(): void {\n this.clearGraceTimeout();\n this.clearReconnectTimeout();\n }\n\n private scheduleReconnect(): void {\n if (this.state === \"ended\") return;\n\n if (!this.reconnectConfig.enabled) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n const maxAttempts = this.reconnectConfig.maxAttempts ?? 5;\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n this.clearReconnectTimeout();\n this.stateMachine.transition(\"reconnecting\");\n\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 1000;\n const delay = baseDelay * Math.pow(2, this.reconnectAttempts);\n this.reconnectAttempts++;\n\n this.emit(\"reconnect\", {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 5,\n delayMs: delay,\n });\n\n this.reconnectTimeout = setTimeout(async () => {\n if (this.state === \"ended\") return;\n\n try {\n await this.whipClient.disconnect();\n const result = await this.whipClient.connect(this.currentStream);\n if (result.whepUrl) {\n this._whepUrl = result.whepUrl;\n }\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"live\");\n this.reconnectAttempts = 0;\n } catch {\n this.scheduleReconnect();\n }\n }, delay);\n }\n}\n\nexport function createBroadcast(options: BroadcastOptions): Broadcast {\n const {\n whipUrl,\n stream,\n reconnect,\n video,\n audio,\n iceServers,\n connectionTimeout,\n onStats,\n statsIntervalMs,\n onResponse,\n } = options;\n\n return new Broadcast({\n whipUrl,\n stream,\n reconnect,\n whipConfig: {\n iceServers,\n videoBitrate: video?.bitrate,\n audioBitrate: audio?.bitrate,\n maxFramerate: video?.maxFramerate,\n connectionTimeout,\n onStats,\n statsIntervalMs,\n onResponse,\n },\n });\n}\n","import { DEFAULT_ICE_SERVERS } from \"../types\";\nimport { ConnectionError, NetworkError } from \"../errors\";\nimport {\n type PeerConnectionFactory,\n type FetchFn,\n type TimerProvider,\n type MediaStreamFactory,\n defaultPeerConnectionFactory,\n defaultFetch,\n defaultTimerProvider,\n defaultMediaStreamFactory,\n} from \"./dependencies\";\n\nexport interface WHEPClientConfig {\n url: string;\n iceServers?: RTCIceServer[];\n connectionTimeout?: number;\n skipIceGathering?: boolean;\n onStats?: (report: RTCStatsReport) => void;\n statsIntervalMs?: number;\n peerConnectionFactory?: PeerConnectionFactory;\n fetch?: FetchFn;\n timers?: TimerProvider;\n mediaStreamFactory?: MediaStreamFactory;\n}\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nexport class WHEPClient {\n private readonly url: string;\n private readonly iceServers: RTCIceServer[];\n private readonly connectionTimeout: number;\n private readonly skipIceGathering: boolean;\n private readonly onStats?: (report: RTCStatsReport) => void;\n private readonly statsIntervalMs: number;\n private readonly pcFactory: PeerConnectionFactory;\n private readonly fetch: FetchFn;\n private readonly timers: TimerProvider;\n private readonly mediaStreamFactory: MediaStreamFactory;\n\n private pc: RTCPeerConnection | null = null;\n private resourceUrl: string | null = null;\n private stream: MediaStream | null = null;\n private abortController: AbortController | null = null;\n private statsTimer: number | null = null;\n private iceGatheringTimer: number | null = null;\n\n constructor(config: WHEPClientConfig) {\n this.url = config.url;\n this.iceServers = config.iceServers ?? DEFAULT_ICE_SERVERS;\n this.connectionTimeout =\n config.connectionTimeout ?? DEFAULT_CONNECTION_TIMEOUT;\n this.skipIceGathering = config.skipIceGathering ?? true;\n this.onStats = config.onStats;\n this.statsIntervalMs = config.statsIntervalMs ?? 5000;\n this.pcFactory =\n config.peerConnectionFactory ?? defaultPeerConnectionFactory;\n this.fetch = config.fetch ?? defaultFetch;\n this.timers = config.timers ?? defaultTimerProvider;\n this.mediaStreamFactory =\n config.mediaStreamFactory ?? defaultMediaStreamFactory;\n }\n\n async connect(): Promise<MediaStream> {\n this.cleanup();\n\n this.pc = this.pcFactory.create({\n iceServers: this.iceServers,\n });\n\n this.pc.addTransceiver(\"video\", { direction: \"recvonly\" });\n this.pc.addTransceiver(\"audio\", { direction: \"recvonly\" });\n\n this.stream = this.mediaStreamFactory.create();\n\n this.pc.ontrack = (event) => {\n const [remoteStream] = event.streams;\n if (remoteStream) {\n this.stream = remoteStream;\n } else if (this.stream) {\n this.stream.addTrack(event.track);\n }\n };\n\n const offer = await this.pc.createOffer();\n await this.pc.setLocalDescription(offer);\n\n if (!this.skipIceGathering) {\n await this.waitForIceGathering();\n }\n\n this.abortController = new AbortController();\n const timeoutId = this.timers.setTimeout(\n () => this.abortController?.abort(),\n this.connectionTimeout,\n );\n\n try {\n const response = await this.fetch(this.url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/sdp\" },\n body: this.pc.localDescription!.sdp,\n signal: this.abortController.signal,\n });\n\n this.timers.clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new ConnectionError(\n `WHEP connection failed: ${response.status} ${response.statusText} ${errorText}`,\n );\n }\n\n const location = response.headers.get(\"location\");\n if (location) {\n this.resourceUrl = new URL(location, this.url).toString();\n }\n\n const answerSdp = await response.text();\n await this.pc.setRemoteDescription({ type: \"answer\", sdp: answerSdp });\n\n this.startStatsTimer();\n\n return this.stream;\n } catch (error) {\n this.timers.clearTimeout(timeoutId);\n if (error instanceof ConnectionError) {\n throw error;\n }\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new NetworkError(\"Connection timeout\");\n }\n throw new NetworkError(\"Failed to establish connection\", error);\n }\n }\n\n private waitForIceGathering(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.pc) {\n resolve();\n return;\n }\n\n if (this.pc.iceGatheringState === \"complete\") {\n resolve();\n return;\n }\n\n const onStateChange = () => {\n if (this.pc?.iceGatheringState === \"complete\") {\n this.pc.removeEventListener(\"icegatheringstatechange\", onStateChange);\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n resolve();\n }\n };\n\n this.pc.addEventListener(\"icegatheringstatechange\", onStateChange);\n\n this.iceGatheringTimer = this.timers.setTimeout(() => {\n this.pc?.removeEventListener(\"icegatheringstatechange\", onStateChange);\n this.iceGatheringTimer = null;\n resolve();\n }, 1000);\n });\n }\n\n private startStatsTimer(): void {\n if (!this.onStats || !this.pc) return;\n\n this.stopStatsTimer();\n\n this.statsTimer = this.timers.setInterval(async () => {\n if (!this.pc) return;\n try {\n const report = await this.pc.getStats();\n this.onStats?.(report);\n } catch {\n // Stats collection failed\n }\n }, this.statsIntervalMs);\n }\n\n private stopStatsTimer(): void {\n if (this.statsTimer !== null) {\n this.timers.clearInterval(this.statsTimer);\n this.statsTimer = null;\n }\n }\n\n private cleanup(): void {\n this.stopStatsTimer();\n\n if (this.iceGatheringTimer !== null) {\n this.timers.clearTimeout(this.iceGatheringTimer);\n this.iceGatheringTimer = null;\n }\n\n if (this.abortController) {\n try {\n this.abortController.abort();\n } catch {\n // Ignore abort errors\n }\n this.abortController = null;\n }\n\n if (this.pc) {\n // Clear event handlers\n this.pc.oniceconnectionstatechange = null;\n this.pc.onconnectionstatechange = null;\n this.pc.ontrack = null;\n\n try {\n this.pc.getTransceivers().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Ignore stop errors\n }\n });\n } catch {\n // Ignore transceiver errors\n }\n\n try {\n this.pc.close();\n } catch {\n // Ignore close errors\n }\n this.pc = null;\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.resourceUrl) {\n try {\n await this.fetch(this.resourceUrl, { method: \"DELETE\" });\n } catch {\n // Ignore delete errors\n }\n }\n\n this.cleanup();\n this.stream = null;\n this.resourceUrl = null;\n }\n\n getStream(): MediaStream | null {\n return this.stream;\n }\n\n getPeerConnection(): RTCPeerConnection | null {\n return this.pc;\n }\n\n restartIce(): void {\n if (this.pc) {\n try {\n this.pc.restartIce();\n } catch {\n // ICE restart not supported\n }\n }\n }\n}\n","import type {\n PlayerState,\n PlayerEventMap,\n PlayerOptions,\n ReconnectConfig,\n ReconnectInfo,\n DaydreamError,\n} from \"./types\";\nimport { WHEPClient, type WHEPClientConfig } from \"./internal/WHEPClient\";\nimport { ConnectionError } from \"./errors\";\nimport { TypedEventEmitter } from \"./internal/TypedEventEmitter\";\nimport { createStateMachine, type StateMachine } from \"./internal/StateMachine\";\n\nconst PLAYER_TRANSITIONS: Record<PlayerState, PlayerState[]> = {\n connecting: [\"playing\", \"buffering\", \"error\"],\n playing: [\"buffering\", \"ended\"],\n buffering: [\"playing\", \"ended\"],\n ended: [],\n error: [\"connecting\"],\n};\n\nexport interface PlayerConfig {\n whepUrl: string;\n reconnect?: ReconnectConfig;\n whepConfig?: Partial<WHEPClientConfig>;\n}\n\nexport class Player extends TypedEventEmitter<PlayerEventMap> {\n private readonly stateMachine: StateMachine<PlayerState>;\n private _stream: MediaStream | null = null;\n private readonly whepUrl: string;\n private readonly reconnectConfig: ReconnectConfig;\n private readonly whepConfig: Partial<WHEPClientConfig> | undefined;\n private whepClient: WHEPClient;\n\n private reconnectAttempts = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n private disconnectedGraceTimeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: PlayerConfig) {\n super();\n this.whepUrl = config.whepUrl;\n this.whepConfig = config.whepConfig;\n this.reconnectConfig = {\n enabled: config.reconnect?.enabled ?? true,\n maxAttempts: config.reconnect?.maxAttempts ?? 30,\n baseDelayMs: config.reconnect?.baseDelayMs ?? 200,\n };\n\n this.whepClient = new WHEPClient({\n url: config.whepUrl,\n ...this.whepConfig,\n });\n\n this.stateMachine = createStateMachine<PlayerState>(\n \"connecting\",\n PLAYER_TRANSITIONS,\n (_from, to) => this.emit(\"stateChange\", to),\n );\n }\n\n get state(): PlayerState {\n return this.stateMachine.current;\n }\n\n get stream(): MediaStream | null {\n return this._stream;\n }\n\n get reconnectInfo(): ReconnectInfo | null {\n if (this.state !== \"buffering\") return null;\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 200;\n const delay = this.calculateReconnectDelay(\n this.reconnectAttempts - 1,\n baseDelay,\n );\n return {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 30,\n delayMs: delay,\n };\n }\n\n async connect(): Promise<void> {\n try {\n this._stream = await this.whepClient.connect();\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"playing\");\n this.reconnectAttempts = 0;\n } catch (error) {\n if (\n this.reconnectConfig.enabled &&\n this.reconnectAttempts < (this.reconnectConfig.maxAttempts ?? 30)\n ) {\n this.scheduleReconnect();\n return;\n }\n this.stateMachine.transition(\"error\");\n const daydreamError =\n error instanceof Error\n ? error\n : new ConnectionError(\"Failed to connect\", error);\n this.emit(\"error\", daydreamError as DaydreamError);\n throw daydreamError;\n }\n }\n\n attachTo(video: HTMLVideoElement): void {\n if (this._stream) {\n video.srcObject = this._stream;\n }\n }\n\n async stop(): Promise<void> {\n this.stateMachine.force(\"ended\");\n this.clearTimeouts();\n\n await this.whepClient.disconnect();\n this._stream = null;\n this.clearListeners();\n }\n\n private setupConnectionMonitoring(): void {\n const pc = this.whepClient.getPeerConnection();\n if (!pc) return;\n\n pc.oniceconnectionstatechange = () => {\n if (this.state === \"ended\") return;\n\n const iceState = pc.iceConnectionState;\n\n if (iceState === \"connected\" || iceState === \"completed\") {\n this.clearGraceTimeout();\n if (this.state === \"buffering\") {\n this.stateMachine.transition(\"playing\");\n this.reconnectAttempts = 0;\n }\n return;\n }\n\n if (iceState === \"disconnected\") {\n this.clearGraceTimeout();\n this.whepClient.restartIce();\n\n this.disconnectedGraceTimeout = setTimeout(() => {\n if (this.state === \"ended\") return;\n const currentState = pc.iceConnectionState;\n if (currentState === \"disconnected\") {\n this.scheduleReconnect();\n }\n }, 2000);\n return;\n }\n\n if (iceState === \"failed\" || iceState === \"closed\") {\n this.clearGraceTimeout();\n this.scheduleReconnect();\n }\n };\n }\n\n private clearGraceTimeout(): void {\n if (this.disconnectedGraceTimeout) {\n clearTimeout(this.disconnectedGraceTimeout);\n this.disconnectedGraceTimeout = null;\n }\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n }\n\n private clearTimeouts(): void {\n this.clearGraceTimeout();\n this.clearReconnectTimeout();\n }\n\n private scheduleReconnect(): void {\n if (this.state === \"ended\") return;\n\n if (!this.reconnectConfig.enabled) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n const maxAttempts = this.reconnectConfig.maxAttempts ?? 30;\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.stateMachine.transition(\"ended\");\n return;\n }\n\n this.clearReconnectTimeout();\n this.stateMachine.transition(\"buffering\");\n\n const baseDelay = this.reconnectConfig.baseDelayMs ?? 200;\n const delay = this.calculateReconnectDelay(\n this.reconnectAttempts,\n baseDelay,\n );\n this.reconnectAttempts++;\n\n this.emit(\"reconnect\", {\n attempt: this.reconnectAttempts,\n maxAttempts: this.reconnectConfig.maxAttempts ?? 30,\n delayMs: delay,\n });\n\n this.reconnectTimeout = setTimeout(async () => {\n if (this.state === \"ended\") return;\n\n try {\n await this.whepClient.disconnect();\n this.whepClient = new WHEPClient({\n url: this.whepUrl,\n ...this.whepConfig,\n });\n this._stream = await this.whepClient.connect();\n this.setupConnectionMonitoring();\n this.stateMachine.transition(\"playing\");\n this.reconnectAttempts = 0;\n } catch {\n this.scheduleReconnect();\n }\n }, delay);\n }\n\n private calculateReconnectDelay(attempt: number, baseDelay: number): number {\n const linearPhaseEndCount = 10;\n const maxDelay = 60000;\n\n if (attempt === 0) return 0;\n if (attempt <= linearPhaseEndCount) return baseDelay;\n\n const exponentialAttempt = attempt - linearPhaseEndCount;\n const delay = 500 * Math.pow(2, exponentialAttempt - 1);\n return Math.min(delay, maxDelay);\n }\n}\n\nexport function createPlayer(whepUrl: string, options?: PlayerOptions): Player {\n return new Player({\n whepUrl,\n reconnect: options?.reconnect,\n whepConfig: {\n iceServers: options?.iceServers,\n connectionTimeout: options?.connectionTimeout,\n skipIceGathering: options?.skipIceGathering,\n onStats: options?.onStats,\n statsIntervalMs: options?.statsIntervalMs,\n },\n });\n}\n","import type { Source } from \"../../types\";\n\nexport type RegistryEntry = {\n id: string;\n source: Source;\n registeredAt: number;\n};\n\nexport type RegistryEvents = {\n onRegister?: (id: string, source: Source) => void;\n onUnregister?: (id: string) => void;\n};\n\nexport interface SourceRegistry {\n register(id: string, source: Source): void;\n unregister(id: string): Source | undefined;\n get(id: string): Source | undefined;\n has(id: string): boolean;\n list(): Array<{ id: string; source: Source }>;\n clear(): void;\n}\n\nexport function createRegistry(events?: RegistryEvents): SourceRegistry {\n const sources = new Map<string, RegistryEntry>();\n\n return {\n register(id: string, source: Source): void {\n if (!id) throw new Error(\"Source id is required\");\n if (!source) throw new Error(\"Source is required\");\n\n sources.set(id, {\n id,\n source,\n registeredAt: Date.now(),\n });\n\n events?.onRegister?.(id, source);\n },\n\n unregister(id: string): Source | undefined {\n const entry = sources.get(id);\n if (!entry) return undefined;\n\n sources.delete(id);\n events?.onUnregister?.(id);\n\n return entry.source;\n },\n\n get(id: string): Source | undefined {\n return sources.get(id)?.source;\n },\n\n has(id: string): boolean {\n return sources.has(id);\n },\n\n list(): Array<{ id: string; source: Source }> {\n return Array.from(sources.values()).map((entry) => ({\n id: entry.id,\n source: entry.source,\n }));\n },\n\n clear(): void {\n const ids = Array.from(sources.keys());\n sources.clear();\n ids.forEach((id) => events?.onUnregister?.(id));\n },\n };\n}\n","import type { Ctx2D, FitMode, Size, Source } from \"../../types\";\n\nexport interface RendererOptions {\n width: number;\n height: number;\n dpr: number;\n keepalive: boolean;\n}\n\nexport interface Renderer {\n readonly captureCanvas: HTMLCanvasElement;\n readonly offscreenCtx: Ctx2D;\n readonly size: Size;\n\n setActiveSource(source: Source | null): void;\n renderFrame(timestamp: number): void;\n resize(width: number, height: number, dpr: number): void;\n setKeepalive(enabled: boolean): void;\n isSourceReady(source: Source): boolean;\n destroy(): void;\n}\n\ntype RectCache = {\n canvasW: number;\n canvasH: number;\n sourceW: number;\n sourceH: number;\n dx: number;\n dy: number;\n dw: number;\n dh: number;\n fit: FitMode;\n};\n\nexport function createRenderer(options: RendererOptions): Renderer {\n let size: Size = {\n width: options.width,\n height: options.height,\n dpr: Math.min(2, options.dpr),\n };\n let keepalive = options.keepalive;\n\n // Canvases\n let captureCanvas: HTMLCanvasElement | null = null;\n let captureCtx: Ctx2D | null = null;\n let offscreen: OffscreenCanvas | HTMLCanvasElement | null = null;\n let offscreenCtx: Ctx2D | null = null;\n\n // Source state\n let currentSource: Source | null = null;\n\n // Rendering state\n let frameIndex = 0;\n let rectCache = new WeakMap<\n HTMLCanvasElement | HTMLVideoElement,\n RectCache\n >();\n\n function initCanvas(): void {\n const canvas = document.createElement(\"canvas\");\n canvas.style.display = \"none\";\n\n const pxW = Math.round(size.width * size.dpr);\n const pxH = Math.round(size.height * size.dpr);\n const outW = Math.round(size.width);\n const outH = Math.round(size.height);\n\n canvas.width = outW;\n canvas.height = outH;\n\n const ctx = canvas.getContext(\"2d\", {\n alpha: false,\n desynchronized: true,\n }) as Ctx2D | null;\n\n if (!ctx) throw new Error(\"2D context not available\");\n\n captureCanvas = canvas;\n captureCtx = ctx;\n\n // Create offscreen canvas for DPR scaling\n try {\n const off = new OffscreenCanvas(pxW, pxH);\n offscreen = off;\n const offCtx = off.getContext(\"2d\", { alpha: false }) as Ctx2D | null;\n if (!offCtx) throw new Error(\"2D context not available for Offscreen\");\n offCtx.imageSmoothingEnabled = true;\n offscreenCtx = offCtx;\n } catch {\n // Fallback to HTMLCanvasElement\n const off = document.createElement(\"canvas\");\n off.width = pxW;\n off.height = pxH;\n const offCtx = off.getContext(\"2d\", { alpha: false }) as Ctx2D | null;\n if (!offCtx)\n throw new Error(\"2D context not available for Offscreen fallback\");\n offCtx.imageSmoothingEnabled = true;\n offscreen = off;\n offscreenCtx = offCtx;\n }\n\n // Initial fill\n offscreenCtx!.fillStyle = \"#111\";\n offscreenCtx!.fillRect(0, 0, pxW, pxH);\n captureCtx!.drawImage(\n offscreen as CanvasImageSource,\n 0,\n 0,\n pxW,\n pxH,\n 0,\n 0,\n outW,\n outH,\n );\n }\n\n function isSourceReady(source: Source): boolean {\n if (source.kind === \"video\") {\n const v = source.element;\n return (\n typeof v.readyState === \"number\" &&\n v.readyState >= 2 &&\n (v.videoWidth || 0) > 0 &&\n (v.videoHeight || 0) > 0\n );\n }\n // canvas\n const c = source.element;\n return (c.width || 0) > 0 && (c.height || 0) > 0;\n }\n\n function getDrawRect(\n el: HTMLCanvasElement | HTMLVideoElement,\n fit: FitMode,\n ): { dx: number; dy: number; dw: number; dh: number } | null {\n const canvas = offscreenCtx?.canvas;\n if (!canvas) return null;\n\n const canvasW = canvas.width;\n const canvasH = canvas.height;\n const sourceW = (el as HTMLVideoElement).videoWidth ?? el.width;\n const sourceH = (el as HTMLVideoElement).videoHeight ?? el.height;\n\n if (!sourceW || !sourceH) return null;\n\n const cached = rectCache.get(el);\n if (\n cached &&\n cached.canvasW === canvasW &&\n cached.canvasH === canvasH &&\n cached.sourceW === sourceW &&\n cached.sourceH === sourceH &&\n cached.fit === fit\n ) {\n return { dx: cached.dx, dy: cached.dy, dw: cached.dw, dh: cached.dh };\n }\n\n const scale =\n fit === \"cover\"\n ? Math.max(canvasW / sourceW, canvasH / sourceH)\n : Math.min(canvasW / sourceW, canvasH / sourceH);\n\n const dw = Math.floor(sourceW * scale);\n const dh = Math.floor(sourceH * scale);\n const dx = Math.floor((canvasW - dw) / 2);\n const dy = Math.floor((canvasH - dh) / 2);\n\n rectCache.set(el, {\n canvasW,\n canvasH,\n sourceW,\n sourceH,\n dx,\n dy,\n dw,\n dh,\n fit,\n });\n\n return { dx, dy, dw, dh };\n }\n\n function blitSource(source: Source): void {\n if (!offscreenCtx) return;\n const ctx = offscreenCtx;\n\n const el = source.element;\n const rect = getDrawRect(el, source.fit ?? \"contain\");\n if (!rect) return;\n\n ctx.drawImage(\n el as CanvasImageSource,\n rect.dx,\n rect.dy,\n rect.dw,\n rect.dh,\n );\n }\n\n // Initialize canvas on creation\n initCanvas();\n\n return {\n get captureCanvas(): HTMLCanvasElement {\n return captureCanvas!;\n },\n\n get offscreenCtx(): Ctx2D {\n return offscreenCtx!;\n },\n\n get size(): Size {\n return { ...size };\n },\n\n isSourceReady,\n\n setActiveSource(source: Source | null): void {\n currentSource = source;\n },\n\n renderFrame(_timestamp: number): void {\n const off = offscreenCtx;\n const cap = captureCtx;\n const capCanvas = captureCanvas;\n if (!off || !cap || !capCanvas) return;\n\n off.globalCompositeOperation = \"source-over\";\n\n if (currentSource && isSourceReady(currentSource)) {\n off.fillStyle = \"#000\";\n off.fillRect(0, 0, off.canvas.width, off.canvas.height);\n blitSource(currentSource);\n }\n\n // Keepalive pixel flicker\n if (keepalive) {\n const w = off.canvas.width;\n const h = off.canvas.height;\n const prevAlpha = off.globalAlpha;\n const prevFill = off.fillStyle;\n try {\n off.globalAlpha = 0.08;\n off.fillStyle = frameIndex % 2 ? \"#101010\" : \"#0e0e0e\";\n off.fillRect(w - 16, h - 16, 16, 16);\n } finally {\n off.globalAlpha = prevAlpha;\n off.fillStyle = prevFill;\n }\n }\n\n frameIndex++;\n\n // Blit offscreen to capture canvas\n cap.drawImage(\n off.canvas,\n 0,\n 0,\n off.canvas.width,\n off.canvas.height,\n 0,\n 0,\n capCanvas.width,\n capCanvas.height,\n );\n },\n\n resize(width: number, height: number, dpr: number): void {\n const nextDpr = Math.min(2, dpr);\n if (\n size.width === width &&\n size.height === height &&\n size.dpr === nextDpr\n ) {\n return;\n }\n\n size = { width, height, dpr: nextDpr };\n\n const pxW = Math.round(width * nextDpr);\n const pxH = Math.round(height * nextDpr);\n const outW = Math.round(width);\n const outH = Math.round(height);\n\n if (captureCanvas) {\n captureCanvas.width = outW;\n captureCanvas.height = outH;\n }\n\n if (offscreen instanceof HTMLCanvasElement) {\n offscreen.width = pxW;\n offscreen.height = pxH;\n } else if (offscreen instanceof OffscreenCanvas) {\n offscreen.width = pxW;\n offscreen.height = pxH;\n }\n\n rectCache = new WeakMap();\n },\n\n setKeepalive(enabled: boolean): void {\n keepalive = enabled;\n },\n\n destroy(): void {\n currentSource = null;\n captureCanvas = null;\n captureCtx = null;\n offscreen = null;\n offscreenCtx = null;\n },\n };\n}\n","export interface SchedulerOptions {\n fps: number;\n sendFps: number;\n onFrame: (timestamp: number) => void;\n onSendFpsChange?: (fps: number) => void;\n}\n\nexport interface Scheduler {\n start(videoElement?: HTMLVideoElement): void;\n stop(): void;\n setFps(fps: number): void;\n setSendFps(fps: number): void;\n readonly isRunning: boolean;\n readonly fps: number;\n readonly sendFps: number;\n}\n\nexport function createScheduler(options: SchedulerOptions): Scheduler {\n let fps = Math.max(1, options.fps);\n let sendFps = Math.max(1, options.sendFps);\n const onFrame = options.onFrame;\n const onSendFpsChange = options.onSendFpsChange;\n\n let isRunning = false;\n let lastFrameAt = 0;\n\n // RAF scheduling\n let rafId: number | null = null;\n let rafFallbackActive = false;\n\n // Video frame callback scheduling\n let videoFrameRequestId: number | null = null;\n let videoFrameSource: HTMLVideoElement | null = null;\n\n function getTimestamp(): number {\n return typeof performance !== \"undefined\" ? performance.now() : Date.now();\n }\n\n function shouldRenderFrame(): boolean {\n const now = getTimestamp();\n const minIntervalMs = 1000 / Math.max(1, sendFps);\n if (lastFrameAt !== 0 && now - lastFrameAt < minIntervalMs) {\n return false;\n }\n return true;\n }\n\n function renderIfNeeded(): void {\n if (!shouldRenderFrame()) return;\n const timestamp = getTimestamp();\n onFrame(timestamp);\n lastFrameAt = timestamp;\n }\n\n function scheduleWithRaf(isFallback: boolean): void {\n if (isFallback) {\n if (rafFallbackActive) return;\n rafFallbackActive = true;\n }\n\n const loop = (): void => {\n renderIfNeeded();\n rafId = requestAnimationFrame(loop);\n };\n\n rafId = requestAnimationFrame(loop);\n }\n\n function scheduleWithVideoFrame(videoEl: HTMLVideoElement): void {\n if (typeof videoEl.requestVideoFrameCallback !== \"function\") {\n scheduleWithRaf(false);\n return;\n }\n\n videoFrameSource = videoEl;\n\n const cb = (): void => {\n renderIfNeeded();\n if (videoFrameSource === videoEl) {\n try {\n videoFrameRequestId = videoEl.requestVideoFrameCallback(cb);\n } catch {\n // Failed to request video frame callback\n }\n }\n };\n\n try {\n videoFrameRequestId = videoEl.requestVideoFrameCallback(cb);\n } catch {\n // Failed to start video frame callback\n }\n\n // Also schedule RAF as fallback for non-video frames\n scheduleWithRaf(true);\n }\n\n function cancelSchedulers(): void {\n if (rafId != null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n rafFallbackActive = false;\n\n if (videoFrameRequestId && videoFrameSource) {\n try {\n if (typeof videoFrameSource.cancelVideoFrameCallback === \"function\") {\n videoFrameSource.cancelVideoFrameCallback(videoFrameRequestId);\n }\n } catch {\n // Failed to cancel video frame callback\n }\n }\n videoFrameRequestId = null;\n videoFrameSource = null;\n }\n\n return {\n get isRunning(): boolean {\n return isRunning;\n },\n\n get fps(): number {\n return fps;\n },\n\n get sendFps(): number {\n return sendFps;\n },\n\n start(videoElement?: HTMLVideoElement): void {\n if (isRunning) {\n cancelSchedulers();\n }\n\n isRunning = true;\n lastFrameAt = 0;\n\n if (\n videoElement &&\n typeof videoElement.requestVideoFrameCallback === \"function\"\n ) {\n scheduleWithVideoFrame(videoElement);\n } else {\n scheduleWithRaf(false);\n }\n },\n\n stop(): void {\n isRunning = false;\n cancelSchedulers();\n },\n\n setFps(newFps: number): void {\n fps = Math.max(1, newFps);\n },\n\n setSendFps(newSendFps: number): void {\n const next = Math.max(1, newSendFps);\n if (sendFps === next) return;\n sendFps = next;\n onSendFpsChange?.(sendFps);\n },\n };\n}\n","export interface AudioManagerOptions {\n autoUnlock: boolean;\n unlockEvents: string[];\n disableSilentAudio: boolean;\n}\n\nexport interface AudioManager {\n setOutputStream(stream: MediaStream): void;\n addTrack(track: MediaStreamTrack): void;\n removeTrack(trackId: string): void;\n unlock(): Promise<boolean>;\n destroy(): void;\n}\n\ndeclare global {\n interface Window {\n webkitAudioContext?: typeof AudioContext;\n }\n}\n\nexport function createAudioManager(options: AudioManagerOptions): AudioManager {\n let outputStream: MediaStream | null = null;\n\n // Audio context and silent track\n let audioCtx: AudioContext | null = null;\n let silentOsc: OscillatorNode | null = null;\n let silentGain: GainNode | null = null;\n let audioDst: MediaStreamAudioDestinationNode | null = null;\n let silentAudioTrack: MediaStreamTrack | null = null;\n\n // External tracks\n const externalAudioTrackIds = new Set<string>();\n const externalAudioEndHandlers = new Map<string, (ev: Event) => void>();\n\n // Auto unlock\n let audioUnlockHandler: ((ev: Event) => void) | null = null;\n let audioUnlockAttached = false;\n let audioStateListenerAttached = false;\n\n function ensureSilentAudioTrack(): void {\n if (options.disableSilentAudio) return;\n if (!outputStream) return;\n\n const alreadyHasAudio = outputStream.getAudioTracks().length > 0;\n if (alreadyHasAudio) return;\n\n if (silentAudioTrack && silentAudioTrack.readyState === \"live\") {\n try {\n outputStream.addTrack(silentAudioTrack);\n } catch {\n // Failed to add silent track\n }\n return;\n }\n\n if (!audioCtx) {\n const AudioContextClass = window.AudioContext || window.webkitAudioContext;\n if (!AudioContextClass) return;\n\n audioCtx = new AudioContextClass({\n sampleRate: 48000,\n });\n try {\n audioCtx.resume().catch(() => {\n // Failed to resume AudioContext\n });\n } catch {\n // Error calling resume\n }\n attachAudioCtxStateListener();\n }\n\n const ac = audioCtx;\n if (!ac) return;\n\n silentOsc = ac.createOscillator();\n silentGain = ac.createGain();\n audioDst = ac.createMediaStreamDestination();\n\n silentGain.gain.setValueAtTime(0.0001, ac.currentTime);\n silentOsc.frequency.setValueAtTime(440, ac.currentTime);\n silentOsc.type = \"sine\";\n silentOsc.connect(silentGain);\n silentGain.connect(audioDst);\n silentOsc.start();\n\n const track = audioDst.stream.getAudioTracks()[0];\n if (track) {\n silentAudioTrack = track;\n try {\n outputStream.addTrack(track);\n } catch {\n // Failed to add track to stream\n }\n }\n }\n\n function removeSilentAudioTrack(): void {\n try {\n if (outputStream && silentAudioTrack) {\n try {\n outputStream.removeTrack(silentAudioTrack);\n } catch {\n // Failed to remove silent track\n }\n }\n if (silentOsc) {\n try {\n silentOsc.stop();\n } catch {\n // Failed to stop oscillator\n }\n try {\n silentOsc.disconnect();\n } catch {\n // Failed to disconnect oscillator\n }\n }\n if (silentGain) {\n try {\n silentGain.disconnect();\n } catch {\n // Failed to disconnect gain\n }\n }\n silentOsc = null;\n silentGain = null;\n audioDst = null;\n silentAudioTrack = null;\n if (audioCtx) {\n try {\n audioCtx.close();\n } catch {\n // Failed to close AudioContext\n }\n }\n audioCtx = null;\n } catch {\n // Error in removeSilentAudioTrack\n }\n }\n\n function rebuildSilentAudioTrack(): void {\n if (options.disableSilentAudio) return;\n if (!outputStream) return;\n if (externalAudioTrackIds.size > 0) return;\n\n if (silentAudioTrack) {\n try {\n outputStream.removeTrack(silentAudioTrack);\n } catch {\n // Failed to remove silent track\n }\n }\n\n if (silentOsc) {\n try {\n silentOsc.stop();\n } catch {\n // Failed to stop oscillator\n }\n try {\n silentOsc.disconnect();\n } catch {\n // Failed to disconnect oscillator\n }\n }\n if (silentGain) {\n try {\n silentGain.disconnect();\n } catch {\n // Failed to disconnect gain\n }\n }\n silentOsc = null;\n silentGain = null;\n audioDst = null;\n silentAudioTrack = null;\n\n const ac = audioCtx;\n if (!ac || ac.state !== \"running\") return;\n\n attachAudioCtxStateListener();\n\n silentOsc = ac.createOscillator();\n silentGain = ac.createGain();\n audioDst = ac.createMediaStreamDestination();\n\n silentGain.gain.setValueAtTime(0.0001, ac.currentTime);\n silentOsc.frequency.setValueAtTime(440, ac.currentTime);\n silentOsc.type = \"sine\";\n silentOsc.connect(silentGain);\n silentGain.connect(audioDst);\n silentOsc.start();\n\n const track = audioDst.stream.getAudioTracks()[0];\n if (track) {\n silentAudioTrack = track;\n try {\n outputStream.addTrack(track);\n } catch {\n // Failed to add track to stream\n }\n }\n }\n\n function attachAudioCtxStateListener(): void {\n const ac = audioCtx;\n if (!ac || audioStateListenerAttached) return;\n\n const onStateChange = (): void => {\n try {\n if (audioCtx && audioCtx.state === \"running\") {\n rebuildSilentAudioTrack();\n cleanupAudioAutoUnlock();\n }\n } catch {\n // Error in state change handler\n }\n };\n\n try {\n (ac as AudioContext & { onstatechange: (() => void) | null }).onstatechange = onStateChange;\n audioStateListenerAttached = true;\n } catch {\n // Failed to attach state listener\n }\n }\n\n function setupAudioAutoUnlock(): void {\n if (!options.autoUnlock) return;\n if (typeof document === \"undefined\") return;\n if (audioUnlockAttached) return;\n\n const handler = (): void => {\n unlock();\n };\n\n audioUnlockHandler = handler;\n options.unlockEvents.forEach((evt) => {\n try {\n document.addEventListener(evt, handler, { capture: true });\n } catch {\n // Failed to add unlock listener\n }\n });\n audioUnlockAttached = true;\n }\n\n function cleanupAudioAutoUnlock(): void {\n if (!audioUnlockAttached) return;\n if (typeof document !== \"undefined\" && audioUnlockHandler) {\n options.unlockEvents.forEach((evt) => {\n try {\n document.removeEventListener(evt, audioUnlockHandler!, {\n capture: true,\n });\n } catch {\n // Failed to remove unlock listener\n }\n });\n }\n audioUnlockAttached = false;\n audioUnlockHandler = null;\n }\n\n async function unlock(): Promise<boolean> {\n try {\n if (typeof window === \"undefined\") return false;\n\n if (!audioCtx || audioCtx.state === \"closed\") {\n const AudioContextClass = window.AudioContext || window.webkitAudioContext;\n if (!AudioContextClass) return false;\n\n audioCtx = new AudioContextClass({\n sampleRate: 48000,\n });\n }\n\n const ac = audioCtx;\n if (!ac) return false;\n\n try {\n await ac.resume();\n } catch {\n // Failed to resume AudioContext\n }\n\n attachAudioCtxStateListener();\n\n if (ac.state === \"running\") {\n rebuildSilentAudioTrack();\n cleanupAudioAutoUnlock();\n return true;\n }\n\n return false;\n } catch {\n // Error in unlock\n return false;\n }\n }\n\n // Setup auto unlock on creation\n setupAudioAutoUnlock();\n\n return {\n setOutputStream(stream: MediaStream): void {\n outputStream = stream;\n ensureSilentAudioTrack();\n },\n\n addTrack(track: MediaStreamTrack): void {\n if (!outputStream) return;\n\n try {\n // Remove silent track when adding external audio\n if (silentAudioTrack) {\n try {\n outputStream.removeTrack(silentAudioTrack);\n } catch {\n // Failed to remove silent track\n }\n }\n\n const exists = outputStream\n .getAudioTracks()\n .some((t) => t.id === track.id);\n if (!exists) {\n outputStream.addTrack(track);\n }\n externalAudioTrackIds.add(track.id);\n\n // Setup ended handler\n const onEnded = (): void => {\n try {\n if (!outputStream) return;\n outputStream.getAudioTracks().forEach((t) => {\n if (t.id === track.id) {\n try {\n outputStream!.removeTrack(t);\n } catch {\n // Failed to remove ended track\n }\n }\n });\n externalAudioTrackIds.delete(track.id);\n externalAudioEndHandlers.delete(track.id);\n\n if (outputStream.getAudioTracks().length === 0) {\n ensureSilentAudioTrack();\n }\n } catch {\n // Error in track ended handler\n }\n try {\n track.removeEventListener(\"ended\", onEnded);\n } catch {\n // Failed to remove ended listener\n }\n };\n\n track.addEventListener(\"ended\", onEnded);\n externalAudioEndHandlers.set(track.id, onEnded);\n } catch {\n // Error in addTrack\n }\n },\n\n removeTrack(trackId: string): void {\n if (!outputStream) return;\n\n outputStream.getAudioTracks().forEach((t) => {\n if (t.id === trackId) {\n outputStream!.removeTrack(t);\n }\n });\n\n externalAudioTrackIds.delete(trackId);\n\n const handler = externalAudioEndHandlers.get(trackId);\n const tracks = outputStream.getAudioTracks();\n const tr = tracks.find((t) => t.id === trackId);\n if (tr && handler) {\n try {\n tr.removeEventListener(\"ended\", handler);\n } catch {\n // Failed to remove ended listener\n }\n }\n externalAudioEndHandlers.delete(trackId);\n\n if (outputStream.getAudioTracks().length === 0) {\n ensureSilentAudioTrack();\n }\n },\n\n unlock,\n\n destroy(): void {\n cleanupAudioAutoUnlock();\n\n try {\n if (audioCtx && (audioCtx as AudioContext & { onstatechange: (() => void) | null }).onstatechange) {\n (audioCtx as AudioContext & { onstatechange: (() => void) | null }).onstatechange = null;\n }\n } catch {\n // Failed to clear state change handler\n }\n audioStateListenerAttached = false;\n\n // Cleanup external track handlers\n externalAudioEndHandlers.forEach((handler, id) => {\n try {\n const tr = outputStream?.getAudioTracks().find((t) => t.id === id);\n if (tr) tr.removeEventListener(\"ended\", handler);\n } catch {\n // Failed to cleanup track handler\n }\n });\n externalAudioEndHandlers.clear();\n externalAudioTrackIds.clear();\n\n removeSilentAudioTrack();\n outputStream = null;\n },\n };\n}\n","export interface VisibilityHandlerOptions {\n onHidden: () => void;\n onVisible: () => void;\n backgroundRenderFn: () => void;\n}\n\nexport interface VisibilityHandler {\n start(): void;\n stop(): void;\n readonly isHidden: boolean;\n}\n\nexport function createVisibilityHandler(\n options: VisibilityHandlerOptions,\n): VisibilityHandler {\n let isHidden = false;\n let backgroundIntervalId: number | null = null;\n let visibilityListener: (() => void) | null = null;\n let started = false;\n\n function onVisibilityChange(): void {\n if (typeof document === \"undefined\") return;\n\n const hidden = document.visibilityState === \"hidden\";\n\n if (hidden && !isHidden) {\n isHidden = true;\n options.onHidden();\n\n // Start background interval rendering\n if (backgroundIntervalId == null) {\n backgroundIntervalId = setInterval(() => {\n options.backgroundRenderFn();\n }, 1000) as unknown as number;\n }\n } else if (!hidden && isHidden) {\n isHidden = false;\n\n // Stop background interval\n if (backgroundIntervalId != null) {\n clearInterval(backgroundIntervalId);\n backgroundIntervalId = null;\n }\n\n options.onVisible();\n }\n }\n\n return {\n get isHidden(): boolean {\n return isHidden;\n },\n\n start(): void {\n if (started) return;\n if (typeof document === \"undefined\") return;\n\n started = true;\n visibilityListener = onVisibilityChange;\n document.addEventListener(\"visibilitychange\", visibilityListener);\n\n // Check initial state\n onVisibilityChange();\n },\n\n stop(): void {\n if (!started) return;\n started = false;\n\n if (typeof document !== \"undefined\" && visibilityListener) {\n try {\n document.removeEventListener(\"visibilitychange\", visibilityListener);\n } catch {\n // Failed to remove visibility listener\n }\n visibilityListener = null;\n }\n\n if (backgroundIntervalId != null) {\n clearInterval(backgroundIntervalId);\n backgroundIntervalId = null;\n }\n\n isHidden = false;\n },\n };\n}\n","import { createRegistry } from \"./internal/compositor/Registry\";\nimport { createRenderer, type Renderer } from \"./internal/compositor/Renderer\";\nimport { createScheduler, type Scheduler } from \"./internal/compositor/Scheduler\";\nimport { createAudioManager, type AudioManager } from \"./internal/compositor/AudioManager\";\nimport { createVisibilityHandler, type VisibilityHandler } from \"./internal/compositor/VisibilityHandler\";\nimport type {\n Compositor as ICompositor,\n CompositorEvent,\n CompositorEventMap,\n CompositorOptions,\n Size,\n Source,\n} from \"./types\";\nimport type { SourceRegistry } from \"./internal/compositor/Registry\";\n\nclass CompositorEventEmitter {\n private listeners = new Map<CompositorEvent, Set<CompositorEventMap[CompositorEvent]>>();\n\n on<E extends CompositorEvent>(event: E, handler: CompositorEventMap[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as CompositorEventMap[CompositorEvent]);\n return () => this.off(event, handler);\n }\n\n off<E extends CompositorEvent>(event: E, handler: CompositorEventMap[E]): void {\n this.listeners.get(event)?.delete(handler as CompositorEventMap[CompositorEvent]);\n }\n\n protected emit<E extends CompositorEvent>(\n event: E,\n ...args: Parameters<CompositorEventMap[E]>\n ): void {\n this.listeners.get(event)?.forEach((handler) => {\n (handler as (...args: Parameters<CompositorEventMap[E]>) => void)(...args);\n });\n }\n\n protected clearListeners(): void {\n this.listeners.clear();\n }\n}\n\nexport class Compositor extends CompositorEventEmitter implements ICompositor {\n private readonly registry: SourceRegistry;\n private readonly renderer: Renderer;\n private readonly scheduler: Scheduler;\n private readonly audioManager: AudioManager;\n private readonly visibilityHandler: VisibilityHandler;\n\n private _activeId: string | null = null;\n private _fps: number;\n private _sendFps: number;\n private lastVisibleSendFps: number | null = null;\n private outputStream: MediaStream | null = null;\n private destroyed = false;\n\n constructor(options: CompositorOptions = {}) {\n super();\n\n const width = options.width ?? 512;\n const height = options.height ?? 512;\n this._fps = Math.max(1, options.fps ?? 30);\n this._sendFps = Math.max(1, options.sendFps ?? this._fps);\n const dpr = Math.min(\n 2,\n options.dpr ??\n (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1),\n );\n const keepalive = options.keepalive ?? true;\n\n // Create subsystems\n this.registry = createRegistry({\n onRegister: (id, source) => this.emit(\"registered\", id, source),\n onUnregister: (id) => this.emit(\"unregistered\", id),\n });\n\n this.renderer = createRenderer({\n width,\n height,\n dpr,\n keepalive,\n });\n\n this.scheduler = createScheduler({\n fps: this._fps,\n sendFps: this._sendFps,\n onFrame: (timestamp) => this.renderer.renderFrame(timestamp),\n onSendFpsChange: (fps) => {\n this._sendFps = fps;\n options.onSendFpsChange?.(fps);\n this.applyVideoTrackConstraints();\n },\n });\n\n this.audioManager = createAudioManager({\n autoUnlock: options.autoUnlockAudio ?? true,\n unlockEvents:\n options.unlockEvents && options.unlockEvents.length > 0\n ? options.unlockEvents\n : [\"pointerdown\", \"click\", \"touchstart\", \"keydown\"],\n disableSilentAudio: options.disableSilentAudio ?? false,\n });\n\n this.visibilityHandler = createVisibilityHandler({\n onHidden: () => {\n if (this.lastVisibleSendFps == null) this.lastVisibleSendFps = this._sendFps;\n if (this._sendFps !== 5) {\n this.scheduler.setSendFps(5);\n this._sendFps = 5;\n }\n },\n onVisible: () => {\n if (this.lastVisibleSendFps != null && this._sendFps !== this.lastVisibleSendFps) {\n this.scheduler.setSendFps(this.lastVisibleSendFps);\n this._sendFps = this.lastVisibleSendFps;\n }\n this.lastVisibleSendFps = null;\n },\n backgroundRenderFn: () => {\n this.renderer.renderFrame(performance.now());\n this.requestVideoTrackFrame();\n },\n });\n\n // Initialize\n this.outputStream = this.createOutputStream();\n this.audioManager.setOutputStream(this.outputStream);\n this.visibilityHandler.start();\n }\n\n // ============================================================================\n // Source Registry\n // ============================================================================\n\n register(id: string, source: Source): void {\n if (this.destroyed) return;\n this.registry.register(id, source);\n }\n\n unregister(id: string): void {\n if (this.destroyed) return;\n const wasActive = this._activeId === id;\n this.registry.unregister(id);\n\n if (wasActive) {\n this._activeId = null;\n this.renderer.setActiveSource(null);\n this.scheduler.stop();\n this.emit(\"activated\", null, undefined);\n }\n }\n\n get(id: string): Source | undefined {\n return this.registry.get(id);\n }\n\n has(id: string): boolean {\n return this.registry.has(id);\n }\n\n list(): Array<{ id: string; source: Source }> {\n return this.registry.list();\n }\n\n // ============================================================================\n // Active Source Management\n // ============================================================================\n\n activate(id: string): void {\n if (this.destroyed) return;\n\n const source = this.registry.get(id);\n if (!source) {\n throw new Error(`Source \"${id}\" not registered`);\n }\n\n this._activeId = id;\n this.renderer.setActiveSource(source);\n\n // Start scheduler with video element if applicable\n const videoEl = source.kind === \"video\" ? source.element : undefined;\n this.scheduler.start(videoEl);\n\n this.emit(\"activated\", id, source);\n }\n\n deactivate(): void {\n if (this.destroyed) return;\n\n this._activeId = null;\n this.renderer.setActiveSource(null);\n this.scheduler.stop();\n this.emit(\"activated\", null, undefined);\n }\n\n get activeId(): string | null {\n return this._activeId;\n }\n\n // ============================================================================\n // Output Stream\n // ============================================================================\n\n get stream(): MediaStream {\n return this.outputStream!;\n }\n\n // ============================================================================\n // Settings\n // ============================================================================\n\n resize(width: number, height: number, dpr?: number): void {\n if (this.destroyed) return;\n\n const effectiveDpr = Math.min(\n 2,\n dpr ??\n (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1),\n );\n\n this.renderer.resize(width, height, effectiveDpr);\n this.recreateStream();\n }\n\n get size(): Size {\n return this.renderer.size;\n }\n\n setFps(fps: number): void {\n if (this.destroyed) return;\n\n const next = Math.max(1, fps);\n if (this._fps === next) return;\n\n this._fps = next;\n this.scheduler.setFps(next);\n this.recreateStream();\n }\n\n get fps(): number {\n return this._fps;\n }\n\n setSendFps(fps: number): void {\n if (this.destroyed) return;\n\n const next = Math.max(1, fps);\n if (this._sendFps === next) return;\n\n this._sendFps = next;\n this.scheduler.setSendFps(next);\n }\n\n get sendFps(): number {\n return this._sendFps;\n }\n\n // ============================================================================\n // Audio\n // ============================================================================\n\n addAudioTrack(track: MediaStreamTrack): void {\n if (this.destroyed) return;\n this.audioManager.addTrack(track);\n }\n\n removeAudioTrack(trackId: string): void {\n if (this.destroyed) return;\n this.audioManager.removeTrack(trackId);\n }\n\n unlockAudio(): Promise<boolean> {\n if (this.destroyed) return Promise.resolve(false);\n return this.audioManager.unlock();\n }\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n\n this.scheduler.stop();\n this.visibilityHandler.stop();\n this.audioManager.destroy();\n this.renderer.destroy();\n this.registry.clear();\n\n // Stop video tracks\n if (this.outputStream) {\n try {\n this.outputStream.getVideoTracks().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Failed to stop video track\n }\n });\n } catch {\n // Failed to get video tracks\n }\n }\n\n this.outputStream = null;\n this.clearListeners();\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n private createOutputStream(): MediaStream {\n const stream = this.renderer.captureCanvas.captureStream(this._fps);\n\n // Set video track content hint\n try {\n const vtrack = stream.getVideoTracks()[0];\n if (vtrack && vtrack.contentHint !== undefined) {\n vtrack.contentHint = \"detail\";\n }\n } catch {\n // Failed to set video track content hint\n }\n\n return stream;\n }\n\n private recreateStream(): void {\n const newStream = this.createOutputStream();\n const prev = this.outputStream;\n\n // Transfer audio tracks\n if (prev && prev !== newStream) {\n try {\n prev.getAudioTracks().forEach((t) => {\n try {\n newStream.addTrack(t);\n } catch {\n // Failed to transfer audio track\n }\n });\n } catch {\n // Failed to get audio tracks\n }\n }\n\n this.outputStream = newStream;\n this.audioManager.setOutputStream(newStream);\n this.applyVideoTrackConstraints();\n\n // Stop old video tracks\n if (prev && prev !== newStream) {\n try {\n prev.getVideoTracks().forEach((t) => {\n try {\n t.stop();\n } catch {\n // Failed to stop video track\n }\n });\n } catch {\n // Failed to get video tracks\n }\n }\n }\n\n private applyVideoTrackConstraints(): void {\n try {\n const track = this.outputStream?.getVideoTracks()[0];\n const canvas = this.renderer.captureCanvas;\n if (!track || !canvas) return;\n\n const constraints: MediaTrackConstraints = {\n width: canvas.width,\n height: canvas.height,\n frameRate: Math.max(1, this._sendFps || this._fps),\n };\n\n try {\n if ((track as MediaStreamTrack & { contentHint?: string }).contentHint !== undefined) {\n (track as MediaStreamTrack & { contentHint?: string }).contentHint = \"detail\";\n }\n } catch {\n // Failed to set content hint\n }\n\n track.applyConstraints(constraints).catch(() => {\n // Failed to apply constraints\n });\n } catch {\n // Error in applyVideoTrackConstraints\n }\n }\n\n private requestVideoTrackFrame(): void {\n const track = this.outputStream?.getVideoTracks()[0];\n if (track && typeof (track as MediaStreamTrack & { requestFrame?: () => void }).requestFrame === \"function\") {\n try {\n (track as MediaStreamTrack & { requestFrame: () => void }).requestFrame();\n } catch {\n // Failed to request video frame\n }\n }\n }\n}\n\nexport function createCompositor(options: CompositorOptions = {}): Compositor {\n return new Compositor(options);\n}\n"],"mappings":"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","names":["createBroadcast","createPlayer","DEFAULT_CONNECTION_TIMEOUT","createBroadcast","createPlayer"]}
|