@livepeer-frameworks/player-core 0.1.1 → 0.1.2
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/cjs/core/ABRController.js +456 -0
- package/dist/cjs/core/ABRController.js.map +1 -0
- package/dist/cjs/core/CodecUtils.js +195 -0
- package/dist/cjs/core/CodecUtils.js.map +1 -0
- package/dist/cjs/core/ErrorClassifier.js +410 -0
- package/dist/cjs/core/ErrorClassifier.js.map +1 -0
- package/dist/cjs/core/EventEmitter.js +108 -0
- package/dist/cjs/core/EventEmitter.js.map +1 -0
- package/dist/cjs/core/GatewayClient.js +342 -0
- package/dist/cjs/core/GatewayClient.js.map +1 -0
- package/dist/cjs/core/InteractionController.js +606 -0
- package/dist/cjs/core/InteractionController.js.map +1 -0
- package/dist/cjs/core/LiveDurationProxy.js +186 -0
- package/dist/cjs/core/LiveDurationProxy.js.map +1 -0
- package/dist/cjs/core/MetaTrackManager.js +624 -0
- package/dist/cjs/core/MetaTrackManager.js.map +1 -0
- package/dist/cjs/core/MistReporter.js +449 -0
- package/dist/cjs/core/MistReporter.js.map +1 -0
- package/dist/cjs/core/MistSignaling.js +264 -0
- package/dist/cjs/core/MistSignaling.js.map +1 -0
- package/dist/cjs/core/PlayerController.js +2658 -0
- package/dist/cjs/core/PlayerController.js.map +1 -0
- package/dist/cjs/core/PlayerInterface.js +269 -0
- package/dist/cjs/core/PlayerInterface.js.map +1 -0
- package/dist/cjs/core/PlayerManager.js +806 -0
- package/dist/cjs/core/PlayerManager.js.map +1 -0
- package/dist/cjs/core/PlayerRegistry.js +270 -0
- package/dist/cjs/core/PlayerRegistry.js.map +1 -0
- package/dist/cjs/core/QualityMonitor.js +474 -0
- package/dist/cjs/core/QualityMonitor.js.map +1 -0
- package/dist/cjs/core/SeekingUtils.js +292 -0
- package/dist/cjs/core/SeekingUtils.js.map +1 -0
- package/dist/cjs/core/StreamStateClient.js +381 -0
- package/dist/cjs/core/StreamStateClient.js.map +1 -0
- package/dist/cjs/core/SubtitleManager.js +227 -0
- package/dist/cjs/core/SubtitleManager.js.map +1 -0
- package/dist/cjs/core/TelemetryReporter.js +258 -0
- package/dist/cjs/core/TelemetryReporter.js.map +1 -0
- package/dist/cjs/core/TimeFormat.js +176 -0
- package/dist/cjs/core/TimeFormat.js.map +1 -0
- package/dist/cjs/core/TimerManager.js +176 -0
- package/dist/cjs/core/TimerManager.js.map +1 -0
- package/dist/cjs/core/UrlUtils.js +160 -0
- package/dist/cjs/core/UrlUtils.js.map +1 -0
- package/dist/cjs/core/detector.js +293 -0
- package/dist/cjs/core/detector.js.map +1 -0
- package/dist/cjs/core/scorer.js +443 -0
- package/dist/cjs/core/scorer.js.map +1 -0
- package/dist/cjs/index.js +121 -20134
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/utils.js +11 -0
- package/dist/cjs/lib/utils.js.map +1 -0
- package/dist/cjs/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js +6 -0
- package/dist/cjs/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/cjs/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js +3042 -0
- package/dist/cjs/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/cjs/players/DashJsPlayer.js +638 -0
- package/dist/cjs/players/DashJsPlayer.js.map +1 -0
- package/dist/cjs/players/HlsJsPlayer.js +482 -0
- package/dist/cjs/players/HlsJsPlayer.js.map +1 -0
- package/dist/cjs/players/MewsWsPlayer/SourceBufferManager.js +522 -0
- package/dist/cjs/players/MewsWsPlayer/SourceBufferManager.js.map +1 -0
- package/dist/cjs/players/MewsWsPlayer/WebSocketManager.js +215 -0
- package/dist/cjs/players/MewsWsPlayer/WebSocketManager.js.map +1 -0
- package/dist/cjs/players/MewsWsPlayer/index.js +987 -0
- package/dist/cjs/players/MewsWsPlayer/index.js.map +1 -0
- package/dist/cjs/players/MistPlayer.js +185 -0
- package/dist/cjs/players/MistPlayer.js.map +1 -0
- package/dist/cjs/players/MistWebRTCPlayer/index.js +635 -0
- package/dist/cjs/players/MistWebRTCPlayer/index.js.map +1 -0
- package/dist/cjs/players/NativePlayer.js +762 -0
- package/dist/cjs/players/NativePlayer.js.map +1 -0
- package/dist/cjs/players/VideoJsPlayer.js +585 -0
- package/dist/cjs/players/VideoJsPlayer.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/JitterBuffer.js +236 -0
- package/dist/cjs/players/WebCodecsPlayer/JitterBuffer.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/LatencyProfiles.js +143 -0
- package/dist/cjs/players/WebCodecsPlayer/LatencyProfiles.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/RawChunkParser.js +96 -0
- package/dist/cjs/players/WebCodecsPlayer/RawChunkParser.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/SyncController.js +359 -0
- package/dist/cjs/players/WebCodecsPlayer/SyncController.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/WebSocketController.js +460 -0
- package/dist/cjs/players/WebCodecsPlayer/WebSocketController.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/index.js +1467 -0
- package/dist/cjs/players/WebCodecsPlayer/index.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js +320 -0
- package/dist/cjs/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js.map +1 -0
- package/dist/cjs/styles/index.js +57 -0
- package/dist/cjs/styles/index.js.map +1 -0
- package/dist/cjs/vanilla/FrameWorksPlayer.js +269 -0
- package/dist/cjs/vanilla/FrameWorksPlayer.js.map +1 -0
- package/dist/cjs/vanilla.js +11 -0
- package/dist/cjs/vanilla.js.map +1 -0
- package/dist/esm/core/ABRController.js +454 -0
- package/dist/esm/core/ABRController.js.map +1 -0
- package/dist/esm/core/CodecUtils.js +193 -0
- package/dist/esm/core/CodecUtils.js.map +1 -0
- package/dist/esm/core/ErrorClassifier.js +408 -0
- package/dist/esm/core/ErrorClassifier.js.map +1 -0
- package/dist/esm/core/EventEmitter.js +106 -0
- package/dist/esm/core/EventEmitter.js.map +1 -0
- package/dist/esm/core/GatewayClient.js +340 -0
- package/dist/esm/core/GatewayClient.js.map +1 -0
- package/dist/esm/core/InteractionController.js +604 -0
- package/dist/esm/core/InteractionController.js.map +1 -0
- package/dist/esm/core/LiveDurationProxy.js +184 -0
- package/dist/esm/core/LiveDurationProxy.js.map +1 -0
- package/dist/esm/core/MetaTrackManager.js +622 -0
- package/dist/esm/core/MetaTrackManager.js.map +1 -0
- package/dist/esm/core/MistReporter.js +447 -0
- package/dist/esm/core/MistReporter.js.map +1 -0
- package/dist/esm/core/MistSignaling.js +262 -0
- package/dist/esm/core/MistSignaling.js.map +1 -0
- package/dist/esm/core/PlayerController.js +2651 -0
- package/dist/esm/core/PlayerController.js.map +1 -0
- package/dist/esm/core/PlayerInterface.js +267 -0
- package/dist/esm/core/PlayerInterface.js.map +1 -0
- package/dist/esm/core/PlayerManager.js +804 -0
- package/dist/esm/core/PlayerManager.js.map +1 -0
- package/dist/esm/core/PlayerRegistry.js +264 -0
- package/dist/esm/core/PlayerRegistry.js.map +1 -0
- package/dist/esm/core/QualityMonitor.js +471 -0
- package/dist/esm/core/QualityMonitor.js.map +1 -0
- package/dist/esm/core/SeekingUtils.js +280 -0
- package/dist/esm/core/SeekingUtils.js.map +1 -0
- package/dist/esm/core/StreamStateClient.js +379 -0
- package/dist/esm/core/StreamStateClient.js.map +1 -0
- package/dist/esm/core/SubtitleManager.js +225 -0
- package/dist/esm/core/SubtitleManager.js.map +1 -0
- package/dist/esm/core/TelemetryReporter.js +256 -0
- package/dist/esm/core/TelemetryReporter.js.map +1 -0
- package/dist/esm/core/TimeFormat.js +169 -0
- package/dist/esm/core/TimeFormat.js.map +1 -0
- package/dist/esm/core/TimerManager.js +174 -0
- package/dist/esm/core/TimerManager.js.map +1 -0
- package/dist/esm/core/UrlUtils.js +151 -0
- package/dist/esm/core/UrlUtils.js.map +1 -0
- package/dist/esm/core/detector.js +279 -0
- package/dist/esm/core/detector.js.map +1 -0
- package/dist/esm/core/scorer.js +422 -0
- package/dist/esm/core/scorer.js.map +1 -0
- package/dist/esm/index.js +26 -20043
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/utils.js +9 -0
- package/dist/esm/lib/utils.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js +4 -0
- package/dist/esm/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js +3036 -0
- package/dist/esm/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/esm/players/DashJsPlayer.js +636 -0
- package/dist/esm/players/DashJsPlayer.js.map +1 -0
- package/dist/esm/players/HlsJsPlayer.js +480 -0
- package/dist/esm/players/HlsJsPlayer.js.map +1 -0
- package/dist/esm/players/MewsWsPlayer/SourceBufferManager.js +520 -0
- package/dist/esm/players/MewsWsPlayer/SourceBufferManager.js.map +1 -0
- package/dist/esm/players/MewsWsPlayer/WebSocketManager.js +213 -0
- package/dist/esm/players/MewsWsPlayer/WebSocketManager.js.map +1 -0
- package/dist/esm/players/MewsWsPlayer/index.js +985 -0
- package/dist/esm/players/MewsWsPlayer/index.js.map +1 -0
- package/dist/esm/players/MistPlayer.js +183 -0
- package/dist/esm/players/MistPlayer.js.map +1 -0
- package/dist/esm/players/MistWebRTCPlayer/index.js +633 -0
- package/dist/esm/players/MistWebRTCPlayer/index.js.map +1 -0
- package/dist/esm/players/NativePlayer.js +759 -0
- package/dist/esm/players/NativePlayer.js.map +1 -0
- package/dist/esm/players/VideoJsPlayer.js +583 -0
- package/dist/esm/players/VideoJsPlayer.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/JitterBuffer.js +233 -0
- package/dist/esm/players/WebCodecsPlayer/JitterBuffer.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/LatencyProfiles.js +134 -0
- package/dist/esm/players/WebCodecsPlayer/LatencyProfiles.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/RawChunkParser.js +91 -0
- package/dist/esm/players/WebCodecsPlayer/RawChunkParser.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/SyncController.js +357 -0
- package/dist/esm/players/WebCodecsPlayer/SyncController.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/WebSocketController.js +458 -0
- package/dist/esm/players/WebCodecsPlayer/WebSocketController.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/index.js +1458 -0
- package/dist/esm/players/WebCodecsPlayer/index.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js +315 -0
- package/dist/esm/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js.map +1 -0
- package/dist/esm/styles/index.js +54 -0
- package/dist/esm/styles/index.js.map +1 -0
- package/dist/esm/vanilla/FrameWorksPlayer.js +264 -0
- package/dist/esm/vanilla/FrameWorksPlayer.js.map +1 -0
- package/dist/esm/vanilla.js +2 -0
- package/dist/esm/vanilla.js.map +1 -0
- package/dist/player.css +4 -1
- package/dist/types/core/ABRController.d.ts +4 -4
- package/dist/types/core/CodecUtils.d.ts +1 -1
- package/dist/types/core/ErrorClassifier.d.ts +77 -0
- package/dist/types/core/GatewayClient.d.ts +4 -4
- package/dist/types/core/MetaTrackManager.d.ts +2 -2
- package/dist/types/core/MistReporter.d.ts +3 -3
- package/dist/types/core/MistSignaling.d.ts +12 -12
- package/dist/types/core/PlayerController.d.ts +19 -14
- package/dist/types/core/PlayerInterface.d.ts +100 -2
- package/dist/types/core/PlayerManager.d.ts +36 -9
- package/dist/types/core/PlayerRegistry.d.ts +11 -11
- package/dist/types/core/QualityMonitor.d.ts +2 -2
- package/dist/types/core/SeekingUtils.d.ts +2 -2
- package/dist/types/core/StreamStateClient.d.ts +2 -2
- package/dist/types/core/TelemetryReporter.d.ts +1 -1
- package/dist/types/core/TimerManager.d.ts +1 -1
- package/dist/types/core/detector.d.ts +1 -1
- package/dist/types/core/index.d.ts +44 -44
- package/dist/types/core/scorer.d.ts +1 -1
- package/dist/types/core/selector.d.ts +2 -2
- package/dist/types/index.d.ts +35 -34
- package/dist/types/players/DashJsPlayer.d.ts +3 -3
- package/dist/types/players/HlsJsPlayer.d.ts +3 -3
- package/dist/types/players/MewsWsPlayer/SourceBufferManager.d.ts +1 -1
- package/dist/types/players/MewsWsPlayer/WebSocketManager.d.ts +1 -1
- package/dist/types/players/MewsWsPlayer/index.d.ts +2 -2
- package/dist/types/players/MewsWsPlayer/types.d.ts +15 -15
- package/dist/types/players/MistPlayer.d.ts +2 -2
- package/dist/types/players/MistWebRTCPlayer/index.d.ts +3 -3
- package/dist/types/players/NativePlayer.d.ts +3 -3
- package/dist/types/players/VideoJsPlayer.d.ts +3 -3
- package/dist/types/players/WebCodecsPlayer/JitterBuffer.d.ts +3 -3
- package/dist/types/players/WebCodecsPlayer/LatencyProfiles.d.ts +1 -1
- package/dist/types/players/WebCodecsPlayer/RawChunkParser.d.ts +2 -2
- package/dist/types/players/WebCodecsPlayer/SyncController.d.ts +2 -2
- package/dist/types/players/WebCodecsPlayer/WebSocketController.d.ts +3 -3
- package/dist/types/players/WebCodecsPlayer/index.d.ts +9 -9
- package/dist/types/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.d.ts +1 -1
- package/dist/types/players/WebCodecsPlayer/types.d.ts +49 -49
- package/dist/types/players/WebCodecsPlayer/worker/types.d.ts +31 -31
- package/dist/types/players/index.d.ts +5 -8
- package/dist/types/types.d.ts +15 -15
- package/dist/types/vanilla/FrameWorksPlayer.d.ts +2 -2
- package/dist/types/vanilla/index.d.ts +4 -4
- package/dist/workers/decoder.worker.js +129 -122
- package/dist/workers/decoder.worker.js.map +1 -1
- package/package.json +31 -15
- package/src/core/ErrorClassifier.ts +499 -0
- package/src/core/PlayerController.ts +17 -2
- package/src/core/PlayerInterface.ts +109 -0
- package/src/core/PlayerManager.ts +290 -46
- package/src/core/PlayerRegistry.ts +221 -87
- package/src/core/TelemetryReporter.ts +4 -1
- package/src/index.ts +13 -4
- package/src/players/WebCodecsPlayer/index.ts +2 -2
- package/src/players/index.ts +5 -16
- package/src/styles/player.css +4 -1
- package/src/vanilla/FrameWorksPlayer.ts +2 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayerManager.js","sources":["../../../../src/core/PlayerManager.ts"],"sourcesContent":["/**\n * PlayerManager\n *\n * Central orchestrator for player selection and lifecycle management.\n * Single source of truth for all scoring logic.\n *\n * Architecture:\n * - `getAllCombinations()` is THE single function that computes player+source scores\n * - Results are cached by content (source types + track codecs), not object identity\n * - Events fire only when selection actually changes (no render spam)\n * - `selectBestPlayer()` returns cached winner without recomputation\n */\n\nimport { getBrowserInfo, getBrowserCompatibility } from \"./detector\";\nimport type {\n IPlayer,\n StreamSource,\n StreamInfo,\n PlayerOptions,\n ErrorHandlingEvents,\n ClassifiedError,\n} from \"./PlayerInterface\";\nimport { ErrorCode } from \"./PlayerInterface\";\nimport { ErrorClassifier, type RecoveryAction } from \"./ErrorClassifier\";\nimport { scorePlayer, isProtocolBlacklisted } from \"./scorer\";\nimport type { PlaybackMode } from \"../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PlayerSelection {\n score: number;\n player: string;\n source: StreamSource;\n source_index: number;\n}\n\nexport interface PlayerManagerOptions {\n /** Force a specific player */\n forcePlayer?: string;\n /** Force a specific source index */\n forceSource?: number;\n /** Force a specific MIME type */\n forceType?: string;\n /** Enable debug logging (logs selection changes only, not every render) */\n debug?: boolean;\n /** Automatic fallback on player failure */\n autoFallback?: boolean;\n /** Maximum fallback attempts */\n maxFallbackAttempts?: number;\n /** Playback mode for protocol selection */\n playbackMode?: PlaybackMode;\n}\n\nexport interface PlayerManagerEvents {\n playerSelected: { player: string; source: StreamSource; score: number };\n playerInitialized: { player: IPlayer; videoElement: HTMLVideoElement };\n fallbackAttempted: { fromPlayer: string; toPlayer: string };\n /** Fires when selection changes (different player+source than before) */\n \"selection-changed\": PlayerSelection | null;\n /** Fires when combinations are recomputed (cache miss) */\n \"combinations-updated\": PlayerCombination[];\n /** Tier 1: Silent recovery attempted (for telemetry) */\n recoveryAttempted: ErrorHandlingEvents[\"recoveryAttempted\"];\n /** Tier 2: Protocol swapped - UI should show toast */\n protocolSwapped: ErrorHandlingEvents[\"protocolSwapped\"];\n /** Tier 3: Quality changed - UI should show toast */\n qualityChanged: ErrorHandlingEvents[\"qualityChanged\"];\n /** Tier 4: All options exhausted - UI should show modal */\n playbackFailed: ErrorHandlingEvents[\"playbackFailed\"];\n}\n\n/** Full combination info including scoring breakdown */\nexport interface PlayerCombination {\n player: string;\n playerName: string;\n source: StreamSource;\n sourceIndex: number;\n sourceType: string;\n score: number;\n compatible: boolean;\n incompatibleReason?: string;\n /** True when player supports MIME but codec is incompatible */\n codecIncompatible?: boolean;\n scoreBreakdown?: {\n trackScore: number;\n trackTypes: string[];\n priorityScore: number;\n sourceScore: number;\n reliabilityScore?: number;\n modeBonus?: number;\n routingBonus?: number;\n weights: {\n tracks: number;\n priority: number;\n source: number;\n reliability?: number;\n mode?: number;\n routing?: number;\n };\n };\n}\n\n// ============================================================================\n// PlayerManager Class\n// ============================================================================\n\nexport class PlayerManager {\n private players: Map<string, IPlayer> = new Map();\n private currentPlayer: IPlayer | null = null;\n private listeners: Map<string, Set<Function>> = new Map();\n private fallbackAttempts = 0;\n private options: PlayerManagerOptions;\n\n // Error handling\n private errorClassifier: ErrorClassifier;\n\n // Caching: prevents recalculation on every render\n private cachedCombinations: PlayerCombination[] | null = null;\n private cachedSelection: PlayerSelection | null = null;\n private cacheKey: string | null = null;\n private lastLoggedWinner: string | null = null;\n\n // Fallback state\n private lastContainer: HTMLElement | null = null;\n private lastStreamInfo: StreamInfo | null = null;\n private lastPlayerOptions: PlayerOptions = {};\n private lastManagerOptions: PlayerManagerOptions = {};\n private excludedCombos: Set<string> = new Set();\n\n // Serializes lifecycle operations to prevent race conditions\n private opQueue: Promise<void> = Promise.resolve();\n\n constructor(options: PlayerManagerOptions = {}) {\n this.options = {\n debug: false,\n autoFallback: true,\n maxFallbackAttempts: 3,\n ...options,\n };\n\n this.errorClassifier = new ErrorClassifier({\n alternativesCount: 0,\n debug: this.options.debug,\n });\n\n // Forward error classifier events to manager events\n this.errorClassifier.on(\"recoveryAttempted\", (data) => this.emit(\"recoveryAttempted\", data));\n this.errorClassifier.on(\"protocolSwapped\", (data) => this.emit(\"protocolSwapped\", data));\n this.errorClassifier.on(\"qualityChanged\", (data) => this.emit(\"qualityChanged\", data));\n this.errorClassifier.on(\"playbackFailed\", (data) => this.emit(\"playbackFailed\", data));\n }\n\n // ==========================================================================\n // Player Registration\n // ==========================================================================\n\n registerPlayer(player: IPlayer): void {\n this.players.set(player.capability.shortname, player);\n this.invalidateCache();\n this.log(`Registered player: ${player.capability.name}`);\n }\n\n unregisterPlayer(shortname: string): void {\n const player = this.players.get(shortname);\n if (player) {\n player.destroy();\n this.players.delete(shortname);\n this.invalidateCache();\n this.log(`Unregistered player: ${shortname}`);\n }\n }\n\n getRegisteredPlayers(): IPlayer[] {\n return Array.from(this.players.values());\n }\n\n // ==========================================================================\n // Caching\n // ==========================================================================\n\n /**\n * Compute cache key based on CONTENT, not object identity.\n * Prevents recalculation when streamInfo is a new object with same data.\n */\n private computeCacheKey(streamInfo: StreamInfo, mode: PlaybackMode): string {\n return JSON.stringify({\n sources: streamInfo.source.map((s) => `${s.type}:${s.url ?? \"\"}`).sort(),\n tracks: streamInfo.meta?.tracks?.map((t) => t.codec).sort() ?? [],\n mode,\n forcePlayer: this.options.forcePlayer,\n forceSource: this.options.forceSource,\n forceType: this.options.forceType,\n });\n }\n\n private getComboKey(playerShortname: string, source: StreamSource): string {\n return `${playerShortname}:${source.type}:${source.url ?? \"\"}`;\n }\n\n /** Invalidate cache (called when player registrations change) */\n invalidateCache(): void {\n this.cachedCombinations = null;\n this.cachedSelection = null;\n this.cacheKey = null;\n }\n\n /** Get cached selection without recomputing */\n getCurrentSelection(): PlayerSelection | null {\n return this.cachedSelection;\n }\n\n /** Get cached combinations without recomputing */\n getCachedCombinations(): PlayerCombination[] | null {\n return this.cachedCombinations;\n }\n\n // ==========================================================================\n // Selection Logic (Single Source of Truth)\n // ==========================================================================\n\n /**\n * THE single source of truth for player+source scoring.\n * Returns ALL combinations (compatible and incompatible) with scores.\n * Results are cached - won't recompute if source types/tracks haven't changed.\n */\n getAllCombinations(streamInfo: StreamInfo, playbackMode?: PlaybackMode): PlayerCombination[] {\n // Determine effective playback mode\n const explicitMode = playbackMode || this.options.playbackMode;\n const effectiveMode: PlaybackMode =\n explicitMode && explicitMode !== \"auto\"\n ? explicitMode\n : streamInfo.type === \"vod\"\n ? \"vod\"\n : \"auto\";\n\n // Check cache\n const key = this.computeCacheKey(streamInfo, effectiveMode);\n if (key === this.cacheKey && this.cachedCombinations) {\n return this.cachedCombinations;\n }\n\n // Cache miss - compute all combinations\n const combinations = this.computeAllCombinations(streamInfo, effectiveMode);\n\n // Update cache\n this.cachedCombinations = combinations;\n this.cacheKey = key;\n\n // Update selection and emit events if changed\n const newSelection = this.pickBestFromCombinations(combinations);\n const selectionChanged = this.hasSelectionChanged(newSelection);\n\n if (selectionChanged) {\n this.cachedSelection = newSelection;\n\n // Log only on actual change\n if (this.options.debug && newSelection) {\n const winnerKey = `${newSelection.player}:${newSelection.source?.type}`;\n if (winnerKey !== this.lastLoggedWinner) {\n console.log(\n `[PlayerManager] Selection: ${newSelection.player} + ${newSelection.source?.type} (score: ${newSelection.score.toFixed(3)})`\n );\n this.lastLoggedWinner = winnerKey;\n }\n }\n\n this.emit(\"selection-changed\", newSelection);\n }\n\n this.emit(\"combinations-updated\", combinations);\n return combinations;\n }\n\n /**\n * Select the best player for given stream info.\n * Uses cached combinations - won't recompute if data hasn't changed.\n */\n selectBestPlayer(\n streamInfo: StreamInfo,\n options?: PlayerManagerOptions\n ): PlayerSelection | false {\n // Merge options\n const mergedOptions = { ...this.options, ...options };\n\n // Special handling for Legacy player - bypass normal selection\n if (mergedOptions.forcePlayer === \"mist-legacy\" || mergedOptions.forceType === \"mist/legacy\") {\n const legacyPlayer = this.players.get(\"mist-legacy\");\n if (legacyPlayer && streamInfo.source.length > 0) {\n const firstSource = streamInfo.source[0];\n const legacySource: StreamSource = {\n url: firstSource.url,\n type: \"mist/legacy\",\n streamName: firstSource.streamName,\n mistPlayerUrl: firstSource.mistPlayerUrl,\n };\n const result: PlayerSelection = {\n score: 0.1,\n player: \"mist-legacy\",\n source: legacySource,\n source_index: 0,\n };\n this.emit(\"playerSelected\", {\n player: result.player,\n source: result.source,\n score: result.score,\n });\n return result;\n }\n }\n\n // Get combinations (will use cache if available)\n const combinations = this.getAllCombinations(streamInfo, mergedOptions.playbackMode);\n\n // Apply force filters\n let filtered = combinations.filter((c) => c.compatible);\n\n if (mergedOptions.forcePlayer) {\n filtered = filtered.filter((c) => c.player === mergedOptions.forcePlayer);\n }\n if (mergedOptions.forceType) {\n filtered = filtered.filter((c) => c.sourceType === mergedOptions.forceType);\n }\n if (mergedOptions.forceSource !== undefined) {\n filtered = filtered.filter((c) => c.sourceIndex === mergedOptions.forceSource);\n }\n\n if (filtered.length === 0) {\n this.log(\"No suitable player found\");\n return false;\n }\n\n const best = filtered[0];\n const result: PlayerSelection = {\n score: best.score,\n player: best.player,\n source: best.source,\n source_index: best.sourceIndex,\n };\n\n this.emit(\"playerSelected\", {\n player: result.player,\n source: result.source,\n score: result.score,\n });\n\n return result;\n }\n\n /**\n * Internal: compute all combinations (no caching)\n */\n private computeAllCombinations(\n streamInfo: StreamInfo,\n effectiveMode: PlaybackMode\n ): PlayerCombination[] {\n const combinations: PlayerCombination[] = [];\n const players = Array.from(this.players.values());\n const maxPriority = Math.max(...players.map((p) => p.capability.priority), 1);\n\n // Filter blacklisted sources for scoring index calculation\n const selectionSources = streamInfo.source.filter((s) => !isProtocolBlacklisted(s.type));\n const selectionIndexBySource = new Map<StreamSource, number>();\n selectionSources.forEach((s, idx) => selectionIndexBySource.set(s, idx));\n const totalSources = selectionSources.length;\n\n const requiredTracks: Array<\"video\" | \"audio\"> = [];\n if (streamInfo.meta.tracks.some((t) => t.type === \"video\")) {\n requiredTracks.push(\"video\");\n }\n if (streamInfo.meta.tracks.some((t) => t.type === \"audio\")) {\n requiredTracks.push(\"audio\");\n }\n\n // Track seen player+sourceType pairs to avoid duplicates\n const seenPairs = new Set<string>();\n\n for (const player of players) {\n for (let sourceIndex = 0; sourceIndex < streamInfo.source.length; sourceIndex++) {\n const source = streamInfo.source[sourceIndex];\n const pairKey = this.getComboKey(player.capability.shortname, source);\n\n // Skip duplicate player+sourceType combinations\n if (seenPairs.has(pairKey)) continue;\n seenPairs.add(pairKey);\n\n // Blacklisted protocols: show as incompatible\n const sourceListIndex = selectionIndexBySource.get(source);\n if (sourceListIndex === undefined) {\n combinations.push({\n player: player.capability.shortname,\n playerName: player.capability.name,\n source,\n sourceIndex,\n sourceType: source.type,\n score: 0,\n compatible: false,\n incompatibleReason: `Protocol \"${source.type}\" is blacklisted`,\n });\n continue;\n }\n\n // Check MIME support\n const mimeSupported = player.isMimeSupported(source.type);\n if (!mimeSupported) {\n combinations.push({\n player: player.capability.shortname,\n playerName: player.capability.name,\n source,\n sourceIndex,\n sourceType: source.type,\n score: 0,\n compatible: false,\n incompatibleReason: `MIME type \"${source.type}\" not supported`,\n });\n continue;\n }\n\n // Check browser/codec compatibility\n const tracktypes = player.isBrowserSupported(source.type, source, streamInfo);\n if (!tracktypes) {\n // Codec incompatible - still score for UI display\n const priorityScore = 1 - player.capability.priority / Math.max(maxPriority, 1);\n const sourceScore = 1 - sourceListIndex / Math.max(totalSources - 1, 1);\n const playerScore = scorePlayer(\n [\"video\", \"audio\"],\n player.capability.priority,\n sourceListIndex,\n {\n maxPriority,\n totalSources,\n playerShortname: player.capability.shortname,\n mimeType: source.type,\n playbackMode: effectiveMode,\n }\n );\n\n combinations.push({\n player: player.capability.shortname,\n playerName: player.capability.name,\n source,\n sourceIndex,\n sourceType: source.type,\n score: playerScore.total,\n compatible: false,\n codecIncompatible: true,\n incompatibleReason: \"Codec not supported by browser\",\n scoreBreakdown: {\n trackScore: 0,\n trackTypes: [],\n priorityScore,\n sourceScore,\n weights: { tracks: 0.5, priority: 0.1, source: 0.05 },\n },\n });\n continue;\n }\n\n if (Array.isArray(tracktypes) && requiredTracks.length > 0) {\n const missing = requiredTracks.filter((t) => !tracktypes.includes(t));\n if (missing.length > 0) {\n const priorityScore = 1 - player.capability.priority / Math.max(maxPriority, 1);\n const sourceScore = 1 - sourceListIndex / Math.max(totalSources - 1, 1);\n const playerScore = scorePlayer(\n tracktypes,\n player.capability.priority,\n sourceListIndex,\n {\n maxPriority,\n totalSources,\n playerShortname: player.capability.shortname,\n mimeType: source.type,\n playbackMode: effectiveMode,\n }\n );\n\n combinations.push({\n player: player.capability.shortname,\n playerName: player.capability.name,\n source,\n sourceIndex,\n sourceType: source.type,\n score: playerScore.total,\n compatible: false,\n incompatibleReason: `Missing required tracks: ${missing.join(\", \")}`,\n scoreBreakdown: {\n trackScore: 0,\n trackTypes: tracktypes,\n priorityScore,\n sourceScore,\n weights: { tracks: 0.5, priority: 0.1, source: 0.05 },\n },\n });\n continue;\n }\n }\n\n // Compatible - calculate full score\n const trackScore = Array.isArray(tracktypes)\n ? tracktypes.reduce(\n (sum, t) => sum + ({ video: 2.0, audio: 1.0, subtitle: 0.5 }[t] || 0),\n 0\n )\n : 1.9;\n const priorityScore = 1 - player.capability.priority / Math.max(maxPriority, 1);\n const sourceScore = 1 - sourceListIndex / Math.max(totalSources - 1, 1);\n\n const playerScore = scorePlayer(tracktypes, player.capability.priority, sourceListIndex, {\n maxPriority,\n totalSources,\n playerShortname: player.capability.shortname,\n mimeType: source.type,\n playbackMode: effectiveMode,\n });\n\n combinations.push({\n player: player.capability.shortname,\n playerName: player.capability.name,\n source,\n sourceIndex,\n sourceType: source.type,\n score: playerScore.total,\n compatible: true,\n scoreBreakdown: {\n trackScore,\n trackTypes: Array.isArray(tracktypes) ? tracktypes : [\"video\", \"audio\"],\n priorityScore,\n sourceScore,\n reliabilityScore: playerScore.breakdown?.reliabilityScore ?? 0,\n modeBonus: playerScore.breakdown?.modeBonus ?? 0,\n routingBonus: playerScore.breakdown?.routingBonus ?? 0,\n weights: {\n tracks: 0.5,\n priority: 0.1,\n source: 0.05,\n reliability: 0.1,\n mode: 0.12,\n routing: 0.08,\n },\n },\n });\n }\n }\n\n // Add Legacy player option\n const legacyPlayer = this.players.get(\"mist-legacy\");\n if (legacyPlayer && streamInfo.source.length > 0) {\n const firstSource = streamInfo.source[0];\n const legacySource: StreamSource = {\n url: firstSource.url,\n type: \"mist/legacy\",\n streamName: firstSource.streamName,\n mistPlayerUrl: firstSource.mistPlayerUrl,\n };\n\n combinations.push({\n player: legacyPlayer.capability.shortname,\n playerName: legacyPlayer.capability.name,\n source: legacySource,\n sourceIndex: 0,\n sourceType: \"mist/legacy\",\n score: 0.1,\n compatible: true,\n scoreBreakdown: {\n trackScore: 2.0,\n trackTypes: [\"video\", \"audio\"],\n priorityScore: 0,\n sourceScore: 0,\n weights: { tracks: 0.5, priority: 0.1, source: 0.05 },\n },\n });\n }\n\n // Sort: compatible first by score descending, then incompatible alphabetically\n return combinations.sort((a, b) => {\n if (a.compatible !== b.compatible) return a.compatible ? -1 : 1;\n if (a.compatible) return b.score - a.score;\n return a.playerName.localeCompare(b.playerName);\n });\n }\n\n private diagnoseNoPlayersAvailable(\n streamInfo: StreamInfo,\n combinations: PlayerCombination[]\n ): { code: ErrorCode; message: string; details?: ClassifiedError[\"details\"] } {\n const allSources = streamInfo.source ?? [];\n const blacklistedSources = allSources.filter((source) => isProtocolBlacklisted(source.type));\n const blacklistedProtocols = Array.from(\n new Set(blacklistedSources.map((source) => source.type))\n );\n\n if (allSources.length > 0 && blacklistedSources.length === allSources.length) {\n return {\n code: ErrorCode.ALL_PROTOCOLS_BLACKLISTED,\n message: `All ${allSources.length} protocols are blacklisted`,\n details: {\n blacklistedProtocols,\n incompatibilityReasons: [\n `All source protocols are blacklisted: ${blacklistedProtocols.join(\", \")}`,\n ],\n },\n };\n }\n\n const incompatibilityReasons = Array.from(\n new Set(\n combinations\n .filter((combo) => !combo.compatible && combo.incompatibleReason)\n .map((combo) => combo.incompatibleReason as string)\n )\n );\n\n if (allSources.length === 0) {\n return {\n code: ErrorCode.ALL_PROTOCOLS_EXHAUSTED,\n message: \"No playback sources provided\",\n details: {\n incompatibilityReasons,\n blacklistedProtocols,\n },\n };\n }\n\n if (incompatibilityReasons.length === 1) {\n return {\n code: ErrorCode.ALL_PROTOCOLS_EXHAUSTED,\n message: incompatibilityReasons[0],\n details: {\n incompatibilityReasons,\n blacklistedProtocols,\n },\n };\n }\n\n return {\n code: ErrorCode.ALL_PROTOCOLS_EXHAUSTED,\n message: \"No compatible player/protocol combinations\",\n details: {\n incompatibilityReasons: incompatibilityReasons.slice(0, 5),\n blacklistedProtocols,\n },\n };\n }\n\n /**\n * Pick best compatible combination\n */\n private pickBestFromCombinations(combinations: PlayerCombination[]): PlayerSelection | null {\n const compatible = combinations.filter((c) => c.compatible);\n if (compatible.length === 0) return null;\n\n const best = compatible[0];\n return {\n score: best.score,\n player: best.player,\n source: best.source,\n source_index: best.sourceIndex,\n };\n }\n\n /**\n * Check if selection changed\n */\n private hasSelectionChanged(newSelection: PlayerSelection | null): boolean {\n if (!this.cachedSelection && !newSelection) return false;\n if (!this.cachedSelection || !newSelection) return true;\n return (\n this.cachedSelection.player !== newSelection.player ||\n this.cachedSelection.source?.type !== newSelection.source?.type ||\n (this.cachedSelection.source?.url ?? \"\") !== (newSelection.source?.url ?? \"\")\n );\n }\n\n // ==========================================================================\n // Player Initialization\n // ==========================================================================\n\n private enqueueOp<T>(op: () => Promise<T>): Promise<T> {\n const run = this.opQueue.then(op, op);\n this.opQueue = run.then(\n () => undefined,\n () => undefined\n );\n return run;\n }\n\n async initializePlayer(\n container: HTMLElement,\n streamInfo: StreamInfo,\n playerOptions: PlayerOptions = {},\n managerOptions?: PlayerManagerOptions\n ): Promise<HTMLVideoElement> {\n this.log(\"initializePlayer() called\");\n return this.enqueueOp(async () => {\n this.log(\"Inside enqueueOp - starting\");\n this.fallbackAttempts = 0;\n this.excludedCombos.clear();\n this.errorClassifier.reset();\n\n // Save for fallback (strip force settings - they're one-shot, not for fallback)\n this.lastContainer = container;\n this.lastStreamInfo = streamInfo;\n this.lastPlayerOptions = playerOptions;\n // Keep playback mode (persistent preference) but clear force settings\n this.lastManagerOptions = {\n playbackMode: managerOptions?.playbackMode,\n debug: managerOptions?.debug,\n autoFallback: managerOptions?.autoFallback,\n maxFallbackAttempts: managerOptions?.maxFallbackAttempts,\n // forcePlayer, forceType, forceSource are intentionally NOT saved\n // They are one-shot selections that shouldn't persist through fallback\n };\n\n return this.tryInitializePlayer(container, streamInfo, playerOptions, managerOptions);\n });\n }\n\n private async tryInitializePlayer(\n container: HTMLElement,\n streamInfo: StreamInfo,\n playerOptions: PlayerOptions,\n managerOptions?: PlayerManagerOptions,\n excludeCombos: Set<string> = new Set()\n ): Promise<HTMLVideoElement> {\n this.log(\"tryInitializePlayer() starting\");\n\n // Clean up previous player\n if (this.currentPlayer) {\n this.log(\"Cleaning up previous player...\");\n await Promise.resolve(this.currentPlayer.destroy());\n this.currentPlayer = null;\n }\n container.innerHTML = \"\";\n\n // Update classifier with current alternatives count\n const allCombinations = this.getAllCombinations(streamInfo, managerOptions?.playbackMode);\n const compatibleCombos = allCombinations.filter(\n (c) => c.compatible && !excludeCombos.has(this.getComboKey(c.player, c.source))\n );\n this.errorClassifier.setAlternativesRemaining(Math.max(0, compatibleCombos.length - 1));\n\n // Filter excluded combinations\n const availableSources = streamInfo.source.filter((_, index) => {\n if (excludeCombos.size === 0) return true;\n const selection = this.selectBestPlayer(\n { ...streamInfo, source: [streamInfo.source[index]] },\n managerOptions\n );\n return selection && !excludeCombos.has(this.getComboKey(selection.player, selection.source));\n });\n\n if (availableSources.length === 0) {\n this.log(\"No available sources after filtering\");\n const diagnostic = this.diagnoseNoPlayersAvailable(streamInfo, allCombinations);\n const action = this.errorClassifier.classifyWithDetails(\n diagnostic.code,\n diagnostic.message,\n diagnostic.details\n );\n if (action.type === \"fatal\") {\n throw new Error(diagnostic.message);\n }\n throw new Error(diagnostic.message);\n }\n\n this.log(`Available sources: ${availableSources.length}`);\n const modifiedStreamInfo = { ...streamInfo, source: availableSources };\n const selection = this.selectBestPlayer(modifiedStreamInfo, managerOptions);\n\n if (!selection) {\n this.log(\"No suitable player selected\");\n const selectionCombinations = this.getAllCombinations(\n modifiedStreamInfo,\n managerOptions?.playbackMode\n );\n const diagnostic = this.diagnoseNoPlayersAvailable(modifiedStreamInfo, selectionCombinations);\n this.errorClassifier.classifyWithDetails(\n diagnostic.code,\n diagnostic.message,\n diagnostic.details\n );\n throw new Error(diagnostic.message);\n }\n\n this.log(`Selected: ${selection.player} for ${selection.source.type}`);\n const player = this.players.get(selection.player);\n if (!player) {\n this.log(`Player ${selection.player} not registered`);\n throw new Error(`Player ${selection.player} not found`);\n }\n\n this.log(`Calling ${selection.player}.initialize()...`);\n try {\n const videoElement = await player.initialize(\n container,\n selection.source,\n playerOptions,\n streamInfo\n );\n this.log(`${selection.player}.initialize() completed successfully`);\n this.currentPlayer = player;\n this.errorClassifier.reset();\n this.emit(\"playerInitialized\", { player, videoElement });\n return videoElement;\n } catch (error: unknown) {\n return this.handleInitError(\n error,\n selection,\n container,\n streamInfo,\n playerOptions,\n managerOptions,\n excludeCombos\n );\n }\n }\n\n /**\n * Handle initialization error using ErrorClassifier to determine recovery action.\n */\n private async handleInitError(\n error: unknown,\n selection: PlayerSelection,\n container: HTMLElement,\n streamInfo: StreamInfo,\n playerOptions: PlayerOptions,\n managerOptions: PlayerManagerOptions | undefined,\n excludeCombos: Set<string>\n ): Promise<HTMLVideoElement> {\n const errorCode = ErrorClassifier.mapErrorToCode(\n error instanceof Error ? error : new Error(String(error))\n );\n const action = this.errorClassifier.classify(\n errorCode,\n error instanceof Error ? error : String(error)\n );\n\n this.log(`Error classified: ${errorCode}, action: ${action.type}`);\n\n switch (action.type) {\n case \"retry\": {\n this.log(`Retrying in ${action.delayMs}ms...`);\n await this.delay(action.delayMs);\n return this.tryInitializePlayer(\n container,\n streamInfo,\n playerOptions,\n managerOptions,\n excludeCombos\n );\n }\n\n case \"swap\": {\n const maxAttempts = this.options.maxFallbackAttempts || 3;\n if (!this.options.autoFallback || this.fallbackAttempts >= maxAttempts) {\n this.errorClassifier.classify(ErrorCode.ALL_PROTOCOLS_EXHAUSTED);\n throw error;\n }\n\n this.fallbackAttempts++;\n const previousPlayer = selection.player;\n const previousProtocol = selection.source.type;\n excludeCombos.add(this.getComboKey(selection.player, selection.source));\n\n this.log(\n `Swapping from ${previousPlayer} (attempt ${this.fallbackAttempts}/${maxAttempts})`\n );\n\n try {\n const result = await this.tryInitializePlayer(\n container,\n streamInfo,\n playerOptions,\n managerOptions,\n excludeCombos\n );\n\n // Notify classifier and emit toast event for successful swap\n const newPlayer = this.currentPlayer?.capability.shortname || \"unknown\";\n const newProtocol = this.cachedSelection?.source.type || \"unknown\";\n this.errorClassifier.notifyProtocolSwap(\n previousPlayer,\n newPlayer,\n previousProtocol,\n newProtocol,\n action.reason\n );\n\n this.emit(\"fallbackAttempted\", {\n fromPlayer: previousPlayer,\n toPlayer: newPlayer,\n });\n\n return result;\n } catch (swapError) {\n throw swapError;\n }\n }\n\n case \"fatal\":\n default:\n throw error;\n }\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n // ==========================================================================\n // Fallback Management\n // ==========================================================================\n\n async tryPlaybackFallback(): Promise<boolean> {\n return this.enqueueOp(async () => {\n if (!this.lastContainer || !this.lastStreamInfo) {\n this.log(\"Cannot attempt fallback: no previous init params\");\n return false;\n }\n\n const maxAttempts = this.options.maxFallbackAttempts || 3;\n if (this.fallbackAttempts >= maxAttempts) {\n this.log(`Fallback exhausted (${this.fallbackAttempts}/${maxAttempts})`);\n this.errorClassifier.classify(ErrorCode.ALL_PROTOCOLS_EXHAUSTED);\n return false;\n }\n\n const previousPlayer = this.currentPlayer?.capability.shortname || \"unknown\";\n const previousProtocol = this.cachedSelection?.source.type || \"unknown\";\n\n if (this.currentPlayer) {\n if (this.cachedSelection) {\n this.excludedCombos.add(\n this.getComboKey(this.cachedSelection.player, this.cachedSelection.source)\n );\n }\n await Promise.resolve(this.currentPlayer.destroy());\n this.currentPlayer = null;\n }\n\n this.fallbackAttempts++;\n this.lastContainer.innerHTML = \"\";\n this.errorClassifier.reset();\n\n try {\n await this.tryInitializePlayer(\n this.lastContainer,\n this.lastStreamInfo,\n this.lastPlayerOptions,\n this.lastManagerOptions,\n this.excludedCombos\n );\n\n const current = this.getCurrentPlayer();\n const newPlayer = current?.capability.shortname || \"unknown\";\n const newProtocol = this.cachedSelection?.source.type || \"unknown\";\n\n this.errorClassifier.notifyProtocolSwap(\n previousPlayer,\n newPlayer,\n previousProtocol,\n newProtocol,\n \"Playback fallback\"\n );\n\n this.emit(\"fallbackAttempted\", {\n fromPlayer: previousPlayer,\n toPlayer: newPlayer,\n });\n\n return true;\n } catch {\n this.log(\"Playback fallback failed\");\n return false;\n }\n });\n }\n\n /**\n * Report an error from a player for classification and potential recovery.\n * Players should call this instead of emitting errors directly.\n */\n reportError(error: Error | string): RecoveryAction {\n const errorCode = ErrorClassifier.mapErrorToCode(error);\n return this.errorClassifier.classify(errorCode, error);\n }\n\n /**\n * Report a quality change (for ABR quality drops).\n * UI layer can call this to trigger toast notification.\n */\n reportQualityChange(direction: \"up\" | \"down\", reason: string): void {\n this.emit(\"qualityChanged\", { direction, reason });\n }\n\n /**\n * Get the error classifier for direct access (advanced use).\n */\n getErrorClassifier(): ErrorClassifier {\n return this.errorClassifier;\n }\n\n getRemainingFallbackAttempts(): number {\n return Math.max(0, (this.options.maxFallbackAttempts || 3) - this.fallbackAttempts);\n }\n\n canAttemptFallback(): boolean {\n return this.getRemainingFallbackAttempts() > 0 && this.lastStreamInfo !== null;\n }\n\n getCurrentPlayer(): IPlayer | null {\n return this.currentPlayer;\n }\n\n // ==========================================================================\n // Browser Capabilities\n // ==========================================================================\n\n getBrowserCapabilities() {\n const browser = getBrowserInfo();\n const compatibility = getBrowserCompatibility();\n\n return {\n browser,\n compatibility,\n supportedMimeTypes: this.getSupportedMimeTypes(),\n availablePlayers: this.getAvailablePlayerInfo(),\n };\n }\n\n private getSupportedMimeTypes(): string[] {\n const mimes = new Set<string>();\n for (const player of this.players.values()) {\n player.capability.mimes.forEach((mime) => mimes.add(mime));\n }\n return Array.from(mimes).sort();\n }\n\n private getAvailablePlayerInfo() {\n return Array.from(this.players.values())\n .map((player) => ({\n name: player.capability.name,\n shortname: player.capability.shortname,\n priority: player.capability.priority,\n mimes: player.capability.mimes,\n }))\n .sort((a, b) => a.priority - b.priority);\n }\n\n // ==========================================================================\n // Lifecycle\n // ==========================================================================\n\n async destroy(): Promise<void> {\n await this.enqueueOp(async () => {\n if (this.currentPlayer) {\n await Promise.resolve(this.currentPlayer.destroy());\n this.currentPlayer = null;\n }\n });\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n\n // ==========================================================================\n // Event System\n // ==========================================================================\n\n on<K extends keyof PlayerManagerEvents>(\n event: K,\n listener: (data: PlayerManagerEvents[K]) => void\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n\n // Return unsubscribe function\n return () => this.off(event, listener);\n }\n\n off<K extends keyof PlayerManagerEvents>(\n event: K,\n listener: (data: PlayerManagerEvents[K]) => void\n ): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit<K extends keyof PlayerManagerEvents>(event: K, data: PlayerManagerEvents[K]): void {\n this.listeners.get(event)?.forEach((listener) => {\n try {\n listener(data);\n } catch (e) {\n console.error(`Error in PlayerManager ${event} listener:`, e);\n }\n });\n }\n\n // ==========================================================================\n // Logging\n // ==========================================================================\n\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[PlayerManager] ${message}`);\n }\n }\n\n // ==========================================================================\n // Testing\n // ==========================================================================\n\n async testSource(\n source: StreamSource,\n streamInfo: StreamInfo\n ): Promise<{ canPlay: boolean; players: string[] }> {\n const testStreamInfo = { ...streamInfo, source: [source] };\n const selection = this.selectBestPlayer(testStreamInfo);\n\n if (!selection) {\n return { canPlay: false, players: [] };\n }\n\n const capablePlayers: string[] = [];\n for (const player of this.players.values()) {\n if (player.isMimeSupported(source.type)) {\n const browserSupport = player.isBrowserSupported(source.type, source, streamInfo);\n if (browserSupport) {\n capablePlayers.push(player.capability.shortname);\n }\n }\n }\n\n return { canPlay: true, players: capablePlayers };\n }\n}\n"],"names":["ErrorClassifier","isProtocolBlacklisted","scorePlayer","ErrorCode","getBrowserInfo","getBrowserCompatibility"],"mappings":"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"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var PlayerManager = require('./PlayerManager.js');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Player Registry
|
|
7
|
+
*
|
|
8
|
+
* Lazy registration of player implementations. Capabilities are declared
|
|
9
|
+
* statically so MIME-based filtering happens without importing any player
|
|
10
|
+
* modules. Only the players matching the stream's source types are loaded.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Static capability registry. Each entry declares its capabilities (MIME types,
|
|
14
|
+
* priority) and a lazy loader that dynamically imports the implementation.
|
|
15
|
+
* No player code is loaded until `load()` is called.
|
|
16
|
+
*/
|
|
17
|
+
const PLAYER_ENTRIES = [
|
|
18
|
+
{
|
|
19
|
+
capability: {
|
|
20
|
+
name: "Native Player",
|
|
21
|
+
shortname: "native",
|
|
22
|
+
priority: 1,
|
|
23
|
+
mimes: [
|
|
24
|
+
"html5/video/mp4",
|
|
25
|
+
"html5/video/webm",
|
|
26
|
+
"html5/video/ogg",
|
|
27
|
+
"html5/audio/mp3",
|
|
28
|
+
"html5/audio/webm",
|
|
29
|
+
"html5/audio/ogg",
|
|
30
|
+
"html5/audio/wav",
|
|
31
|
+
"html5/application/vnd.apple.mpegurl",
|
|
32
|
+
"html5/application/vnd.apple.mpegurl;version=7",
|
|
33
|
+
"whep",
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
load: () => Promise.resolve().then(function () { return require('../players/NativePlayer.js'); }).then((m) => new m.NativePlayerImpl()),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
capability: {
|
|
40
|
+
name: "WebCodecs Player",
|
|
41
|
+
shortname: "webcodecs",
|
|
42
|
+
priority: 0,
|
|
43
|
+
mimes: ["ws/video/raw", "wss/video/raw", "ws/video/h264", "wss/video/h264"],
|
|
44
|
+
},
|
|
45
|
+
load: () => Promise.resolve().then(function () { return require('../players/WebCodecsPlayer/index.js'); }).then((m) => new m.WebCodecsPlayerImpl()),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
capability: {
|
|
49
|
+
name: "MistServer WebRTC",
|
|
50
|
+
shortname: "mist-webrtc",
|
|
51
|
+
priority: 2,
|
|
52
|
+
mimes: ["webrtc", "mist/webrtc"],
|
|
53
|
+
},
|
|
54
|
+
load: () => Promise.resolve().then(function () { return require('../players/MistWebRTCPlayer/index.js'); }).then((m) => new m.MistWebRTCPlayerImpl()),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
capability: {
|
|
58
|
+
name: "Video.js Player",
|
|
59
|
+
shortname: "videojs",
|
|
60
|
+
priority: 2,
|
|
61
|
+
mimes: [
|
|
62
|
+
"html5/application/vnd.apple.mpegurl",
|
|
63
|
+
"html5/application/vnd.apple.mpegurl;version=7",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
load: () => Promise.resolve().then(function () { return require('../players/VideoJsPlayer.js'); }).then((m) => new m.VideoJsPlayerImpl()),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
capability: {
|
|
70
|
+
name: "HLS.js Player",
|
|
71
|
+
shortname: "hlsjs",
|
|
72
|
+
priority: 3,
|
|
73
|
+
mimes: [
|
|
74
|
+
"html5/application/vnd.apple.mpegurl",
|
|
75
|
+
"html5/application/vnd.apple.mpegurl;version=7",
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
load: () => Promise.resolve().then(function () { return require('../players/HlsJsPlayer.js'); }).then((m) => new m.HlsJsPlayerImpl()),
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
capability: {
|
|
82
|
+
name: "Dash.js Player",
|
|
83
|
+
shortname: "dashjs",
|
|
84
|
+
priority: 100,
|
|
85
|
+
mimes: ["dash/video/mp4"],
|
|
86
|
+
},
|
|
87
|
+
load: () => Promise.resolve().then(function () { return require('../players/DashJsPlayer.js'); }).then((m) => new m.DashJsPlayerImpl()),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
capability: {
|
|
91
|
+
name: "Legacy",
|
|
92
|
+
shortname: "mist-legacy",
|
|
93
|
+
priority: 99,
|
|
94
|
+
mimes: ["mist/legacy"],
|
|
95
|
+
},
|
|
96
|
+
load: () => Promise.resolve().then(function () { return require('../players/MistPlayer.js'); }).then((m) => new m.MistPlayerImpl()),
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
capability: {
|
|
100
|
+
name: "MEWS WebSocket Player",
|
|
101
|
+
shortname: "mews",
|
|
102
|
+
priority: 2,
|
|
103
|
+
mimes: ["ws/video/mp4", "wss/video/mp4", "ws/video/webm", "wss/video/webm"],
|
|
104
|
+
},
|
|
105
|
+
load: () => Promise.resolve().then(function () { return require('../players/MewsWsPlayer/index.js'); }).then((m) => new m.MewsWsPlayerImpl()),
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Loading State
|
|
110
|
+
// ============================================================================
|
|
111
|
+
/** Track which players have been loaded per manager */
|
|
112
|
+
const loadedPlayersMap = new WeakMap();
|
|
113
|
+
function getLoadedSet(manager) {
|
|
114
|
+
let set = loadedPlayersMap.get(manager);
|
|
115
|
+
if (!set) {
|
|
116
|
+
set = new Set();
|
|
117
|
+
loadedPlayersMap.set(manager, set);
|
|
118
|
+
}
|
|
119
|
+
return set;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Load only players whose capabilities match the given source MIME types.
|
|
123
|
+
* Already-loaded players are skipped. Safe to call multiple times with
|
|
124
|
+
* different MIME types — new players are added incrementally.
|
|
125
|
+
*/
|
|
126
|
+
async function loadMatchingPlayers(manager, sourceMimes) {
|
|
127
|
+
const loaded = getLoadedSet(manager);
|
|
128
|
+
const toLoad = PLAYER_ENTRIES.filter((entry) => {
|
|
129
|
+
if (loaded.has(entry.capability.shortname))
|
|
130
|
+
return false;
|
|
131
|
+
return entry.capability.mimes.some((m) => sourceMimes.includes(m));
|
|
132
|
+
});
|
|
133
|
+
if (toLoad.length === 0)
|
|
134
|
+
return;
|
|
135
|
+
const players = await Promise.all(toLoad.map((e) => e.load()));
|
|
136
|
+
for (const player of players) {
|
|
137
|
+
loaded.add(player.capability.shortname);
|
|
138
|
+
const alreadyRegistered = manager
|
|
139
|
+
.getRegisteredPlayers()
|
|
140
|
+
.some((p) => p.capability.shortname === player.capability.shortname);
|
|
141
|
+
if (!alreadyRegistered) {
|
|
142
|
+
manager.registerPlayer(player);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Load a specific player by shortname. Used for forcePlayer support.
|
|
148
|
+
*/
|
|
149
|
+
async function loadPlayerByShortname(manager, shortname) {
|
|
150
|
+
const loaded = getLoadedSet(manager);
|
|
151
|
+
if (loaded.has(shortname))
|
|
152
|
+
return;
|
|
153
|
+
const entry = PLAYER_ENTRIES.find((e) => e.capability.shortname === shortname);
|
|
154
|
+
if (!entry)
|
|
155
|
+
return;
|
|
156
|
+
const player = await entry.load();
|
|
157
|
+
loaded.add(player.capability.shortname);
|
|
158
|
+
const alreadyRegistered = manager
|
|
159
|
+
.getRegisteredPlayers()
|
|
160
|
+
.some((p) => p.capability.shortname === player.capability.shortname);
|
|
161
|
+
if (!alreadyRegistered) {
|
|
162
|
+
manager.registerPlayer(player);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Load all players. Used for backwards compatibility (createPlayerManager,
|
|
167
|
+
* registerAllPlayers) and when no MIME filter is available.
|
|
168
|
+
*/
|
|
169
|
+
async function loadAllPlayers(manager) {
|
|
170
|
+
const allMimes = PLAYER_ENTRIES.flatMap((e) => e.capability.mimes);
|
|
171
|
+
return loadMatchingPlayers(manager, allMimes);
|
|
172
|
+
}
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// Public API
|
|
175
|
+
// ============================================================================
|
|
176
|
+
/** Deduplication promises for full registration (loadAllPlayers) */
|
|
177
|
+
const fullRegistrationPromises = new WeakMap();
|
|
178
|
+
/**
|
|
179
|
+
* Ensure all players are registered. Backwards-compatible API that loads
|
|
180
|
+
* every player module. Prefer the MIME-filtered path via initializePlayer.
|
|
181
|
+
*/
|
|
182
|
+
function ensurePlayersRegistered(manager = globalPlayerManager) {
|
|
183
|
+
const loaded = getLoadedSet(manager);
|
|
184
|
+
if (loaded.size === PLAYER_ENTRIES.length) {
|
|
185
|
+
return Promise.resolve();
|
|
186
|
+
}
|
|
187
|
+
const existing = fullRegistrationPromises.get(manager);
|
|
188
|
+
if (existing)
|
|
189
|
+
return existing;
|
|
190
|
+
const promise = loadAllPlayers(manager).catch((error) => {
|
|
191
|
+
console.error("[PlayerRegistry] Registration failed:", error);
|
|
192
|
+
fullRegistrationPromises.delete(manager);
|
|
193
|
+
throw error;
|
|
194
|
+
});
|
|
195
|
+
fullRegistrationPromises.set(manager, promise);
|
|
196
|
+
return promise;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Monkey-patch initializePlayer to lazily load only matching players.
|
|
200
|
+
* Extracts source MIME types from streamInfo and loads the subset of
|
|
201
|
+
* player modules that can handle those types.
|
|
202
|
+
*/
|
|
203
|
+
const originalInitialize = PlayerManager.PlayerManager.prototype.initializePlayer;
|
|
204
|
+
PlayerManager.PlayerManager.prototype.initializePlayer = async function (...args) {
|
|
205
|
+
const [_container, streamInfo, _playerOptions, managerOptions] = args;
|
|
206
|
+
const sourceMimes = streamInfo?.source?.map((s) => s.type) ?? [];
|
|
207
|
+
if (sourceMimes.length > 0) {
|
|
208
|
+
// Load only players matching the stream's source types
|
|
209
|
+
await loadMatchingPlayers(this, sourceMimes);
|
|
210
|
+
// Also load a forced player if specified
|
|
211
|
+
if (managerOptions?.forcePlayer) {
|
|
212
|
+
await loadPlayerByShortname(this, managerOptions.forcePlayer);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// No source info — fall back to loading all
|
|
217
|
+
await ensurePlayersRegistered(this);
|
|
218
|
+
}
|
|
219
|
+
return originalInitialize.apply(this, args);
|
|
220
|
+
};
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// Global Instance
|
|
223
|
+
// ============================================================================
|
|
224
|
+
const isDev = (() => {
|
|
225
|
+
try {
|
|
226
|
+
const g = globalThis;
|
|
227
|
+
const p = g.process;
|
|
228
|
+
const env = p?.env;
|
|
229
|
+
return env?.NODE_ENV === "development";
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
})();
|
|
235
|
+
const globalPlayerManager = new PlayerManager.PlayerManager({
|
|
236
|
+
debug: isDev,
|
|
237
|
+
autoFallback: true,
|
|
238
|
+
maxFallbackAttempts: 3,
|
|
239
|
+
});
|
|
240
|
+
/**
|
|
241
|
+
* Register all available players (async for backwards compatibility)
|
|
242
|
+
*/
|
|
243
|
+
async function registerAllPlayers(manager = globalPlayerManager) {
|
|
244
|
+
await ensurePlayersRegistered(manager);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Create a new PlayerManager instance with all players registered
|
|
248
|
+
*/
|
|
249
|
+
function createPlayerManager(options) {
|
|
250
|
+
const manager = new PlayerManager.PlayerManager(options);
|
|
251
|
+
ensurePlayersRegistered(manager).catch((error) => {
|
|
252
|
+
if (isDev) {
|
|
253
|
+
console.warn("Player registration failed:", error);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
return manager;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get the static capability registry (for UI display without loading modules)
|
|
260
|
+
*/
|
|
261
|
+
function getAvailablePlayerCapabilities() {
|
|
262
|
+
return PLAYER_ENTRIES.map((e) => e.capability);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
exports.createPlayerManager = createPlayerManager;
|
|
266
|
+
exports.ensurePlayersRegistered = ensurePlayersRegistered;
|
|
267
|
+
exports.getAvailablePlayerCapabilities = getAvailablePlayerCapabilities;
|
|
268
|
+
exports.globalPlayerManager = globalPlayerManager;
|
|
269
|
+
exports.registerAllPlayers = registerAllPlayers;
|
|
270
|
+
//# sourceMappingURL=PlayerRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayerRegistry.js","sources":["../../../../src/core/PlayerRegistry.ts"],"sourcesContent":["/**\n * Player Registry\n *\n * Lazy registration of player implementations. Capabilities are declared\n * statically so MIME-based filtering happens without importing any player\n * modules. Only the players matching the stream's source types are loaded.\n */\n\nimport { PlayerManager } from \"./PlayerManager\";\nimport type { IPlayer, PlayerCapability } from \"./PlayerInterface\";\n\n// ============================================================================\n// Lazy Player Entry\n// ============================================================================\n\ninterface LazyPlayerEntry {\n capability: PlayerCapability;\n load: () => Promise<IPlayer>;\n}\n\n/**\n * Static capability registry. Each entry declares its capabilities (MIME types,\n * priority) and a lazy loader that dynamically imports the implementation.\n * No player code is loaded until `load()` is called.\n */\nconst PLAYER_ENTRIES: LazyPlayerEntry[] = [\n {\n capability: {\n name: \"Native Player\",\n shortname: \"native\",\n priority: 1,\n mimes: [\n \"html5/video/mp4\",\n \"html5/video/webm\",\n \"html5/video/ogg\",\n \"html5/audio/mp3\",\n \"html5/audio/webm\",\n \"html5/audio/ogg\",\n \"html5/audio/wav\",\n \"html5/application/vnd.apple.mpegurl\",\n \"html5/application/vnd.apple.mpegurl;version=7\",\n \"whep\",\n ],\n },\n load: () => import(\"../players/NativePlayer\").then((m) => new m.NativePlayerImpl()),\n },\n {\n capability: {\n name: \"WebCodecs Player\",\n shortname: \"webcodecs\",\n priority: 0,\n mimes: [\"ws/video/raw\", \"wss/video/raw\", \"ws/video/h264\", \"wss/video/h264\"],\n },\n load: () => import(\"../players/WebCodecsPlayer\").then((m) => new m.WebCodecsPlayerImpl()),\n },\n {\n capability: {\n name: \"MistServer WebRTC\",\n shortname: \"mist-webrtc\",\n priority: 2,\n mimes: [\"webrtc\", \"mist/webrtc\"],\n },\n load: () => import(\"../players/MistWebRTCPlayer\").then((m) => new m.MistWebRTCPlayerImpl()),\n },\n {\n capability: {\n name: \"Video.js Player\",\n shortname: \"videojs\",\n priority: 2,\n mimes: [\n \"html5/application/vnd.apple.mpegurl\",\n \"html5/application/vnd.apple.mpegurl;version=7\",\n ],\n },\n load: () => import(\"../players/VideoJsPlayer\").then((m) => new m.VideoJsPlayerImpl()),\n },\n {\n capability: {\n name: \"HLS.js Player\",\n shortname: \"hlsjs\",\n priority: 3,\n mimes: [\n \"html5/application/vnd.apple.mpegurl\",\n \"html5/application/vnd.apple.mpegurl;version=7\",\n ],\n },\n load: () => import(\"../players/HlsJsPlayer\").then((m) => new m.HlsJsPlayerImpl()),\n },\n {\n capability: {\n name: \"Dash.js Player\",\n shortname: \"dashjs\",\n priority: 100,\n mimes: [\"dash/video/mp4\"],\n },\n load: () => import(\"../players/DashJsPlayer\").then((m) => new m.DashJsPlayerImpl()),\n },\n {\n capability: {\n name: \"Legacy\",\n shortname: \"mist-legacy\",\n priority: 99,\n mimes: [\"mist/legacy\"],\n },\n load: () => import(\"../players/MistPlayer\").then((m) => new m.MistPlayerImpl()),\n },\n {\n capability: {\n name: \"MEWS WebSocket Player\",\n shortname: \"mews\",\n priority: 2,\n mimes: [\"ws/video/mp4\", \"wss/video/mp4\", \"ws/video/webm\", \"wss/video/webm\"],\n },\n load: () => import(\"../players/MewsWsPlayer\").then((m) => new m.MewsWsPlayerImpl()),\n },\n];\n\n// ============================================================================\n// Loading State\n// ============================================================================\n\n/** Track which players have been loaded per manager */\nconst loadedPlayersMap = new WeakMap<PlayerManager, Set<string>>();\n\nfunction getLoadedSet(manager: PlayerManager): Set<string> {\n let set = loadedPlayersMap.get(manager);\n if (!set) {\n set = new Set();\n loadedPlayersMap.set(manager, set);\n }\n return set;\n}\n\n/**\n * Load only players whose capabilities match the given source MIME types.\n * Already-loaded players are skipped. Safe to call multiple times with\n * different MIME types — new players are added incrementally.\n */\nasync function loadMatchingPlayers(manager: PlayerManager, sourceMimes: string[]): Promise<void> {\n const loaded = getLoadedSet(manager);\n\n const toLoad = PLAYER_ENTRIES.filter((entry) => {\n if (loaded.has(entry.capability.shortname)) return false;\n return entry.capability.mimes.some((m) => sourceMimes.includes(m));\n });\n\n if (toLoad.length === 0) return;\n\n const players = await Promise.all(toLoad.map((e) => e.load()));\n for (const player of players) {\n loaded.add(player.capability.shortname);\n const alreadyRegistered = manager\n .getRegisteredPlayers()\n .some((p) => p.capability.shortname === player.capability.shortname);\n if (!alreadyRegistered) {\n manager.registerPlayer(player);\n }\n }\n}\n\n/**\n * Load a specific player by shortname. Used for forcePlayer support.\n */\nasync function loadPlayerByShortname(manager: PlayerManager, shortname: string): Promise<void> {\n const loaded = getLoadedSet(manager);\n if (loaded.has(shortname)) return;\n\n const entry = PLAYER_ENTRIES.find((e) => e.capability.shortname === shortname);\n if (!entry) return;\n\n const player = await entry.load();\n loaded.add(player.capability.shortname);\n const alreadyRegistered = manager\n .getRegisteredPlayers()\n .some((p) => p.capability.shortname === player.capability.shortname);\n if (!alreadyRegistered) {\n manager.registerPlayer(player);\n }\n}\n\n/**\n * Load all players. Used for backwards compatibility (createPlayerManager,\n * registerAllPlayers) and when no MIME filter is available.\n */\nasync function loadAllPlayers(manager: PlayerManager): Promise<void> {\n const allMimes = PLAYER_ENTRIES.flatMap((e) => e.capability.mimes);\n return loadMatchingPlayers(manager, allMimes);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/** Deduplication promises for full registration (loadAllPlayers) */\nconst fullRegistrationPromises = new WeakMap<PlayerManager, Promise<void>>();\n\n/**\n * Ensure all players are registered. Backwards-compatible API that loads\n * every player module. Prefer the MIME-filtered path via initializePlayer.\n */\nexport function ensurePlayersRegistered(\n manager: PlayerManager = globalPlayerManager\n): Promise<void> {\n const loaded = getLoadedSet(manager);\n if (loaded.size === PLAYER_ENTRIES.length) {\n return Promise.resolve();\n }\n\n const existing = fullRegistrationPromises.get(manager);\n if (existing) return existing;\n\n const promise = loadAllPlayers(manager).catch((error) => {\n console.error(\"[PlayerRegistry] Registration failed:\", error);\n fullRegistrationPromises.delete(manager);\n throw error;\n });\n\n fullRegistrationPromises.set(manager, promise);\n return promise;\n}\n\n/**\n * Monkey-patch initializePlayer to lazily load only matching players.\n * Extracts source MIME types from streamInfo and loads the subset of\n * player modules that can handle those types.\n */\nconst originalInitialize = PlayerManager.prototype.initializePlayer;\nPlayerManager.prototype.initializePlayer = async function (\n ...args: Parameters<PlayerManager[\"initializePlayer\"]>\n) {\n const [_container, streamInfo, _playerOptions, managerOptions] = args;\n const sourceMimes = streamInfo?.source?.map((s) => s.type) ?? [];\n\n if (sourceMimes.length > 0) {\n // Load only players matching the stream's source types\n await loadMatchingPlayers(this, sourceMimes);\n\n // Also load a forced player if specified\n if (managerOptions?.forcePlayer) {\n await loadPlayerByShortname(this, managerOptions.forcePlayer);\n }\n } else {\n // No source info — fall back to loading all\n await ensurePlayersRegistered(this);\n }\n\n return originalInitialize.apply(this, args);\n};\n\n// ============================================================================\n// Global Instance\n// ============================================================================\n\nconst isDev = (() => {\n try {\n const g = globalThis as Record<string, unknown>;\n const p = g.process as Record<string, unknown> | undefined;\n const env = p?.env as Record<string, unknown> | undefined;\n return env?.NODE_ENV === \"development\";\n } catch {\n return false;\n }\n})();\n\nexport const globalPlayerManager = new PlayerManager({\n debug: isDev,\n autoFallback: true,\n maxFallbackAttempts: 3,\n});\n\n/**\n * Register all available players (async for backwards compatibility)\n */\nexport async function registerAllPlayers(\n manager: PlayerManager = globalPlayerManager\n): Promise<void> {\n await ensurePlayersRegistered(manager);\n}\n\n/**\n * Create a new PlayerManager instance with all players registered\n */\nexport function createPlayerManager(\n options?: ConstructorParameters<typeof PlayerManager>[0]\n): PlayerManager {\n const manager = new PlayerManager(options);\n ensurePlayersRegistered(manager).catch((error) => {\n if (isDev) {\n console.warn(\"Player registration failed:\", error);\n }\n });\n return manager;\n}\n\n/**\n * Get the static capability registry (for UI display without loading modules)\n */\nexport function getAvailablePlayerCapabilities(): PlayerCapability[] {\n return PLAYER_ENTRIES.map((e) => e.capability);\n}\n"],"names":["PlayerManager"],"mappings":"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"}
|