@mantequilla-soft/3speak-player 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/platform.ts","../src/core/api.ts","../src/core/player.ts","../src/core/pool.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { PlatformInfo } from '../types';\n\nlet cached: PlatformInfo | null = null;\n\n/**\n * Detect platform capabilities for HLS playback strategy.\n * Results are cached after first call.\n */\nexport function detectPlatform(): PlatformInfo {\n if (cached) return cached;\n\n if (typeof navigator === 'undefined' || typeof document === 'undefined') {\n // SSR / non-browser\n cached = {\n isIOS: false,\n isSafari: false,\n supportsNativeHLS: false,\n supportsMSE: false,\n supportsHlsJs: false,\n };\n return cached;\n }\n\n const ua = navigator.userAgent;\n\n const isIOS =\n /iPad|iPhone|iPod/.test(ua) ||\n (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n\n const isSafari = /^((?!chrome|android).)*safari/i.test(ua);\n\n const testVideo = document.createElement('video');\n const supportsNativeHLS =\n testVideo.canPlayType('application/vnd.apple.mpegurl') !== '';\n\n const supportsMSE =\n typeof MediaSource !== 'undefined' &&\n typeof MediaSource.isTypeSupported === 'function';\n\n cached = {\n isIOS,\n isSafari,\n supportsNativeHLS,\n supportsMSE,\n supportsHlsJs: supportsMSE, // hls.js requires MSE\n };\n\n return cached;\n}\n\n// Minimal silent MP4 (1 frame, ~300 bytes) for autoplay probe\nconst SILENT_MP4 =\n 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAABltZGF0AAAA' +\n 'EgYJpAAQ//728PAppAAAAARBAAVcAAAAUG1vb3YAAABsbXZoZAAAAAAAAAAAAAAAAAAAA+gAAAAAAAEAAAEA' +\n 'AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +\n 'AAAAAAAAACAAACknRyYWsAAABcdGtoZAAAAA8AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +\n 'AAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAEAAAABAAAAAAACNm1kaWEAAAAgbWRoZAAAAAAAAAAAAAAAAAAA' +\n 'KAAAAAAAAFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAOFtaW5m' +\n 'AAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAChdGJn' +\n 'AAAAABN0c2QAAAAAAAAAAQAAAINhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAEAAQAEgAAABIAAAAAAAA' +\n 'AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwFkAAr/4QAZZ2QACqzZQoeAXmAh' +\n 'AAADAAEAAAMAA8SJZYABAAZo6+PLIsAAAAAbcmVhcAAAAB1jb2xybmNseAAGAAYABgAAAAAQcGFzcAAAAAEA' +\n 'AAABAAAAFHN0dHMAAAAAAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAAEwAAAAEAAAAUc3RzYwAAAAAAAAABAA' +\n 'AAAQAAAAEAAAABAAAAFHNkdHAAAAAAICAAAAAUc3RzYwAAAAAAAA==';\n\nconst autoplayCache = new Map<string, boolean>();\n\n/**\n * Detect whether the browser allows autoplay.\n * @param muted - Test muted autoplay (default: true). Unmuted autoplay is blocked on most browsers.\n * @returns Promise resolving to true if autoplay is allowed.\n */\nexport async function canAutoplay(muted: boolean = true): Promise<boolean> {\n const key = muted ? 'muted' : 'unmuted';\n if (autoplayCache.has(key)) return autoplayCache.get(key)!;\n\n if (typeof document === 'undefined') {\n autoplayCache.set(key, false);\n return false;\n }\n\n const video = document.createElement('video');\n video.setAttribute('playsinline', '');\n video.muted = muted;\n video.src = SILENT_MP4;\n\n try {\n await video.play();\n video.pause();\n autoplayCache.set(key, true);\n return true;\n } catch {\n autoplayCache.set(key, false);\n return false;\n } finally {\n video.removeAttribute('src');\n video.load();\n }\n}\n","import type { VideoMetadata, VideoSource } from '../types';\n\nconst DEFAULT_API_BASE = 'https://play.3speak.tv';\n\n/**\n * 3Speak video API client.\n * Fetches video metadata and HLS URLs from the snapie player API.\n */\nexport class ThreeSpeakApi {\n private apiBase: string;\n private debug: boolean;\n\n constructor(apiBase?: string, debug = false) {\n this.apiBase = (apiBase || DEFAULT_API_BASE).replace(/\\/$/, '');\n this.debug = debug;\n }\n\n private log(...args: unknown[]) {\n if (this.debug) console.log('[3Speak API]', ...args);\n }\n\n /**\n * Fetch full video metadata from the embed API.\n * @param author - Hive account name\n * @param permlink - 3Speak video permlink\n */\n async fetchVideoMetadata(author: string, permlink: string): Promise<VideoMetadata> {\n const url = `${this.apiBase}/api/embed?v=${author}/${permlink}`;\n this.log('Fetching:', url);\n\n const response = await fetch(url);\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));\n throw new Error(error.error || `Failed to fetch video: HTTP ${response.status}`);\n }\n\n const data = await response.json();\n this.log('Got metadata:', data.owner, data.permlink, data.status);\n return data as VideoMetadata;\n }\n\n /**\n * Fetch just the HLS source URLs (convenience wrapper).\n * Returns a VideoSource ready to pass to the player.\n */\n async fetchSource(author: string, permlink: string): Promise<VideoSource> {\n const meta = await this.fetchVideoMetadata(author, permlink);\n return metadataToSource(meta);\n }\n\n /**\n * Prefetch an HLS manifest AND its first video segment to warm CDN + browser cache.\n * This means when hls.js actually starts playback, the first segment is already cached.\n */\n async prefetchManifest(hlsUrl: string): Promise<void> {\n try {\n const resp = await fetch(hlsUrl, { mode: 'cors', credentials: 'omit' });\n const text = await resp.text();\n this.log('Prefetched manifest:', hlsUrl.substring(0, 80));\n\n // Resolve relative URLs against manifest base\n const baseUrl = hlsUrl.substring(0, hlsUrl.lastIndexOf('/') + 1);\n\n const resolveUrl = (ref: string) =>\n ref.startsWith('http') ? ref : baseUrl + ref;\n\n // Check if this is a master playlist (contains quality variants)\n if (text.includes('#EXT-X-STREAM-INF')) {\n // Master playlist — find first variant (lowest bandwidth = fastest)\n const lines = text.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n // This is the first variant URL\n const variantUrl = resolveUrl(trimmed);\n this.log('Prefetching first variant:', variantUrl.substring(0, 80));\n const varResp = await fetch(variantUrl, { mode: 'cors', credentials: 'omit' });\n const varText = await varResp.text();\n // Now find and prefetch the first segment from this variant\n this.prefetchFirstSegment(varText, variantUrl);\n break;\n }\n }\n } else {\n // Media playlist — directly find first segment\n this.prefetchFirstSegment(text, hlsUrl);\n }\n } catch {\n // Silently fail — this is just an optimization\n }\n }\n\n /**\n * Parse a media playlist and prefetch its first .ts/.m4s segment.\n */\n private prefetchFirstSegment(playlistText: string, playlistUrl: string): void {\n const base = playlistUrl.substring(0, playlistUrl.lastIndexOf('/') + 1);\n const lines = playlistText.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n const segUrl = trimmed.startsWith('http') ? trimmed : base + trimmed;\n this.log('Prefetching first segment:', segUrl.substring(0, 80));\n fetch(segUrl, { mode: 'cors', credentials: 'omit' }).catch(() => {});\n break;\n }\n }\n }\n\n /**\n * Increment view count for a video.\n */\n async recordView(owner: string, permlink: string, type = 'embed'): Promise<void> {\n try {\n await fetch(`${this.apiBase}/api/view`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ owner, permlink, type }),\n });\n this.log('View recorded:', owner, permlink);\n } catch {\n // Non-critical — don't throw\n }\n }\n}\n\n/**\n * Convert API metadata to a VideoSource with fallback chain.\n */\nexport function metadataToSource(meta: VideoMetadata): VideoSource {\n const fallbacks: string[] = [];\n if (meta.videoUrlFallback1 && meta.videoUrlFallback1 !== meta.videoUrl) {\n fallbacks.push(meta.videoUrlFallback1);\n }\n if (meta.videoUrlFallback2 && meta.videoUrlFallback2 !== meta.videoUrl) {\n fallbacks.push(meta.videoUrlFallback2);\n }\n if (meta.videoUrlFallback3 && meta.videoUrlFallback3 !== meta.videoUrl) {\n fallbacks.push(meta.videoUrlFallback3);\n }\n\n return {\n url: meta.videoUrl,\n fallbacks,\n poster: meta.thumbnail || undefined,\n };\n}\n\n/** Default API instance */\nexport const api = new ThreeSpeakApi();\n","import Hls from 'hls.js';\nimport { detectPlatform } from './platform';\nimport { ThreeSpeakApi } from './api';\nimport type {\n VideoSource,\n PlayerConfig,\n PlayerState,\n PlayerEvents,\n EventHandler,\n EventUnsubscribe,\n QualityLevel,\n} from '../types';\n\nconst DEFAULT_CONFIG: Required<PlayerConfig> = {\n apiBase: 'https://play.3speak.tv',\n debug: false,\n muted: true,\n loop: false,\n poster: true,\n hlsConfig: {},\n audioOnly: false,\n autopause: false,\n resume: false,\n};\n\n/**\n * 3Speak HLS Video Player.\n *\n * Framework-agnostic — works with any <video> element.\n * Handles HLS playback via native Safari HLS or hls.js (Chrome/Firefox/Edge).\n *\n * @example\n * ```js\n * import { Player } from '@mantequilla-soft/3speak-player';\n *\n * const player = new Player({ muted: true, loop: true });\n * player.attach(document.querySelector('video'));\n * player.load('@author/permlink');\n * player.on('ready', ({ isVertical }) => console.log('vertical?', isVertical));\n * ```\n */\nexport class Player {\n private config: Required<PlayerConfig>;\n private api: ThreeSpeakApi;\n private platform = detectPlatform();\n private video: HTMLVideoElement | null = null;\n private hls: Hls | null = null;\n private listeners = new Map<string, Set<Function>>();\n private fallbackIndex = 0;\n private fallbacks: string[] = [];\n private _ready = false;\n private _destroyed = false;\n private _audioOnly = false;\n private _currentRef: string | null = null;\n private _resumeSaveTimer: ReturnType<typeof setTimeout> | null = null;\n private _observer: IntersectionObserver | null = null;\n private cleanupFns: (() => void)[] = [];\n\n constructor(config?: PlayerConfig) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.api = new ThreeSpeakApi(this.config.apiBase, this.config.debug);\n this._audioOnly = this.config.audioOnly;\n }\n\n private log(...args: unknown[]) {\n if (this.config.debug) console.log('[3Speak Player]', ...args);\n }\n\n // ─── Event Emitter ───\n\n /**\n * Subscribe to a player event.\n * @returns Unsubscribe function\n */\n on<T extends keyof PlayerEvents>(event: T, handler: EventHandler<T>): EventUnsubscribe {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(handler);\n return () => this.off(event, handler);\n }\n\n /** Unsubscribe from a player event. */\n off<T extends keyof PlayerEvents>(event: T, handler: EventHandler<T>): void {\n this.listeners.get(event)?.delete(handler);\n }\n\n /** Subscribe to a player event, auto-unsubscribe after first call. */\n once<T extends keyof PlayerEvents>(event: T, handler: EventHandler<T>): EventUnsubscribe {\n const wrapped = ((...args: unknown[]) => {\n unsub();\n (handler as Function)(...args);\n }) as EventHandler<T>;\n const unsub = this.on(event, wrapped);\n return unsub;\n }\n\n private emit<T extends keyof PlayerEvents>(event: T, ...args: Parameters<PlayerEvents[T]>): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n (handler as Function)(...args);\n } catch (e) {\n console.error(`[3Speak Player] Error in ${event} handler:`, e);\n }\n });\n }\n\n // ─── Lifecycle ───\n\n /**\n * Attach the player to a <video> element.\n * Sets required attributes (playsinline, etc.) automatically.\n */\n attach(element: HTMLVideoElement): this {\n if (this._destroyed) throw new Error('Player is destroyed');\n if (this.video === element) return this;\n\n // Clean up previous attachment\n this.detach();\n\n this.video = element;\n\n // Set required attributes for iOS\n element.setAttribute('playsinline', '');\n element.setAttribute('webkit-playsinline', '');\n element.muted = this.config.muted;\n element.loop = this.config.loop;\n\n // Bind events\n this.bindVideoEvents(element);\n\n // Auto-pause on scroll out\n if (this.config.autopause) {\n this.setupAutopause(element);\n }\n\n this.log('Attached to video element');\n return this;\n }\n\n /**\n * Detach from the current video element and clean up HLS.\n */\n detach(): this {\n this.destroyHls();\n this.cleanupFns.forEach((fn) => fn());\n this.cleanupFns = [];\n\n if (this.video) {\n this.video.pause();\n this.video.removeAttribute('src');\n this.video.load();\n }\n\n this.destroyAutopause();\n if (this._resumeSaveTimer) {\n clearTimeout(this._resumeSaveTimer);\n this._resumeSaveTimer = null;\n }\n\n this.video = null;\n this._ready = false;\n this.fallbackIndex = 0;\n this.fallbacks = [];\n return this;\n }\n\n /**\n * Load a video by author/permlink (fetches HLS URL from 3Speak API).\n * @param ref - Either \"author/permlink\" or \"@author/permlink\"\n */\n async load(ref: string): Promise<this>;\n /**\n * Load a video from a direct VideoSource.\n */\n async load(source: VideoSource): Promise<this>;\n async load(refOrSource: string | VideoSource): Promise<this> {\n if (!this.video) throw new Error('No video element attached. Call attach() first.');\n\n let source: VideoSource;\n\n if (typeof refOrSource === 'string') {\n const clean = refOrSource.replace(/^@/, '');\n const [author, permlink] = clean.split('/');\n if (!author || !permlink) throw new Error(`Invalid video ref: \"${refOrSource}\". Use \"author/permlink\".`);\n\n this._currentRef = clean;\n this.log('Loading from API:', author, permlink);\n this.emit('loading', true as any);\n source = await this.api.fetchSource(author, permlink);\n } else {\n this._currentRef = null;\n source = refOrSource;\n }\n\n this._ready = false;\n this.fallbackIndex = 0;\n this.fallbacks = source.fallbacks || [];\n\n if (this.config.poster && source.poster && this.video) {\n this.video.poster = source.poster;\n }\n\n this.loadSource(source.url);\n this.emit('loading', true as any);\n return this;\n }\n\n // ─── Playback Controls ───\n\n play(): Promise<void> {\n if (!this.video) return Promise.resolve();\n const promise = this.video.play();\n return promise || Promise.resolve();\n }\n\n pause(): void {\n this.video?.pause();\n }\n\n togglePlay(): void {\n if (!this.video) return;\n if (this.video.paused) {\n this.play();\n } else {\n this.pause();\n }\n }\n\n seek(time: number): void {\n if (this.video) this.video.currentTime = time;\n }\n\n /** Set muted state */\n setMuted(muted: boolean): void {\n if (this.video) this.video.muted = muted;\n }\n\n /** Set volume (0-1) */\n setVolume(volume: number): void {\n if (this.video) this.video.volume = Math.max(0, Math.min(1, volume));\n }\n\n /** Set loop mode */\n setLoop(loop: boolean): void {\n this.config.loop = loop;\n if (this.video) this.video.loop = loop;\n }\n\n /** Set playback rate */\n setPlaybackRate(rate: number): void {\n if (this.video) this.video.playbackRate = rate;\n }\n\n /** Toggle Picture-in-Picture mode */\n async togglePip(): Promise<void> {\n if (!this.video) return;\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else if (this.video.requestPictureInPicture) {\n await this.video.requestPictureInPicture();\n }\n } catch (e) {\n this.log('PiP toggle failed:', e);\n }\n }\n\n /** Toggle fullscreen mode */\n async toggleFullscreen(): Promise<void> {\n if (!this.video) return;\n try {\n if (document.fullscreenElement) {\n await document.exitFullscreen();\n } else {\n await this.video.requestFullscreen();\n }\n } catch (e) {\n this.log('Fullscreen toggle failed:', e);\n }\n }\n\n /** Get available quality levels (hls.js only, empty for native HLS) */\n getQualities(): QualityLevel[] {\n if (!this.hls) return [];\n return this.hls.levels.map((level, index) => ({\n index,\n height: level.height,\n width: level.width,\n bitrate: level.bitrate,\n }));\n }\n\n /** Set quality level (-1 for auto, hls.js only) */\n setQuality(index: number): void {\n if (this.hls) this.hls.currentLevel = index;\n }\n\n /** Get current quality level index (-1 = auto, hls.js only) */\n getCurrentQuality(): number {\n return this.hls?.currentLevel ?? -1;\n }\n\n /**\n * Get thumbnail at a given time. Currently returns the poster image.\n * Reserved for future sprite sheet support.\n */\n getThumbnailAt(_time: number): string | null {\n return this.video?.poster || null;\n }\n\n /** Set audio-only mode (hides video, keeps audio playing) */\n setAudioOnly(enabled: boolean): void {\n this._audioOnly = enabled;\n if (this.video) {\n this.video.style.visibility = enabled ? 'hidden' : '';\n }\n this.log('Audio-only:', enabled);\n }\n\n /** Enable auto-pause when video scrolls out of viewport */\n enableAutopause(): void {\n this.config.autopause = true;\n if (this.video && !this._observer) {\n this.setupAutopause(this.video);\n }\n }\n\n /** Disable auto-pause on scroll out */\n disableAutopause(): void {\n this.config.autopause = false;\n this.destroyAutopause();\n }\n\n /** Clear saved resume position for a video ref. Clears current video if no ref given. */\n clearResumePosition(ref?: string): void {\n const key = ref || this._currentRef;\n if (key) {\n try { localStorage.removeItem(`3speak_pos_${key}`); } catch {}\n this.log('Cleared resume position for', key);\n }\n }\n\n // ─── State ───\n\n /** Get current player state snapshot */\n getState(): PlayerState {\n const v = this.video;\n let buffered = 0;\n if (v && v.buffered.length > 0 && v.duration > 0) {\n buffered = v.buffered.end(v.buffered.length - 1) / v.duration;\n }\n return {\n currentTime: v?.currentTime || 0,\n duration: v?.duration || 0,\n paused: v?.paused ?? true,\n muted: v?.muted ?? this.config.muted,\n volume: v?.volume ?? 1,\n ready: this._ready,\n loading: !this._ready && !!this.video?.src,\n isVertical: v ? (v.videoHeight > v.videoWidth ? true : v.videoWidth > 0 ? false : null) : null,\n videoWidth: v?.videoWidth || 0,\n videoHeight: v?.videoHeight || 0,\n buffered,\n pip: !!document.pictureInPictureElement && document.pictureInPictureElement === v,\n fullscreen: !!document.fullscreenElement && document.fullscreenElement === v,\n audioOnly: this._audioOnly,\n };\n }\n\n /** Whether the player has loaded metadata and is ready to play */\n get ready(): boolean {\n return this._ready;\n }\n\n /** Whether this player instance has been destroyed */\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n /** The underlying <video> element (if attached) */\n get element(): HTMLVideoElement | null {\n return this.video;\n }\n\n /** Access the 3Speak API client */\n get apiClient(): ThreeSpeakApi {\n return this.api;\n }\n\n // ─── Cleanup ───\n\n /**\n * Destroy the player and release all resources.\n * Cannot be used after this.\n */\n destroy(): void {\n this.detach();\n this.listeners.clear();\n this._destroyed = true;\n this.log('Destroyed');\n }\n\n // ─── Private ───\n\n private loadSource(hlsUrl: string): void {\n if (!this.video) return;\n\n // Clean up any existing HLS instance\n this.destroyHls();\n\n const platform = this.platform;\n\n if (platform.isIOS || (platform.isSafari && !platform.supportsHlsJs)) {\n // iOS Safari / older Safari: native HLS\n this.log('Using native HLS');\n this.video.src = hlsUrl;\n } else if (platform.supportsHlsJs) {\n // Chrome, Firefox, Edge: use hls.js\n this.log('Using hls.js');\n const hls = new Hls({\n enableWorker: true,\n lowLatencyMode: false,\n maxBufferSize: 10 * 1000 * 1000,\n maxBufferLength: 15,\n startLevel: 0,\n startFragPrefetch: true,\n ...this.config.hlsConfig,\n });\n\n hls.loadSource(hlsUrl);\n hls.attachMedia(this.video);\n\n hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {\n const level = hls.levels[data.level];\n if (level) {\n this.emit('qualitychange', {\n index: data.level,\n height: level.height,\n width: level.width,\n bitrate: level.bitrate,\n });\n }\n });\n\n hls.on(Hls.Events.ERROR, (_event, data) => {\n if (data.fatal) {\n this.log('Fatal HLS error:', data.type, data.details);\n if (this.tryFallback(hls)) return;\n\n this.emit('error', {\n message: `HLS fatal error: ${data.details}`,\n code: data.response?.code,\n fatal: true,\n });\n hls.destroy();\n this.hls = null;\n } else {\n this.emit('error', {\n message: `HLS error: ${data.details}`,\n fatal: false,\n });\n }\n });\n\n this.hls = hls;\n } else if (platform.supportsNativeHLS) {\n // Fallback: native HLS on non-Safari (unlikely but safe)\n this.video.src = hlsUrl;\n } else {\n this.emit('error', {\n message: 'No HLS support detected. Cannot play this video.',\n fatal: true,\n });\n }\n }\n\n private tryFallback(hls?: Hls): boolean {\n if (this.fallbackIndex < this.fallbacks.length) {\n const fallbackUrl = this.fallbacks[this.fallbackIndex];\n this.fallbackIndex++;\n this.log(`Trying fallback ${this.fallbackIndex}:`, fallbackUrl.substring(0, 80));\n this.emit('fallback', { url: fallbackUrl, index: this.fallbackIndex });\n\n if (hls) {\n hls.loadSource(fallbackUrl);\n } else if (this.video) {\n this.video.src = fallbackUrl;\n }\n return true;\n }\n return false;\n }\n\n private destroyHls(): void {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n }\n\n private setupAutopause(element: HTMLVideoElement): void {\n if (typeof IntersectionObserver === 'undefined') return;\n this.destroyAutopause();\n this._observer = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n const visible = entry.isIntersecting;\n this.emit('visibility', visible);\n if (!visible && !this.video?.paused) {\n this.pause();\n this.log('Auto-paused (scrolled out of view)');\n }\n },\n { threshold: 0.25 },\n );\n this._observer.observe(element);\n }\n\n private destroyAutopause(): void {\n if (this._observer) {\n this._observer.disconnect();\n this._observer = null;\n }\n }\n\n private saveResumePosition(): void {\n if (!this.config.resume || !this._currentRef || !this.video) return;\n const time = this.video.currentTime;\n if (time < 1) return; // Don't save near the start\n try { localStorage.setItem(`3speak_pos_${this._currentRef}`, String(time)); } catch {}\n }\n\n private restoreResumePosition(): void {\n if (!this.config.resume || !this._currentRef || !this.video) return;\n try {\n const saved = localStorage.getItem(`3speak_pos_${this._currentRef}`);\n if (!saved) return;\n const time = parseFloat(saved);\n if (isNaN(time) || time < 1) return;\n // Skip if near the end (within 3s)\n const duration = this.video.duration;\n if (duration && time > duration - 3) return;\n this.video.currentTime = time;\n this.emit('resume', { time, ref: this._currentRef });\n this.log('Resumed at', time.toFixed(1) + 's');\n } catch {}\n }\n\n private bindVideoEvents(video: HTMLVideoElement): void {\n const on = <K extends keyof HTMLVideoElementEventMap>(\n event: K,\n handler: (e: HTMLVideoElementEventMap[K]) => void\n ) => {\n video.addEventListener(event, handler);\n this.cleanupFns.push(() => video.removeEventListener(event, handler));\n };\n\n on('loadedmetadata', () => {\n if (this._ready) return;\n const w = video.videoWidth;\n const h = video.videoHeight;\n if (w && h) {\n this._ready = true;\n const isVertical = h > w;\n this.restoreResumePosition();\n this.emit('ready', { isVertical, width: w, height: h });\n this.emit('resize', { isVertical, width: w, height: h });\n this.emit('loading', false as any);\n this.log(`Ready: ${w}x${h} (${isVertical ? 'vertical' : 'horizontal'})`);\n }\n });\n\n // Fallback for browsers that fire loadeddata before loadedmetadata has dimensions\n on('loadeddata', () => {\n if (!this._ready && video.videoWidth && video.videoHeight) {\n this._ready = true;\n const isVertical = video.videoHeight > video.videoWidth;\n this.emit('ready', { isVertical, width: video.videoWidth, height: video.videoHeight });\n this.emit('resize', { isVertical, width: video.videoWidth, height: video.videoHeight });\n this.emit('loading', false as any);\n }\n });\n\n on('timeupdate', () => {\n this.emit('timeupdate', {\n currentTime: video.currentTime,\n duration: video.duration || 0,\n paused: video.paused,\n });\n // Throttle-save resume position (every 3s)\n if (this.config.resume && this._currentRef && !this._resumeSaveTimer) {\n this._resumeSaveTimer = setTimeout(() => {\n this._resumeSaveTimer = null;\n this.saveResumePosition();\n }, 3000);\n }\n });\n\n on('play', () => this.emit('play'));\n on('pause', () => this.emit('pause'));\n on('ended', () => this.emit('ended'));\n\n on('waiting', () => this.emit('loading', true as any));\n on('canplay', () => { if (this._ready) this.emit('loading', false as any); });\n\n on('progress', () => {\n if (video.buffered.length > 0 && video.duration > 0) {\n this.emit('buffered', video.buffered.end(video.buffered.length - 1) / video.duration);\n }\n });\n\n on('enterpictureinpicture' as any, () => this.emit('pip', true));\n on('leavepictureinpicture' as any, () => this.emit('pip', false));\n\n const onFullscreenChange = () => {\n this.emit('fullscreen', document.fullscreenElement === video);\n };\n document.addEventListener('fullscreenchange', onFullscreenChange);\n this.cleanupFns.push(() => document.removeEventListener('fullscreenchange', onFullscreenChange));\n\n // Native fallback on error (iOS / non-hls.js)\n on('error', () => {\n if (!this.hls && !this.tryFallback()) {\n this.emit('error', {\n message: video.error?.message || 'Video playback error',\n code: video.error?.code,\n fatal: true,\n });\n }\n });\n }\n}\n","import { Player } from './player';\nimport { ThreeSpeakApi } from './api';\nimport { detectPlatform } from './platform';\nimport type { PlayerConfig, VideoSource } from '../types';\n\n/**\n * Manages a pool of Player instances for feed/shorts-style UIs.\n *\n * Handles:\n * - Creating/recycling players for visible videos\n * - Pausing all except the active player\n * - Manifest prefetching for upcoming videos on iOS\n * - Cleaning up off-screen players\n *\n * @example\n * ```js\n * const pool = new PlayerPool({ muted: true, loop: true });\n *\n * // Add videos as they enter the viewport\n * pool.add('vid-1', videoElement1, { url: 'https://...' });\n * pool.add('vid-2', videoElement2, { url: 'https://...' });\n *\n * // Activate the current video (pauses all others)\n * pool.activate('vid-1');\n *\n * // Remove when scrolled out of range\n * pool.remove('vid-2');\n *\n * // Clean up\n * pool.destroy();\n * ```\n */\nexport class PlayerPool {\n private players = new Map<string, Player>();\n private activeId: string | null = null;\n private config: PlayerConfig;\n private api: ThreeSpeakApi;\n private platform = detectPlatform();\n\n constructor(config?: PlayerConfig) {\n this.config = config || {};\n this.api = new ThreeSpeakApi(config?.apiBase, config?.debug);\n }\n\n /**\n * Add a player to the pool.\n * @param id - Unique identifier for this video slot\n * @param element - The <video> element to attach to\n * @param source - Video source (optional — can call load() later)\n */\n add(id: string, element: HTMLVideoElement, source?: VideoSource): Player {\n // Reuse existing player if same element\n let player = this.players.get(id);\n if (player && player.element === element) {\n if (source) player.load(source);\n return player;\n }\n\n // Clean up old player for this id\n if (player) player.destroy();\n\n player = new Player(this.config);\n player.attach(element);\n this.players.set(id, player);\n\n if (source) player.load(source);\n\n return player;\n }\n\n /**\n * Add a player by 3Speak author/permlink (auto-fetches HLS URL).\n */\n async addByRef(id: string, element: HTMLVideoElement, author: string, permlink: string): Promise<Player> {\n const player = this.add(id, element);\n await player.load(`${author}/${permlink}`);\n return player;\n }\n\n /**\n * Get a player by id.\n */\n get(id: string): Player | undefined {\n return this.players.get(id);\n }\n\n /**\n * Remove a player from the pool and destroy it.\n */\n remove(id: string): void {\n const player = this.players.get(id);\n if (player) {\n player.destroy();\n this.players.delete(id);\n if (this.activeId === id) this.activeId = null;\n }\n }\n\n /**\n * Activate a player (play it, pause all others).\n */\n activate(id: string): void {\n this.activeId = id;\n\n for (const [playerId, player] of this.players) {\n if (playerId === id) {\n player.play();\n } else {\n player.pause();\n }\n }\n }\n\n /** Pause all players. */\n pauseAll(): void {\n for (const player of this.players.values()) {\n player.pause();\n }\n }\n\n /** Set muted state on all players. */\n setAllMuted(muted: boolean): void {\n for (const player of this.players.values()) {\n player.setMuted(muted);\n }\n }\n\n /** Set loop on all players. */\n setAllLoop(loop: boolean): void {\n for (const player of this.players.values()) {\n player.setLoop(loop);\n }\n }\n\n /** Get the currently active player. */\n getActive(): Player | undefined {\n return this.activeId ? this.players.get(this.activeId) : undefined;\n }\n\n /** Get the active player's id. */\n get activePlayerId(): string | null {\n return this.activeId;\n }\n\n /** Number of players in the pool. */\n get size(): number {\n return this.players.size;\n }\n\n /** All player ids in the pool. */\n get ids(): string[] {\n return [...this.players.keys()];\n }\n\n /**\n * Prefetch an HLS manifest (warms CDN, ~1-5KB).\n * Especially useful on iOS where we can't preload actual video data.\n */\n async prefetch(hlsUrl: string): Promise<void> {\n return this.api.prefetchManifest(hlsUrl);\n }\n\n /**\n * Prefetch a manifest by author/permlink.\n */\n async prefetchByRef(author: string, permlink: string): Promise<void> {\n const source = await this.api.fetchSource(author, permlink);\n return this.api.prefetchManifest(source.url);\n }\n\n /**\n * Retain only the given ids, destroy all others.\n * Useful for keeping a sliding window of players around the current index.\n */\n retainOnly(ids: Set<string> | string[]): void {\n const keep = ids instanceof Set ? ids : new Set(ids);\n for (const [id, player] of this.players) {\n if (!keep.has(id)) {\n player.destroy();\n this.players.delete(id);\n if (this.activeId === id) this.activeId = null;\n }\n }\n }\n\n /**\n * Destroy all players and the pool.\n */\n destroy(): void {\n for (const player of this.players.values()) {\n player.destroy();\n }\n this.players.clear();\n this.activeId = null;\n }\n}\n"]}