vidply 1.1.7 → 1.1.9

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.
Files changed (33) hide show
  1. package/dist/dev/{vidply.AudioDescriptionManager-DCZFE3N2.js → vidply.AudioDescriptionManager-HUWRAHX4.js} +2 -2
  2. package/dist/dev/{vidply.DASHRenderer-HP7BXLGV.js → vidply.DASHRenderer-DAIMQ7NC.js} +13 -3
  3. package/dist/dev/vidply.DASHRenderer-DAIMQ7NC.js.map +7 -0
  4. package/dist/dev/{vidply.HLSRenderer-IVT5CQQ4.js → vidply.HLSRenderer-7XRBH6P3.js} +7 -1
  5. package/dist/dev/vidply.HLSRenderer-7XRBH6P3.js.map +7 -0
  6. package/dist/dev/{vidply.chunk-2RIPRXWI.js → vidply.chunk-JBW74LP7.js} +37 -2
  7. package/dist/dev/vidply.chunk-JBW74LP7.js.map +7 -0
  8. package/dist/dev/vidply.esm.js +8 -5
  9. package/dist/dev/vidply.esm.js.map +2 -2
  10. package/dist/legacy/vidply.js +58 -4
  11. package/dist/legacy/vidply.js.map +2 -2
  12. package/dist/legacy/vidply.min.js +1 -1
  13. package/dist/legacy/vidply.min.meta.json +11 -11
  14. package/dist/prod/{vidply.AudioDescriptionManager-JJFZSG7G.min.js → vidply.AudioDescriptionManager-4TFVBYZU.min.js} +1 -1
  15. package/dist/prod/vidply.DASHRenderer-AGZ27ACW.min.js +6 -0
  16. package/dist/prod/vidply.HLSRenderer-ZT2YDQNA.min.js +6 -0
  17. package/dist/prod/vidply.chunk-6OJPJD4H.min.js +6 -0
  18. package/dist/prod/vidply.esm.min.js +1 -1
  19. package/dist/vidply.esm.min.meta.json +23 -23
  20. package/package.json +2 -2
  21. package/src/controls/CaptionManager.ts +48 -1
  22. package/src/controls/ControlBar.ts +18 -3
  23. package/src/core/Player.ts +3 -0
  24. package/src/renderers/DASHRenderer.ts +12 -2
  25. package/src/renderers/HLSRenderer.ts +8 -0
  26. package/src/types/renderer.ts +9 -0
  27. package/dist/dev/vidply.DASHRenderer-HP7BXLGV.js.map +0 -7
  28. package/dist/dev/vidply.HLSRenderer-IVT5CQQ4.js.map +0 -7
  29. package/dist/dev/vidply.chunk-2RIPRXWI.js.map +0 -7
  30. package/dist/prod/vidply.DASHRenderer-U5QKC66O.min.js +0 -6
  31. package/dist/prod/vidply.HLSRenderer-DBXM4KLR.min.js +0 -6
  32. package/dist/prod/vidply.chunk-MOAZJSWV.min.js +0 -6
  33. /package/dist/dev/{vidply.AudioDescriptionManager-DCZFE3N2.js.map → vidply.AudioDescriptionManager-HUWRAHX4.js.map} +0 -0
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import {
7
7
  CaptionManager
8
- } from "./vidply.chunk-2RIPRXWI.js";
8
+ } from "./vidply.chunk-JBW74LP7.js";
9
9
  import "./vidply.chunk-X6PJOVWZ.js";
10
10
  import "./vidply.chunk-FDUUJHK6.js";
11
11
 
@@ -569,4 +569,4 @@ var AudioDescriptionManager = class {
569
569
  export {
570
570
  AudioDescriptionManager
571
571
  };
572
- //# sourceMappingURL=vidply.AudioDescriptionManager-DCZFE3N2.js.map
572
+ //# sourceMappingURL=vidply.AudioDescriptionManager-HUWRAHX4.js.map
@@ -9,6 +9,7 @@ var DASHRenderer = class {
9
9
  player;
10
10
  media;
11
11
  dash;
12
+ isStreaming = true;
12
13
  _dashSourceLoaded;
13
14
  _pendingSrc;
14
15
  _dashSubtitleTracksCount;
@@ -63,10 +64,19 @@ var DASHRenderer = class {
63
64
  logLevel: this.player.options.debug ? 4 : 0
64
65
  },
65
66
  streaming: {
67
+ // Override dash.js default of 'lowestStartupDelay'. For audio
68
+ // AdaptationSets that tie on selectionPriority and role=main (e.g.
69
+ // Axinom's three en/en-low/en-high tracks), 'lowestStartupDelay'
70
+ // falls through to 'highestEfficiency' which, for audio, has no
71
+ // meaningful pixels-per-bit metric and collapses to "highest
72
+ // bitrate". 'firstTrack' respects manifest order instead, which is
73
+ // both predictable and closer to the MPD author's intent.
74
+ selectionModeForInitialTrack: "firstTrack",
66
75
  buffer: {
67
76
  bufferTimeAtTopQuality: 30,
68
77
  bufferTimeAtTopQualityLongForm: 60,
69
- stableBufferTime: 12,
78
+ // dash.js 5.x: use bufferTimeDefault (replaces removed stableBufferTime)
79
+ bufferTimeDefault: 12,
70
80
  bufferToKeep: 20,
71
81
  bufferPruningInterval: 10
72
82
  },
@@ -129,7 +139,7 @@ var DASHRenderer = class {
129
139
  async loadDashJs() {
130
140
  return new Promise((resolve, reject) => {
131
141
  const script = document.createElement("script");
132
- script.src = "https://cdn.jsdelivr.net/npm/dashjs@latest/dist/dash.all.min.js";
142
+ script.src = "https://cdn.jsdelivr.net/npm/dashjs@5.1.1/dist/modern/umd/dash.all.min.js";
133
143
  script.onload = () => resolve();
134
144
  script.onerror = () => reject(new Error("Failed to load dash.js"));
135
145
  document.head.appendChild(script);
@@ -679,4 +689,4 @@ var DASHRenderer = class {
679
689
  export {
680
690
  DASHRenderer
681
691
  };
682
- //# sourceMappingURL=vidply.DASHRenderer-HP7BXLGV.js.map
692
+ //# sourceMappingURL=vidply.DASHRenderer-DAIMQ7NC.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/renderers/DASHRenderer.ts"],
4
+ "sourcesContent": ["import type { Renderer } from '../types/renderer.js';\r\nimport type { Player } from '../core/Player.js';\r\n\r\ninterface DashTextTrack {\r\n lang?: string;\r\n language?: string;\r\n srclang?: string;\r\n kind?: string;\r\n [key: string]: unknown;\r\n}\r\n\r\nexport class DASHRenderer implements Renderer {\r\n player: Player;\r\n media: HTMLMediaElement;\r\n dash: any;\r\n readonly isStreaming = true;\r\n _dashSourceLoaded: boolean;\r\n _pendingSrc: string | null;\r\n _dashSubtitleTracksCount: number | undefined;\r\n _dashTextTracks: DashTextTrack[];\r\n _cueUpdateTimer: ReturnType<typeof setInterval> | null;\r\n _captionEnabledHandler: ((...args: any[]) => void) | null;\r\n _captionDisabledHandler: ((...args: any[]) => void) | null;\r\n _lastKnownCueCount: number;\r\n _dashTextIsTtml: boolean;\r\n _pendingTimeouts: ReturnType<typeof setTimeout>[];\r\n _ttmlDiv: HTMLElement | null;\r\n\r\n constructor(player: Player) {\r\n this.player = player;\r\n this.media = player.element;\r\n this.dash = null;\r\n this._dashSourceLoaded = false;\r\n this._pendingSrc = null;\r\n this._dashSubtitleTracksCount = undefined;\r\n this._dashTextTracks = [];\r\n this._cueUpdateTimer = null;\r\n this._captionEnabledHandler = null;\r\n this._captionDisabledHandler = null;\r\n this._lastKnownCueCount = 0;\r\n this._dashTextIsTtml = false;\r\n this._pendingTimeouts = [];\r\n this._ttmlDiv = null;\r\n }\r\n\r\n async init() {\r\n this.player.log('Using dash.js for DASH support');\r\n await this.initDashJs();\r\n }\r\n\r\n async initDashJs() {\r\n this.media.controls = false;\r\n this.media.removeAttribute('controls');\r\n\r\n if (!window.dashjs) {\r\n await this.loadDashJs();\r\n }\r\n\r\n // Remove <source> children — dash.js manages the src via MSE\r\n const sourceElements = Array.from(this.media.querySelectorAll('source'));\r\n let originalSrc = null;\r\n if (sourceElements.length > 0) {\r\n originalSrc = sourceElements[0].getAttribute('src');\r\n sourceElements.forEach(source => source.remove());\r\n this.player.log('Removed <source> elements for HTML5 validity (dash.js uses MSE)');\r\n }\r\n\r\n const dashjs = window.dashjs;\r\n if (!dashjs) {\r\n throw new Error('dash.js not available');\r\n }\r\n this.dash = dashjs.MediaPlayer().create();\r\n\r\n this.dash.updateSettings({\r\n debug: {\r\n logLevel: this.player.options.debug ? 4 : 0\r\n },\r\n streaming: {\r\n // Override dash.js default of 'lowestStartupDelay'. For audio\r\n // AdaptationSets that tie on selectionPriority and role=main (e.g.\r\n // Axinom's three en/en-low/en-high tracks), 'lowestStartupDelay'\r\n // falls through to 'highestEfficiency' which, for audio, has no\r\n // meaningful pixels-per-bit metric and collapses to \"highest\r\n // bitrate\". 'firstTrack' respects manifest order instead, which is\r\n // both predictable and closer to the MPD author's intent.\r\n selectionModeForInitialTrack: 'firstTrack',\r\n buffer: {\r\n bufferTimeAtTopQuality: 30,\r\n bufferTimeAtTopQualityLongForm: 60,\r\n // dash.js 5.x: use bufferTimeDefault (replaces removed stableBufferTime)\r\n bufferTimeDefault: 12,\r\n bufferToKeep: 20,\r\n bufferPruningInterval: 10\r\n },\r\n retryAttempts: {\r\n MPD: 4,\r\n MediaSegment: 6,\r\n InitializationSegment: 4,\r\n BitstreamSwitchingSegment: 4\r\n },\r\n retryIntervals: {\r\n MPD: 1000,\r\n MediaSegment: 1000,\r\n InitializationSegment: 1000,\r\n BitstreamSwitchingSegment: 1000\r\n },\r\n abr: {\r\n autoSwitchBitrate: { video: true, audio: true }\r\n },\r\n text: {\r\n defaultEnabled: true\r\n }\r\n }\r\n });\r\n\r\n // Create the TTML rendering div before initialize() so the DOM element\r\n // exists, but attach it to dash.js after initialize() because\r\n // attachTTMLRenderingDiv() requires attachView() which initialize() calls.\r\n this._ttmlDiv = document.createElement('div');\r\n this._ttmlDiv.className = 'vidply-dash-ttml';\r\n this._ttmlDiv.style.visibility = 'hidden';\r\n const wrapper = this.player.videoWrapper || this.media.parentElement;\r\n if (wrapper) {\r\n wrapper.appendChild(this._ttmlDiv);\r\n }\r\n\r\n this.dash.initialize(this.media, null, false);\r\n this.dash.attachTTMLRenderingDiv(this._ttmlDiv);\r\n\r\n // Resolve source URL\r\n let src = this.player.currentSource;\r\n\r\n if (!src && originalSrc) {\r\n src = originalSrc;\r\n }\r\n\r\n if (!src) {\r\n src = this.player.element.getAttribute('data-vidply-src');\r\n }\r\n\r\n if (!src) {\r\n const elementSrc = this.player.element.getAttribute('src') || this.player.element.src;\r\n if (elementSrc && !elementSrc.startsWith('blob:')) {\r\n src = elementSrc;\r\n }\r\n }\r\n\r\n this.player.log(`Loading DASH source: ${src}`, 'log');\r\n\r\n if (!src) {\r\n throw new Error('No DASH source found');\r\n }\r\n\r\n if (this.player.options.deferLoad) {\r\n this._pendingSrc = src;\r\n } else {\r\n this.dash.attachSource(src);\r\n this._dashSourceLoaded = true;\r\n }\r\n\r\n this.attachDashEvents();\r\n this.attachMediaEvents();\r\n this._setupCaptionSync();\r\n }\r\n\r\n async loadDashJs() {\r\n return new Promise<void>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = 'https://cdn.jsdelivr.net/npm/dashjs@5.1.1/dist/modern/umd/dash.all.min.js';\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error('Failed to load dash.js'));\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n _setTimeout(fn: () => void, delay: number) {\r\n const id = setTimeout(() => {\r\n this._pendingTimeouts = this._pendingTimeouts.filter(t => t !== id);\r\n fn();\r\n }, delay);\r\n this._pendingTimeouts.push(id);\r\n return id;\r\n }\r\n\r\n attachDashEvents() {\r\n const dashjs = window.dashjs;\r\n if (!dashjs) return;\r\n const dashEvents = dashjs.MediaPlayer.events;\r\n\r\n this.dash.on(dashEvents.MANIFEST_LOADED, (e: any) => {\r\n const data = e.data || e;\r\n this.player.log('DASH manifest loaded');\r\n this.player.emit('dashmanifestloaded', data);\r\n\r\n if (this.player.container) {\r\n this.player.container.classList.remove('vidply-external-controls');\r\n }\r\n\r\n this._setTimeout(() => {\r\n this._checkSubtitleTracks();\r\n }, 500);\r\n });\r\n\r\n this.dash.on(dashEvents.QUALITY_CHANGE_RENDERED, (e: any) => {\r\n if (e.mediaType === 'video') {\r\n this.player.log('DASH quality changed to index ' + e.newQuality);\r\n this.player.emit('dashqualitychanged', e);\r\n }\r\n });\r\n\r\n this.dash.on(dashEvents.TEXT_TRACKS_ADDED, (e: any) => {\r\n const tracks = e.tracks || [];\r\n this._dashTextTracks = tracks;\r\n this._dashTextIsTtml = tracks.some((t: any) =>\r\n t.isTTML || /stpp|ttml/i.test(t.codec || '') || /ttml/i.test(t.mimeType || '')\r\n );\r\n this.player.log(`DASH text tracks added: ${tracks.length} tracks, format: ${this._dashTextIsTtml ? 'TTML' : 'WebVTT'}`);\r\n this._dashSubtitleTracksCount = tracks.length;\r\n this.player.emit('dashsubtitletracksupdated', { tracks });\r\n this.updateCaptionButtonsForDash();\r\n\r\n if (tracks.length > 0) {\r\n try {\r\n this.dash.setTextTrack(0);\r\n } catch (err) {\r\n // ignore if not ready yet\r\n }\r\n if (!this._dashTextIsTtml) {\r\n this._startCueUpdatePolling();\r\n }\r\n }\r\n });\r\n\r\n this.dash.on(dashEvents.STREAM_INITIALIZED, () => {\r\n this.player.log('DASH stream initialized');\r\n this.player.emit('dashstreaminitialized');\r\n\r\n this._setTimeout(() => {\r\n const qualities = this.getQualities();\r\n if (qualities.length > 0) {\r\n this.player.emit('dashmanifestparsed', { qualities });\r\n }\r\n }, 300);\r\n });\r\n\r\n this.dash.on(dashEvents.ERROR, (e: any) => {\r\n this.handleDashError(e);\r\n });\r\n\r\n this.dash.on(dashEvents.FRAGMENT_LOADING_COMPLETED, (e: any) => {\r\n this.player.state.buffering = false;\r\n if (e.request && e.request.mediaType === 'text' && !this._dashTextIsTtml) {\r\n this._setTimeout(() => {\r\n const count = this._getTotalCueCount();\r\n if (count > this._lastKnownCueCount) {\r\n this._lastKnownCueCount = count;\r\n this.player.emit('textcuesupdate');\r\n }\r\n }, 100);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Count total cues across all subtitle/caption tracks (for WebVTT DASH).\r\n */\r\n _getTotalCueCount() {\r\n const textTracks = this.media.textTracks;\r\n let total = 0;\r\n if (!textTracks) return total;\r\n for (let i = 0; i < textTracks.length; i++) {\r\n const track = textTracks[i];\r\n if ((track.kind === 'subtitles' || track.kind === 'captions') && !track._vidplyStale && track.cues) {\r\n total += track.cues.length;\r\n }\r\n }\r\n return total;\r\n }\r\n\r\n /**\r\n * Sync VidPly caption track switches with dash.js so it loads\r\n * subtitle segments for the selected language.\r\n */\r\n _setupCaptionSync() {\r\n this._captionEnabledHandler = (selectedTrack) => {\r\n if (this._dashTextIsTtml) {\r\n // dash.js only renders TTML content to the rendering div when the\r\n // TextTrack mode is 'showing'. CaptionManager sets it to 'hidden',\r\n // so we override it here. VidPly's own caption overlay is skipped\r\n // via handlesOwnCaptions().\r\n if (selectedTrack.track) {\r\n selectedTrack.track.mode = 'showing';\r\n }\r\n if (this._ttmlDiv) {\r\n this._ttmlDiv.style.visibility = 'visible';\r\n }\r\n }\r\n this._syncDashTextTrack(selectedTrack);\r\n };\r\n this._captionDisabledHandler = () => {\r\n if (this._dashTextIsTtml && this._ttmlDiv) {\r\n this._ttmlDiv.style.visibility = 'hidden';\r\n }\r\n if (this.dash) {\r\n try { this.dash.setTextTrack(-1); } catch (e) { /* ignore */ }\r\n }\r\n };\r\n this.player.on('captionsenabled', this._captionEnabledHandler);\r\n this.player.on('captionsdisabled', this._captionDisabledHandler);\r\n }\r\n\r\n /**\r\n * Map a VidPly caption track to the corresponding dash.js track index\r\n * and switch dash.js to load segments for that language.\r\n */\r\n _syncDashTextTrack(selectedTrack: any) {\r\n if (!this.dash || !this._dashTextTracks.length) return;\r\n\r\n const lang = selectedTrack.language;\r\n if (!lang) return;\r\n\r\n const dashIndex = this._dashTextTracks.findIndex(dt => {\r\n const dtLang = dt.lang || dt.language || dt.srclang || '';\r\n if (!dtLang) return false;\r\n return dtLang === lang || dtLang.startsWith(lang) || lang.startsWith(dtLang);\r\n });\r\n\r\n if (dashIndex >= 0) {\r\n this.player.log(`Syncing DASH text track to index ${dashIndex} (${lang})`);\r\n try {\r\n this.dash.setTextTrack(dashIndex);\r\n } catch (err) { /* ignore */ }\r\n if (!this._dashTextIsTtml) {\r\n this._lastKnownCueCount = 0;\r\n this._startCueUpdatePolling();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Poll for new WebVTT cues being added by dash.js as subtitle segments load.\r\n * Emits events for transcript refresh when new cues arrive.\r\n */\r\n _startCueUpdatePolling() {\r\n this._stopCueUpdatePolling();\r\n let prevCueCount = 0;\r\n let stableRounds = 0;\r\n\r\n this._cueUpdateTimer = setInterval(() => {\r\n const count = this._getTotalCueCount();\r\n\r\n if (count > prevCueCount) {\r\n prevCueCount = count;\r\n stableRounds = 0;\r\n this.player.emit('textcuesupdate');\r\n } else {\r\n stableRounds++;\r\n if (stableRounds >= 8) {\r\n this._stopCueUpdatePolling();\r\n if (count > 0) {\r\n this.player.emit('textcuesupdate');\r\n }\r\n }\r\n }\r\n }, 500);\r\n }\r\n\r\n _stopCueUpdatePolling() {\r\n if (this._cueUpdateTimer) {\r\n clearInterval(this._cueUpdateTimer);\r\n this._cueUpdateTimer = null;\r\n }\r\n }\r\n\r\n _checkSubtitleTracks() {\r\n if (this._dashSubtitleTracksCount !== undefined && this._dashSubtitleTracksCount > 0) {\r\n return;\r\n }\r\n const tracks = this.media.textTracks;\r\n let count = 0;\r\n for (let i = 0; i < tracks.length; i++) {\r\n const track = tracks[i];\r\n if ((track.kind === 'subtitles' || track.kind === 'captions') && !track._vidplyStale) {\r\n count++;\r\n }\r\n }\r\n this._dashSubtitleTracksCount = count;\r\n this.updateCaptionButtonsForDash();\r\n }\r\n\r\n updateCaptionButtonsForDash() {\r\n const tracksCount = this._dashSubtitleTracksCount || 0;\r\n\r\n const doUpdate = () => {\r\n this.player.invalidateTrackCache();\r\n\r\n if (tracksCount > 0) {\r\n if (this.player.captionManager) {\r\n this.player.captionManager.refreshTracks();\r\n }\r\n\r\n if (!this._dashTextIsTtml && this.player.transcriptManager?.isVisible) {\r\n this.player.transcriptManager.loadTranscriptData();\r\n this.player.transcriptManager.updateLanguageSelector();\r\n }\r\n\r\n if (this.player.controlBar) {\r\n this.player.controlBar.ensureCaptionsButton();\r\n if (!this._dashTextIsTtml) {\r\n this.player.controlBar.ensureCaptionStyleButton();\r\n this.player.controlBar.ensureTranscriptButton();\r\n }\r\n }\r\n } else {\r\n if (this.player.captionManager) {\r\n this.player.captionManager.refreshTracks();\r\n }\r\n\r\n if (this.player.transcriptManager?.isVisible) {\r\n this.player.transcriptManager.hideTranscript();\r\n }\r\n\r\n if (this.player.controlBar) {\r\n this.player.controlBar.removeHlsCaptionButtons(true);\r\n }\r\n }\r\n };\r\n\r\n if (this.player.controlBar) {\r\n doUpdate();\r\n return;\r\n }\r\n\r\n const onReady = () => {\r\n this.player.off('ready', onReady);\r\n doUpdate();\r\n };\r\n this.player.on('ready', onReady);\r\n }\r\n\r\n attachMediaEvents() {\r\n this.media.addEventListener('loadedmetadata', () => {\r\n this.player.state.duration = this.media.duration;\r\n this.player.emit('loadedmetadata');\r\n });\r\n\r\n this.media.addEventListener('durationchange', () => {\r\n const duration = this.media.duration;\r\n if (duration && isFinite(duration) && duration > 0) {\r\n this.player.state.duration = duration;\r\n this.player.emit('durationchange', duration);\r\n }\r\n });\r\n\r\n this.media.addEventListener('play', () => {\r\n this.player.state.playing = true;\r\n this.player.state.paused = false;\r\n this.player.state.ended = false;\r\n this.player.emit('play');\r\n\r\n if (this.player.options.onPlay) {\r\n this.player.options.onPlay.call(this.player);\r\n }\r\n });\r\n\r\n this.media.addEventListener('pause', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.emit('pause');\r\n\r\n if (this.player.options.onPause) {\r\n this.player.options.onPause.call(this.player);\r\n }\r\n });\r\n\r\n this.media.addEventListener('ended', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.state.ended = true;\r\n this.player.emit('ended');\r\n\r\n if (this.player.options.onEnded) {\r\n this.player.options.onEnded.call(this.player);\r\n }\r\n\r\n if (this.player.options.loop) {\r\n this.player.seek(0);\r\n this.player.play();\r\n }\r\n });\r\n\r\n this.media.addEventListener('timeupdate', () => {\r\n this.player.state.currentTime = this.media.currentTime;\r\n this.player.emit('timeupdate', this.media.currentTime);\r\n\r\n if (this.player.options.onTimeUpdate) {\r\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\r\n }\r\n });\r\n\r\n this.media.addEventListener('volumechange', () => {\r\n this.player.state.volume = this.media.volume;\r\n this.player.state.muted = this.media.muted;\r\n this.player.emit('volumechange', this.media.volume);\r\n });\r\n\r\n this.media.addEventListener('seeking', () => {\r\n this.player.state.seeking = true;\r\n this.player.emit('seeking');\r\n });\r\n\r\n this.media.addEventListener('seeked', () => {\r\n this.player.state.seeking = false;\r\n this.player.emit('seeked');\r\n });\r\n\r\n this.media.addEventListener('waiting', () => {\r\n this.player.state.buffering = true;\r\n this.player.emit('waiting');\r\n });\r\n\r\n this.media.addEventListener('canplay', () => {\r\n this.player.state.buffering = false;\r\n this.player.emit('canplay');\r\n });\r\n\r\n this.media.addEventListener('error', () => {\r\n this.player.handleError(this.media.error);\r\n });\r\n }\r\n\r\n handleDashError(e: any) {\r\n const error = e.error || e;\r\n if (!error) return;\r\n const code = error.code ?? '';\r\n const message = error.message || '';\r\n this.player.log(`DASH Error - Code: ${code}, Message: ${message}`, 'warn');\r\n\r\n if (code && code >= 100) {\r\n this.player.log('Fatal DASH error', 'error');\r\n this.player.handleError(new Error(`DASH Error: ${code} - ${message}`));\r\n } else {\r\n this.player.log('Non-fatal DASH error: ' + (message || error), 'warn');\r\n }\r\n }\r\n\r\n ensureLoaded() {\r\n if (!this.player.options.deferLoad) {\r\n return;\r\n }\r\n\r\n if (!this.dash) {\r\n return;\r\n }\r\n\r\n if (this._dashSourceLoaded) {\r\n return;\r\n }\r\n\r\n const src = this._pendingSrc || this.player._pendingSource || this.player.currentSource;\r\n if (!src) {\r\n return;\r\n }\r\n\r\n try {\r\n this.dash.attachSource(src);\r\n this._dashSourceLoaded = true;\r\n } catch (e) {\r\n // ignore\r\n }\r\n }\r\n\r\n play() {\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n\r\n if (this.player.options.deferLoad && this.dash && !this._dashSourceLoaded) {\r\n const src = this._pendingSrc || this.player.currentSource;\r\n if (src) {\r\n try {\r\n this.dash.attachSource(src);\r\n this._dashSourceLoaded = true;\r\n } catch (e) {\r\n // ignore and let media.play() surface errors if any\r\n }\r\n }\r\n }\r\n\r\n const promise = this.media.play();\r\n\r\n window.scrollTo(scrollX, scrollY);\r\n\r\n if (promise !== undefined) {\r\n promise.catch(error => {\r\n this.player.log('Play failed:', error, 'warn');\r\n });\r\n }\r\n }\r\n\r\n pause() {\r\n this.media.pause();\r\n }\r\n\r\n seek(time: number) {\r\n this.media.currentTime = time;\r\n }\r\n\r\n setVolume(volume: number) {\r\n this.media.volume = volume;\r\n }\r\n\r\n setMuted(muted: boolean) {\r\n this.media.muted = muted;\r\n }\r\n\r\n setPlaybackSpeed(speed: number) {\r\n this.media.playbackRate = speed;\r\n }\r\n\r\n switchQuality(qualityIndex: number) {\r\n if (!this.dash) return;\r\n\r\n if (qualityIndex === -1) {\r\n // Re-enable ABR auto-switching\r\n if (typeof this.dash.setAutoSwitchQualityFor === 'function') {\r\n this.dash.setAutoSwitchQualityFor('video', true);\r\n } else {\r\n this.dash.updateSettings({\r\n streaming: { abr: { autoSwitchBitrate: { video: true } } }\r\n });\r\n }\r\n } else {\r\n // Disable ABR and lock to the chosen quality\r\n if (typeof this.dash.setAutoSwitchQualityFor === 'function') {\r\n this.dash.setAutoSwitchQualityFor('video', false);\r\n } else {\r\n this.dash.updateSettings({\r\n streaming: { abr: { autoSwitchBitrate: { video: false } } }\r\n });\r\n }\r\n\r\n if (typeof this.dash.setRepresentationForTypeByIndex === 'function') {\r\n this.dash.setRepresentationForTypeByIndex('video', qualityIndex);\r\n } else if (typeof this.dash.setQualityFor === 'function') {\r\n this.dash.setQualityFor('video', qualityIndex, true);\r\n }\r\n }\r\n }\r\n\r\n getQualities() {\r\n if (!this.dash) return [];\r\n\r\n try {\r\n // dash.js v5+: getRepresentationsByType\r\n let reps = null;\r\n if (typeof this.dash.getRepresentationsByType === 'function') {\r\n reps = this.dash.getRepresentationsByType('video');\r\n }\r\n\r\n if (reps && reps.length > 0) {\r\n const heightCounts: Record<number, number> = {};\r\n reps.forEach((r: any) => {\r\n const h = Number(r.height) || 0;\r\n heightCounts[h] = (heightCounts[h] || 0) + 1;\r\n });\r\n\r\n return reps.map((rep: any, index: number) => {\r\n const height = Number(rep.height) || 0;\r\n const bitrate = Number(rep.bandwidth || rep.bitrate) || 0;\r\n const kb = bitrate > 0 ? Math.round(bitrate / 1000) : 0;\r\n let name;\r\n if (height > 0 && heightCounts[height] > 1 && kb > 0) {\r\n name = `${height}p (${kb} kbps)`;\r\n } else if (height > 0) {\r\n name = `${height}p`;\r\n } else {\r\n name = kb > 0 ? `${kb} kbps` : 'Auto';\r\n }\r\n return {\r\n index,\r\n id: rep.id,\r\n height: rep.height,\r\n width: rep.width,\r\n bitrate,\r\n name\r\n };\r\n });\r\n }\r\n\r\n // Fallback: dash.js v4 and earlier\r\n const bitrateList = this.dash.getBitrateInfoListFor('video');\r\n if (!bitrateList || bitrateList.length === 0) return [];\r\n\r\n const heightCounts: Record<number, number> = {};\r\n bitrateList.forEach((info: any) => {\r\n const h = Number(info.height) || 0;\r\n heightCounts[h] = (heightCounts[h] || 0) + 1;\r\n });\r\n\r\n return bitrateList.map((info: any, index: number) => {\r\n const height = Number(info.height) || 0;\r\n const bitrate = Number(info.bitrate) || 0;\r\n const kb = bitrate > 0 ? Math.round(bitrate / 1000) : 0;\r\n let name;\r\n if (height > 0 && heightCounts[height] > 1 && kb > 0) {\r\n name = `${height}p (${kb} kbps)`;\r\n } else if (height > 0) {\r\n name = `${height}p`;\r\n } else {\r\n name = kb > 0 ? `${kb} kbps` : 'Auto';\r\n }\r\n return {\r\n index,\r\n height: info.height,\r\n width: info.width,\r\n bitrate: info.bitrate,\r\n name\r\n };\r\n });\r\n } catch (e) {\r\n return [];\r\n }\r\n }\r\n\r\n getCurrentQuality() {\r\n if (!this.dash) return -1;\r\n try {\r\n if (typeof this.dash.getRepresentationsByType === 'function') {\r\n const reps = this.dash.getRepresentationsByType('video');\r\n const current = this.dash.getCurrentRepresentationForType?.('video');\r\n if (current && reps) {\r\n const idx = reps.findIndex((r: any) => r.id === current.id);\r\n if (idx >= 0) return idx;\r\n }\r\n }\r\n return this.dash.getQualityFor('video');\r\n } catch (e) {\r\n return -1;\r\n }\r\n }\r\n\r\n handlesOwnCaptions() {\r\n return this._dashTextIsTtml;\r\n }\r\n\r\n supportsAutoQuality() {\r\n return true;\r\n }\r\n\r\n isAutoQuality() {\r\n if (!this.dash) return true;\r\n try {\r\n if (typeof this.dash.getAutoSwitchQualityFor === 'function') {\r\n return this.dash.getAutoSwitchQualityFor('video');\r\n }\r\n const settings = this.dash.getSettings();\r\n return settings?.streaming?.abr?.autoSwitchBitrate?.video !== false;\r\n } catch (e) {\r\n return true;\r\n }\r\n }\r\n\r\n destroy() {\r\n this._pendingTimeouts.forEach(id => clearTimeout(id));\r\n this._pendingTimeouts = [];\r\n this._stopCueUpdatePolling();\r\n this._lastKnownCueCount = 0;\r\n\r\n if (this._captionEnabledHandler) {\r\n this.player.off('captionsenabled', this._captionEnabledHandler);\r\n this._captionEnabledHandler = null;\r\n }\r\n if (this._captionDisabledHandler) {\r\n this.player.off('captionsdisabled', this._captionDisabledHandler);\r\n this._captionDisabledHandler = null;\r\n }\r\n\r\n if (this._ttmlDiv && this._ttmlDiv.parentNode) {\r\n this._ttmlDiv.parentNode.removeChild(this._ttmlDiv);\r\n this._ttmlDiv = null;\r\n }\r\n\r\n // Mark all subtitle/caption text tracks as stale. dash.js creates\r\n // programmatic TextTrack objects that persist on the <video> element\r\n // after destroy() and cannot be removed via standard APIs. The stale\r\n // flag prevents _checkSubtitleTracks() in a new renderer instance from\r\n // treating them as tracks belonging to the current stream.\r\n const textTracks = this.media.textTracks;\r\n for (let i = 0; i < textTracks.length; i++) {\r\n const track = textTracks[i];\r\n if (track.kind === 'subtitles' || track.kind === 'captions') {\r\n track._vidplyStale = true;\r\n track.mode = 'disabled';\r\n }\r\n }\r\n\r\n if (this.dash) {\r\n try {\r\n // Silence dash.js logging during teardown to suppress harmless\r\n // SourceBuffer errors from in-flight async operations.\r\n this.dash.updateSettings({ debug: { logLevel: 0 } });\r\n // reset() cleanly detaches from MediaSource and cancels pending\r\n // buffer operations before destroy() releases all resources.\r\n this.dash.reset();\r\n } catch (e) { /* ignore teardown errors */ }\r\n try {\r\n this.dash.destroy();\r\n } catch (e) { /* ignore teardown errors */ }\r\n this.dash = null;\r\n }\r\n this._dashTextTracks = [];\r\n this._dashTextIsTtml = false;\r\n }\r\n}\r\n"],
5
+ "mappings": "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",
6
+ "names": ["heightCounts"]
7
+ }
@@ -9,6 +9,12 @@ var HLSRenderer = class {
9
9
  player;
10
10
  media;
11
11
  hls;
12
+ // True once hls.js is driving playback via MSE. Native HLS playback on
13
+ // iOS / iPadOS keeps a real HTTP URL on the <video> and does not need the
14
+ // streaming path to be forced.
15
+ get isStreaming() {
16
+ return this.hls !== null && this.hls !== void 0;
17
+ }
12
18
  _hlsSourceLoaded;
13
19
  _pendingSrc;
14
20
  _hlsSubtitleTracksCount;
@@ -516,4 +522,4 @@ var HLSRenderer = class {
516
522
  export {
517
523
  HLSRenderer
518
524
  };
519
- //# sourceMappingURL=vidply.HLSRenderer-IVT5CQQ4.js.map
525
+ //# sourceMappingURL=vidply.HLSRenderer-7XRBH6P3.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/renderers/HLSRenderer.ts"],
4
+ "sourcesContent": ["import type { Renderer } from '../types/renderer.js';\r\nimport type { Player } from '../core/Player.js';\r\n\r\nexport class HLSRenderer implements Renderer {\r\n player: Player;\r\n media: HTMLMediaElement;\r\n hls: any;\r\n\r\n // True once hls.js is driving playback via MSE. Native HLS playback on\r\n // iOS / iPadOS keeps a real HTTP URL on the <video> and does not need the\r\n // streaming path to be forced.\r\n get isStreaming(): boolean {\r\n return this.hls !== null && this.hls !== undefined;\r\n }\r\n\r\n _hlsSourceLoaded: boolean;\r\n _pendingSrc: string | null;\r\n _hlsSubtitleTracksCount: number | undefined;\r\n _cueUpdateTimer: ReturnType<typeof setInterval> | null;\r\n _lastKnownCueCount: number;\r\n _nativeTrackListenersDestroyed?: boolean;\r\n _didDeferredLoad?: boolean;\r\n _cleanupNativeTextTrackListeners: () => void;\r\n\r\n constructor(player: Player) {\r\n this.player = player;\r\n this.media = player.element;\r\n this.hls = null;\r\n this._hlsSourceLoaded = false;\r\n this._pendingSrc = null;\r\n this._hlsSubtitleTracksCount = undefined;\r\n this._cueUpdateTimer = null;\r\n this._lastKnownCueCount = 0;\r\n this._cleanupNativeTextTrackListeners = () => {};\r\n }\r\n\r\n async init() {\r\n // Check if browser natively supports HLS (Safari)\r\n if (this.canPlayNatively()) {\r\n this.player.log('Using native HLS support');\r\n await this.initNative();\r\n } else {\r\n this.player.log('Using hls.js for HLS support');\r\n await this.initHlsJs();\r\n }\r\n }\r\n\r\n canPlayNatively() {\r\n // Use native HLS only on iOS/iPadOS (MSE unavailable); desktop macOS Safari uses hls.js\r\n // for quality switching and parity with Chrome/Firefox.\r\n const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;\r\n // iPad in desktop mode reports MacIntel but has touch\r\n const isIPadDesktopMode = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;\r\n\r\n if (!isIOS && !isIPadDesktopMode) {\r\n return false;\r\n }\r\n\r\n const video = document.createElement('video');\r\n return video.canPlayType('application/vnd.apple.mpegurl') !== '';\r\n }\r\n\r\n async initNative() {\r\n // Use HTML5 renderer for native HLS support\r\n const HTML5Renderer = (await import('./HTML5Renderer.js')).HTML5Renderer;\r\n const renderer = new HTML5Renderer(this.player);\r\n await renderer.init();\r\n\r\n // Copy methods from HTML5Renderer onto this instance\r\n Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach((method: string) => {\r\n if (method !== 'constructor' && typeof (renderer as any)[method] === 'function') {\r\n (this as any)[method] = (renderer as any)[method].bind(renderer);\r\n }\r\n });\r\n\r\n this._attachNativeTextTrackListeners();\r\n\r\n // The method-copy above shadows HLSRenderer.prototype.destroy with\r\n // HTML5Renderer's destroy. Wrap it so our listeners are also cleaned up.\r\n const html5Destroy = this.destroy;\r\n this.destroy = () => {\r\n this._cleanupNativeTextTrackListeners();\r\n html5Destroy();\r\n };\r\n }\r\n\r\n /**\r\n * Listen for HLS-exposed text tracks so captions/transcript buttons appear on native HLS.\r\n * Debounces rapid addtrack bursts (one per subtitle rendition in the manifest).\r\n */\r\n _attachNativeTextTrackListeners() {\r\n let debounceTimer: ReturnType<typeof setTimeout> | undefined;\r\n\r\n const checkTracks = () => {\r\n clearTimeout(debounceTimer);\r\n debounceTimer = setTimeout(() => {\r\n if (this._nativeTrackListenersDestroyed) return;\r\n const tracks = this.media.textTracks;\r\n let count = 0;\r\n for (let i = 0; i < tracks.length; i++) {\r\n const k = tracks[i].kind;\r\n if (k === 'subtitles' || k === 'captions') {\r\n count++;\r\n }\r\n }\r\n this._hlsSubtitleTracksCount = count;\r\n this.updateCaptionButtonsForHls();\r\n }, 150);\r\n };\r\n\r\n this.media.textTracks.addEventListener('addtrack', checkTracks);\r\n this.media.textTracks.addEventListener('removetrack', checkTracks);\r\n this.media.addEventListener('loadedmetadata', checkTracks);\r\n\r\n this._cleanupNativeTextTrackListeners = () => {\r\n this._nativeTrackListenersDestroyed = true;\r\n clearTimeout(debounceTimer);\r\n this.media.textTracks.removeEventListener('addtrack', checkTracks);\r\n this.media.textTracks.removeEventListener('removetrack', checkTracks);\r\n this.media.removeEventListener('loadedmetadata', checkTracks);\r\n };\r\n }\r\n\r\n async initHlsJs() {\r\n // Hide native controls\r\n this.media.controls = false;\r\n this.media.removeAttribute('controls');\r\n \r\n // Load hls.js if not already loaded\r\n if (!window.Hls) {\r\n await this.loadHlsJs();\r\n }\r\n\r\n if (!window.Hls?.isSupported()) {\r\n throw new Error('HLS is not supported in this browser');\r\n }\r\n const HlsCtor = window.Hls!;\r\n\r\n // HTML5 spec: If video has src attribute, <source> children are not allowed.\r\n // hls.js sets a blob: URL on the src attribute, so we must remove any <source> elements\r\n // to maintain valid HTML. Store the original source URL first.\r\n const sourceElements = Array.from(this.media.querySelectorAll('source'));\r\n let originalSrc = null;\r\n if (sourceElements.length > 0) {\r\n originalSrc = sourceElements[0].getAttribute('src');\r\n sourceElements.forEach(source => source.remove());\r\n this.player.log('Removed <source> elements for HTML5 validity (hls.js uses src attribute)');\r\n }\r\n\r\n // Create hls.js instance with better error recovery\r\n this.hls = new HlsCtor({\r\n debug: this.player.options.debug,\r\n // When deferLoad is enabled, do not start loading until the first play().\r\n autoStartLoad: !this.player.options.deferLoad,\r\n enableWorker: true,\r\n lowLatencyMode: false,\r\n backBufferLength: 90,\r\n maxBufferLength: 30,\r\n maxMaxBufferLength: 600,\r\n maxBufferSize: 60 * 1000 * 1000,\r\n maxBufferHole: 0.5,\r\n // Network retry settings\r\n manifestLoadingTimeOut: 10000,\r\n manifestLoadingMaxRetry: 4,\r\n manifestLoadingRetryDelay: 1000,\r\n manifestLoadingMaxRetryTimeout: 64000,\r\n levelLoadingTimeOut: 10000,\r\n levelLoadingMaxRetry: 4,\r\n levelLoadingRetryDelay: 1000,\r\n levelLoadingMaxRetryTimeout: 64000,\r\n fragLoadingTimeOut: 20000,\r\n fragLoadingMaxRetry: 6,\r\n fragLoadingRetryDelay: 1000,\r\n fragLoadingMaxRetryTimeout: 64000\r\n });\r\n\r\n // Attach media element\r\n this.hls.attachMedia(this.media);\r\n\r\n // Load source - use currentSource for external renderers, or get from attribute\r\n // Priority: currentSource > originalSrc (from removed <source>) > data-vidply-src > src attribute\r\n let src = this.player.currentSource;\r\n \r\n if (!src && originalSrc) {\r\n src = originalSrc;\r\n }\r\n \r\n if (!src) {\r\n // Try data-vidply-src attribute (used by TYPO3 integration)\r\n src = this.player.element.getAttribute('data-vidply-src');\r\n }\r\n \r\n if (!src) {\r\n // Fallback to element's src attribute (but not blob: URLs)\r\n const elementSrc = this.player.element.getAttribute('src') || this.player.element.src;\r\n if (elementSrc && !elementSrc.startsWith('blob:')) {\r\n src = elementSrc;\r\n }\r\n }\r\n \r\n this.player.log(`Loading HLS source: ${src}`, 'log');\r\n \r\n if (!src) {\r\n throw new Error('No HLS source found');\r\n }\r\n \r\n if (this.player.options.deferLoad) {\r\n // Defer manifest/segment loading until first play()\r\n this._pendingSrc = src;\r\n } else {\r\n this.hls.loadSource(src);\r\n this._hlsSourceLoaded = true;\r\n }\r\n\r\n // Attach events\r\n this.attachHlsEvents();\r\n this.attachMediaEvents();\r\n }\r\n\r\n async loadHlsJs() {\r\n return new Promise<void>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error('Failed to load hls.js'));\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n attachHlsEvents() {\r\n this.hls.on(window.Hls!.Events.MANIFEST_PARSED, (_event: any, data: any) => {\r\n this.player.log('HLS manifest loaded, found ' + data.levels.length + ' quality levels');\r\n this.player.emit('hlsmanifestparsed', data);\r\n \r\n // Show VidPly controls (remove external controls class if present)\r\n if (this.player.container) {\r\n this.player.container.classList.remove('vidply-external-controls');\r\n }\r\n \r\n // Check for subtitle tracks after manifest parse\r\n // This handles streams without subtitles (SUBTITLE_TRACKS_UPDATED won't fire for them)\r\n setTimeout(() => {\r\n if (this._hlsSubtitleTracksCount === undefined || this._hlsSubtitleTracksCount === 0) {\r\n const currentCount = this.hls?.subtitleTracks?.length || 0;\r\n if (currentCount === 0) {\r\n this._hlsSubtitleTracksCount = 0;\r\n this.updateCaptionButtonsForHls();\r\n }\r\n }\r\n }, 500);\r\n });\r\n\r\n this.hls.on(window.Hls!.Events.LEVEL_SWITCHED, (_event: any, data: any) => {\r\n this.player.log('HLS level switched to ' + data.level);\r\n this.player.emit('hlslevelswitched', data);\r\n });\r\n\r\n // Handle HLS subtitle tracks\r\n this.hls.on(window.Hls!.Events.SUBTITLE_TRACKS_UPDATED, (_event: any, data: any) => {\r\n this.player.log('HLS subtitle tracks updated, found ' + data.subtitleTracks.length + ' tracks');\r\n this.player.emit('hlssubtitletracksupdated', data);\r\n this._hlsSubtitleTracksCount = data.subtitleTracks.length;\r\n this.updateCaptionButtonsForHls();\r\n if (data.subtitleTracks.length > 0) {\r\n this._startCueUpdatePolling();\r\n }\r\n });\r\n\r\n this.hls.on(window.Hls!.Events.SUBTITLE_TRACK_SWITCH, (_event: any, data: any) => {\r\n this.player.log('HLS subtitle track switched to ' + data.id);\r\n this.player.emit('hlssubtitletrackswitch', data);\r\n this._lastKnownCueCount = 0;\r\n this._startCueUpdatePolling();\r\n });\r\n\r\n this.hls.on(window.Hls!.Events.ERROR, (_event: any, data: any) => {\r\n this.handleHlsError(data);\r\n });\r\n\r\n this.hls.on(window.Hls!.Events.FRAG_BUFFERED, (_event: any, _data: any) => {\r\n this.player.state.buffering = false;\r\n });\r\n\r\n // Subtitle fragments do NOT go through the media source buffer, so\r\n // FRAG_BUFFERED is unreliable for them. SUBTITLE_FRAG_PROCESSED fires\r\n // immediately after hls.js has parsed the WebVTT and appended cues to\r\n // the TextTrack via `addCueToTrack`, which is exactly when we need to\r\n // refresh captions/transcript UIs.\r\n this.hls.on(window.Hls!.Events.SUBTITLE_FRAG_PROCESSED, (_event: any, data: any) => {\r\n if (!data || !data.success) return;\r\n const count = this._getTotalCueCount();\r\n if (count > this._lastKnownCueCount) {\r\n this._lastKnownCueCount = count;\r\n this.player.emit('textcuesupdate');\r\n }\r\n });\r\n\r\n // Some streams (e.g. IMSC1/TTML rendered externally by hls.js) deliver\r\n // their cues via CUES_PARSED instead of through a native TextTrack. Echo\r\n // that through to the transcript so it can refresh regardless of the\r\n // underlying subtitle format.\r\n this.hls.on(window.Hls!.Events.CUES_PARSED, (_event: any, _data: any) => {\r\n this.player.emit('textcuesupdate');\r\n });\r\n }\r\n\r\n _getTotalCueCount() {\r\n const textTracks = this.media.textTracks;\r\n let total = 0;\r\n if (!textTracks) return total;\r\n for (let i = 0; i < textTracks.length; i++) {\r\n const track = textTracks[i];\r\n if ((track.kind === 'subtitles' || track.kind === 'captions') && track.cues) {\r\n total += track.cues.length;\r\n }\r\n }\r\n return total;\r\n }\r\n\r\n _startCueUpdatePolling() {\r\n this._stopCueUpdatePolling();\r\n let prevCueCount = 0;\r\n let stableRounds = 0;\r\n\r\n this._cueUpdateTimer = setInterval(() => {\r\n const count = this._getTotalCueCount();\r\n\r\n if (count > prevCueCount) {\r\n prevCueCount = count;\r\n stableRounds = 0;\r\n this.player.emit('textcuesupdate');\r\n } else {\r\n stableRounds++;\r\n if (stableRounds >= 8) {\r\n this._stopCueUpdatePolling();\r\n if (count > 0) {\r\n this.player.emit('textcuesupdate');\r\n }\r\n }\r\n }\r\n }, 500);\r\n }\r\n\r\n _stopCueUpdatePolling() {\r\n if (this._cueUpdateTimer) {\r\n clearInterval(this._cueUpdateTimer);\r\n this._cueUpdateTimer = null;\r\n }\r\n }\r\n\r\n /**\r\n * Update caption buttons based on HLS subtitle tracks\r\n * Handles the case where control bar may not exist yet\r\n */\r\n updateCaptionButtonsForHls() {\r\n const tracksCount = this._hlsSubtitleTracksCount || 0;\r\n \r\n const doUpdate = () => {\r\n this.player.invalidateTrackCache();\r\n \r\n if (tracksCount > 0) {\r\n // HLS has subtitle tracks - refresh managers and add buttons\r\n if (this.player.captionManager) {\r\n this.player.captionManager.refreshTracks();\r\n }\r\n \r\n if (this.player.transcriptManager?.isVisible) {\r\n this.player.transcriptManager.loadTranscriptData();\r\n this.player.transcriptManager.updateLanguageSelector();\r\n }\r\n \r\n if (this.player.controlBar) {\r\n this.player.controlBar.ensureCaptionsButton();\r\n this.player.controlBar.ensureCaptionStyleButton();\r\n this.player.controlBar.ensureTranscriptButton();\r\n }\r\n } else {\r\n // No HLS subtitle tracks - clean up\r\n if (this.player.captionManager) {\r\n this.player.captionManager.refreshTracks();\r\n }\r\n \r\n if (this.player.transcriptManager?.isVisible) {\r\n this.player.transcriptManager.hideTranscript();\r\n }\r\n \r\n if (this.player.controlBar) {\r\n this.player.controlBar.removeHlsCaptionButtons(true);\r\n }\r\n }\r\n };\r\n \r\n if (this.player.controlBar) {\r\n doUpdate();\r\n return;\r\n }\r\n \r\n // Control bar doesn't exist yet - wait for ready event\r\n const onReady = () => {\r\n this.player.off('ready', onReady);\r\n doUpdate();\r\n };\r\n this.player.on('ready', onReady);\r\n }\r\n\r\n attachMediaEvents() {\r\n // Use same events as HTML5 renderer\r\n this.media.addEventListener('loadedmetadata', () => {\r\n this.player.state.duration = this.media.duration;\r\n this.player.emit('loadedmetadata');\r\n });\r\n\r\n this.media.addEventListener('durationchange', () => {\r\n const duration = this.media.duration;\r\n if (duration && isFinite(duration) && duration > 0) {\r\n this.player.state.duration = duration;\r\n this.player.emit('durationchange', duration);\r\n }\r\n });\r\n\r\n this.media.addEventListener('play', () => {\r\n this.player.state.playing = true;\r\n this.player.state.paused = false;\r\n this.player.state.ended = false;\r\n this.player.emit('play');\r\n \r\n if (this.player.options.onPlay) {\r\n this.player.options.onPlay.call(this.player);\r\n }\r\n });\r\n\r\n this.media.addEventListener('pause', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.emit('pause');\r\n \r\n if (this.player.options.onPause) {\r\n this.player.options.onPause.call(this.player);\r\n }\r\n });\r\n\r\n this.media.addEventListener('ended', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.state.ended = true;\r\n this.player.emit('ended');\r\n \r\n if (this.player.options.onEnded) {\r\n this.player.options.onEnded.call(this.player);\r\n }\r\n \r\n if (this.player.options.loop) {\r\n this.player.seek(0);\r\n this.player.play();\r\n }\r\n });\r\n\r\n this.media.addEventListener('timeupdate', () => {\r\n this.player.state.currentTime = this.media.currentTime;\r\n this.player.emit('timeupdate', this.media.currentTime);\r\n \r\n if (this.player.options.onTimeUpdate) {\r\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\r\n }\r\n });\r\n\r\n this.media.addEventListener('volumechange', () => {\r\n this.player.state.volume = this.media.volume;\r\n this.player.state.muted = this.media.muted;\r\n this.player.emit('volumechange', this.media.volume);\r\n });\r\n\r\n this.media.addEventListener('waiting', () => {\r\n this.player.state.buffering = true;\r\n this.player.emit('waiting');\r\n });\r\n\r\n this.media.addEventListener('canplay', () => {\r\n this.player.state.buffering = false;\r\n this.player.emit('canplay');\r\n });\r\n\r\n this.media.addEventListener('error', () => {\r\n this.player.handleError(this.media.error);\r\n });\r\n }\r\n\r\n handleHlsError(data: any) {\r\n // Log detailed error info\r\n this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, 'warn');\r\n if (data.response) {\r\n this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, 'warn');\r\n }\r\n \r\n if (data.fatal) {\r\n switch (data.type) {\r\n case window.Hls!.ErrorTypes.NETWORK_ERROR:\r\n this.player.log('Fatal network error, trying to recover...', 'error');\r\n this.player.log(`Network error details: ${data.details}`, 'error');\r\n setTimeout(() => {\r\n this.hls.startLoad();\r\n }, 1000);\r\n break;\r\n \r\n case window.Hls!.ErrorTypes.MEDIA_ERROR:\r\n this.player.log('Fatal media error, trying to recover...', 'error');\r\n this.hls.recoverMediaError();\r\n break;\r\n \r\n default:\r\n this.player.log('Fatal error, cannot recover', 'error');\r\n this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));\r\n this.hls.destroy();\r\n break;\r\n }\r\n } else {\r\n this.player.log('Non-fatal HLS error: ' + data.details, 'warn');\r\n }\r\n }\r\n\r\n /**\r\n * Ensure the HLS manifest/initial loading is started without starting playback.\r\n * This makes playlist selection behave more like single-video initialization.\r\n */\r\n ensureLoaded() {\r\n if (!this.player.options.deferLoad) {\r\n return;\r\n }\r\n\r\n // Native HLS path delegates to HTML5Renderer; if we got here and have no hls.js instance,\r\n // there's nothing to do.\r\n if (!this.hls) {\r\n return;\r\n }\r\n\r\n if (this._hlsSourceLoaded) {\r\n return;\r\n }\r\n\r\n const src = this._pendingSrc || this.player._pendingSource || this.player.currentSource;\r\n if (!src) {\r\n return;\r\n }\r\n\r\n try {\r\n this.hls.loadSource(src);\r\n this._hlsSourceLoaded = true;\r\n // Start loading so manifest is parsed and levels/tracks become available.\r\n // Note: this may fetch initial fragments depending on stream/config.\r\n this.hls.startLoad();\r\n } catch (e) {\r\n // ignore\r\n }\r\n }\r\n\r\n play() {\r\n // Save scroll position to prevent browser from scrolling to video\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n\r\n // If deferLoad is enabled, start HLS loading only on the first user play request.\r\n if (this.player.options.deferLoad && this.hls && !this._hlsSourceLoaded) {\r\n const src = this._pendingSrc || this.player.currentSource;\r\n if (src) {\r\n try {\r\n this.hls.loadSource(src);\r\n this.hls.startLoad();\r\n this._hlsSourceLoaded = true;\r\n } catch (e) {\r\n // ignore and let media.play() surface errors if any\r\n }\r\n }\r\n }\r\n \r\n const promise = this.media.play();\r\n \r\n // Restore scroll position immediately to prevent auto-scroll\r\n window.scrollTo(scrollX, scrollY);\r\n \r\n if (promise !== undefined) {\r\n promise.catch(error => {\r\n this.player.log('Play failed:', error, 'warn');\r\n });\r\n }\r\n }\r\n\r\n pause() {\r\n this.media.pause();\r\n }\r\n\r\n seek(time: number) {\r\n this.media.currentTime = time;\r\n }\r\n\r\n setVolume(volume: number) {\r\n this.media.volume = volume;\r\n }\r\n\r\n setMuted(muted: boolean) {\r\n this.media.muted = muted;\r\n }\r\n\r\n setPlaybackSpeed(speed: number) {\r\n this.media.playbackRate = speed;\r\n }\r\n\r\n switchQuality(levelIndex: number) {\r\n if (this.hls) {\r\n this.hls.currentLevel = levelIndex;\r\n }\r\n }\r\n\r\n getQualities() {\r\n if (this.hls && this.hls.levels) {\r\n // hls.js creates separate levels for each video+audio-group combination,\r\n // producing duplicates (e.g. three \"720p\" entries). Deduplicate by\r\n // resolution height, keeping the entry with the highest bitrate per height.\r\n const byHeight = new Map();\r\n\r\n this.hls.levels.forEach((level: any, index: number) => {\r\n const height = Number(level.height) || 0;\r\n const bitrate = Number(level.bitrate) || 0;\r\n const key = height > 0 ? height : `br_${bitrate}`;\r\n const existing = byHeight.get(key);\r\n\r\n if (!existing || bitrate > (existing.bitrate || 0)) {\r\n byHeight.set(key, { index, height: level.height, width: level.width, bitrate, level });\r\n }\r\n });\r\n\r\n return Array.from(byHeight.values()).map((entry: any) => {\r\n const height = Number(entry.height) || 0;\r\n const kb = entry.bitrate > 0 ? Math.round(entry.bitrate / 1000) : 0;\r\n const name = height > 0 ? `${height}p` : (kb > 0 ? `${kb} kb` : 'Auto');\r\n return { index: entry.index, height: entry.height, width: entry.width, bitrate: entry.bitrate, name };\r\n });\r\n }\r\n return [];\r\n }\r\n\r\n getCurrentQuality() {\r\n if (this.hls) {\r\n return this.hls.currentLevel;\r\n }\r\n return -1;\r\n }\r\n\r\n supportsAutoQuality() {\r\n return true;\r\n }\r\n\r\n isAutoQuality() {\r\n return this.hls?.currentLevel === -1;\r\n }\r\n\r\n destroy() {\r\n this._stopCueUpdatePolling();\r\n this._lastKnownCueCount = 0;\r\n if (this.hls) {\r\n this.hls.destroy();\r\n this.hls = null;\r\n }\r\n }\r\n}\r\n\r\n"],
5
+ "mappings": ";;;;;;;AAGO,IAAM,cAAN,MAAsC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAuB;AACzB,WAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ;AAAA,EAC3C;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAgB;AAC1B,SAAK,SAAS;AACd,SAAK,QAAQ,OAAO;AACpB,SAAK,MAAM;AACX,SAAK,mBAAmB;AACxB,SAAK,cAAc;AACnB,SAAK,0BAA0B;AAC/B,SAAK,kBAAkB;AACvB,SAAK,qBAAqB;AAC1B,SAAK,mCAAmC,MAAM;AAAA,IAAC;AAAA,EACjD;AAAA,EAEA,MAAM,OAAO;AAEX,QAAI,KAAK,gBAAgB,GAAG;AAC1B,WAAK,OAAO,IAAI,0BAA0B;AAC1C,YAAM,KAAK,WAAW;AAAA,IACxB,OAAO;AACL,WAAK,OAAO,IAAI,8BAA8B;AAC9C,YAAM,KAAK,UAAU;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,kBAAkB;AAGhB,UAAM,QAAQ,mBAAmB,KAAK,UAAU,SAAS,KAAK,CAAC,OAAO;AAEtE,UAAM,oBAAoB,UAAU,aAAa,cAAc,UAAU,iBAAiB;AAE1F,QAAI,CAAC,SAAS,CAAC,mBAAmB;AAChC,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,WAAO,MAAM,YAAY,+BAA+B,MAAM;AAAA,EAChE;AAAA,EAEA,MAAM,aAAa;AAEjB,UAAM,iBAAiB,MAAM,OAAO,oCAAoB,GAAG;AAC3D,UAAM,WAAW,IAAI,cAAc,KAAK,MAAM;AAC9C,UAAM,SAAS,KAAK;AAGpB,WAAO,oBAAoB,OAAO,eAAe,QAAQ,CAAC,EAAE,QAAQ,CAAC,WAAmB;AACtF,UAAI,WAAW,iBAAiB,OAAQ,SAAiB,MAAM,MAAM,YAAY;AAC/E,QAAC,KAAa,MAAM,IAAK,SAAiB,MAAM,EAAE,KAAK,QAAQ;AAAA,MACjE;AAAA,IACF,CAAC;AAED,SAAK,gCAAgC;AAIrC,UAAM,eAAe,KAAK;AAC1B,SAAK,UAAU,MAAM;AACnB,WAAK,iCAAiC;AACtC,mBAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kCAAkC;AAChC,QAAI;AAEJ,UAAM,cAAc,MAAM;AACxB,mBAAa,aAAa;AAC1B,sBAAgB,WAAW,MAAM;AAC/B,YAAI,KAAK,+BAAgC;AACzC,cAAM,SAAS,KAAK,MAAM;AAC1B,YAAI,QAAQ;AACZ,iBAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,gBAAM,IAAI,OAAO,CAAC,EAAE;AACpB,cAAI,MAAM,eAAe,MAAM,YAAY;AACzC;AAAA,UACF;AAAA,QACF;AACA,aAAK,0BAA0B;AAC/B,aAAK,2BAA2B;AAAA,MAClC,GAAG,GAAG;AAAA,IACR;AAEA,SAAK,MAAM,WAAW,iBAAiB,YAAY,WAAW;AAC9D,SAAK,MAAM,WAAW,iBAAiB,eAAe,WAAW;AACjE,SAAK,MAAM,iBAAiB,kBAAkB,WAAW;AAEzD,SAAK,mCAAmC,MAAM;AAC5C,WAAK,iCAAiC;AACtC,mBAAa,aAAa;AAC1B,WAAK,MAAM,WAAW,oBAAoB,YAAY,WAAW;AACjE,WAAK,MAAM,WAAW,oBAAoB,eAAe,WAAW;AACpE,WAAK,MAAM,oBAAoB,kBAAkB,WAAW;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,MAAM,YAAY;AAEhB,SAAK,MAAM,WAAW;AACtB,SAAK,MAAM,gBAAgB,UAAU;AAGrC,QAAI,CAAC,OAAO,KAAK;AACf,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,QAAI,CAAC,OAAO,KAAK,YAAY,GAAG;AAC9B,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,UAAM,UAAU,OAAO;AAKvB,UAAM,iBAAiB,MAAM,KAAK,KAAK,MAAM,iBAAiB,QAAQ,CAAC;AACvE,QAAI,cAAc;AAClB,QAAI,eAAe,SAAS,GAAG;AAC7B,oBAAc,eAAe,CAAC,EAAE,aAAa,KAAK;AAClD,qBAAe,QAAQ,YAAU,OAAO,OAAO,CAAC;AAChD,WAAK,OAAO,IAAI,0EAA0E;AAAA,IAC5F;AAGA,SAAK,MAAM,IAAI,QAAQ;AAAA,MACrB,OAAO,KAAK,OAAO,QAAQ;AAAA;AAAA,MAE3B,eAAe,CAAC,KAAK,OAAO,QAAQ;AAAA,MACpC,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,eAAe,KAAK,MAAO;AAAA,MAC3B,eAAe;AAAA;AAAA,MAEf,wBAAwB;AAAA,MACxB,yBAAyB;AAAA,MACzB,2BAA2B;AAAA,MAC3B,gCAAgC;AAAA,MAChC,qBAAqB;AAAA,MACrB,sBAAsB;AAAA,MACtB,wBAAwB;AAAA,MACxB,6BAA6B;AAAA,MAC7B,oBAAoB;AAAA,MACpB,qBAAqB;AAAA,MACrB,uBAAuB;AAAA,MACvB,4BAA4B;AAAA,IAC9B,CAAC;AAGD,SAAK,IAAI,YAAY,KAAK,KAAK;AAI/B,QAAI,MAAM,KAAK,OAAO;AAEtB,QAAI,CAAC,OAAO,aAAa;AACvB,YAAM;AAAA,IACR;AAEA,QAAI,CAAC,KAAK;AAER,YAAM,KAAK,OAAO,QAAQ,aAAa,iBAAiB;AAAA,IAC1D;AAEA,QAAI,CAAC,KAAK;AAER,YAAM,aAAa,KAAK,OAAO,QAAQ,aAAa,KAAK,KAAK,KAAK,OAAO,QAAQ;AAClF,UAAI,cAAc,CAAC,WAAW,WAAW,OAAO,GAAG;AACjD,cAAM;AAAA,MACR;AAAA,IACF;AAEA,SAAK,OAAO,IAAI,uBAAuB,GAAG,IAAI,KAAK;AAEnD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAEA,QAAI,KAAK,OAAO,QAAQ,WAAW;AAEjC,WAAK,cAAc;AAAA,IACrB,OAAO;AACL,WAAK,IAAI,WAAW,GAAG;AACvB,WAAK,mBAAmB;AAAA,IAC1B;AAGA,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,MAAM,YAAY;AAChB,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM;AACb,aAAO,SAAS,MAAM,QAAQ;AAC9B,aAAO,UAAU,MAAM,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAChE,eAAS,KAAK,YAAY,MAAM;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB;AAChB,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,iBAAiB,CAAC,QAAa,SAAc;AAC1E,WAAK,OAAO,IAAI,gCAAgC,KAAK,OAAO,SAAS,iBAAiB;AACtF,WAAK,OAAO,KAAK,qBAAqB,IAAI;AAG1C,UAAI,KAAK,OAAO,WAAW;AACzB,aAAK,OAAO,UAAU,UAAU,OAAO,0BAA0B;AAAA,MACnE;AAIA,iBAAW,MAAM;AACf,YAAI,KAAK,4BAA4B,UAAa,KAAK,4BAA4B,GAAG;AACpF,gBAAM,eAAe,KAAK,KAAK,gBAAgB,UAAU;AACzD,cAAI,iBAAiB,GAAG;AACtB,iBAAK,0BAA0B;AAC/B,iBAAK,2BAA2B;AAAA,UAClC;AAAA,QACF;AAAA,MACF,GAAG,GAAG;AAAA,IACR,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,gBAAgB,CAAC,QAAa,SAAc;AACzE,WAAK,OAAO,IAAI,2BAA2B,KAAK,KAAK;AACrD,WAAK,OAAO,KAAK,oBAAoB,IAAI;AAAA,IAC3C,CAAC;AAGD,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,yBAAyB,CAAC,QAAa,SAAc;AAClF,WAAK,OAAO,IAAI,wCAAwC,KAAK,eAAe,SAAS,SAAS;AAC9F,WAAK,OAAO,KAAK,4BAA4B,IAAI;AACjD,WAAK,0BAA0B,KAAK,eAAe;AACnD,WAAK,2BAA2B;AAChC,UAAI,KAAK,eAAe,SAAS,GAAG;AAClC,aAAK,uBAAuB;AAAA,MAC9B;AAAA,IACF,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,uBAAuB,CAAC,QAAa,SAAc;AAChF,WAAK,OAAO,IAAI,oCAAoC,KAAK,EAAE;AAC3D,WAAK,OAAO,KAAK,0BAA0B,IAAI;AAC/C,WAAK,qBAAqB;AAC1B,WAAK,uBAAuB;AAAA,IAC9B,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,OAAO,CAAC,QAAa,SAAc;AAChE,WAAK,eAAe,IAAI;AAAA,IAC1B,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,eAAe,CAAC,QAAa,UAAe;AACzE,WAAK,OAAO,MAAM,YAAY;AAAA,IAChC,CAAC;AAOD,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,yBAAyB,CAAC,QAAa,SAAc;AAClF,UAAI,CAAC,QAAQ,CAAC,KAAK,QAAS;AAC5B,YAAM,QAAQ,KAAK,kBAAkB;AACrC,UAAI,QAAQ,KAAK,oBAAoB;AACnC,aAAK,qBAAqB;AAC1B,aAAK,OAAO,KAAK,gBAAgB;AAAA,MACnC;AAAA,IACF,CAAC;AAMD,SAAK,IAAI,GAAG,OAAO,IAAK,OAAO,aAAa,CAAC,QAAa,UAAe;AACvE,WAAK,OAAO,KAAK,gBAAgB;AAAA,IACnC,CAAC;AAAA,EACH;AAAA,EAEA,oBAAoB;AAClB,UAAM,aAAa,KAAK,MAAM;AAC9B,QAAI,QAAQ;AACZ,QAAI,CAAC,WAAY,QAAO;AACxB,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,YAAM,QAAQ,WAAW,CAAC;AAC1B,WAAK,MAAM,SAAS,eAAe,MAAM,SAAS,eAAe,MAAM,MAAM;AAC3E,iBAAS,MAAM,KAAK;AAAA,MACtB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,yBAAyB;AACvB,SAAK,sBAAsB;AAC3B,QAAI,eAAe;AACnB,QAAI,eAAe;AAEnB,SAAK,kBAAkB,YAAY,MAAM;AACvC,YAAM,QAAQ,KAAK,kBAAkB;AAErC,UAAI,QAAQ,cAAc;AACxB,uBAAe;AACf,uBAAe;AACf,aAAK,OAAO,KAAK,gBAAgB;AAAA,MACnC,OAAO;AACL;AACA,YAAI,gBAAgB,GAAG;AACrB,eAAK,sBAAsB;AAC3B,cAAI,QAAQ,GAAG;AACb,iBAAK,OAAO,KAAK,gBAAgB;AAAA,UACnC;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,GAAG;AAAA,EACR;AAAA,EAEA,wBAAwB;AACtB,QAAI,KAAK,iBAAiB;AACxB,oBAAc,KAAK,eAAe;AAClC,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,6BAA6B;AAC3B,UAAM,cAAc,KAAK,2BAA2B;AAEpD,UAAM,WAAW,MAAM;AACrB,WAAK,OAAO,qBAAqB;AAEjC,UAAI,cAAc,GAAG;AAEnB,YAAI,KAAK,OAAO,gBAAgB;AAC9B,eAAK,OAAO,eAAe,cAAc;AAAA,QAC3C;AAEA,YAAI,KAAK,OAAO,mBAAmB,WAAW;AAC5C,eAAK,OAAO,kBAAkB,mBAAmB;AACjD,eAAK,OAAO,kBAAkB,uBAAuB;AAAA,QACvD;AAEA,YAAI,KAAK,OAAO,YAAY;AAC1B,eAAK,OAAO,WAAW,qBAAqB;AAC5C,eAAK,OAAO,WAAW,yBAAyB;AAChD,eAAK,OAAO,WAAW,uBAAuB;AAAA,QAChD;AAAA,MACF,OAAO;AAEL,YAAI,KAAK,OAAO,gBAAgB;AAC9B,eAAK,OAAO,eAAe,cAAc;AAAA,QAC3C;AAEA,YAAI,KAAK,OAAO,mBAAmB,WAAW;AAC5C,eAAK,OAAO,kBAAkB,eAAe;AAAA,QAC/C;AAEA,YAAI,KAAK,OAAO,YAAY;AAC1B,eAAK,OAAO,WAAW,wBAAwB,IAAI;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,YAAY;AAC1B,eAAS;AACT;AAAA,IACF;AAGA,UAAM,UAAU,MAAM;AACpB,WAAK,OAAO,IAAI,SAAS,OAAO;AAChC,eAAS;AAAA,IACX;AACA,SAAK,OAAO,GAAG,SAAS,OAAO;AAAA,EACjC;AAAA,EAEA,oBAAoB;AAElB,SAAK,MAAM,iBAAiB,kBAAkB,MAAM;AAClD,WAAK,OAAO,MAAM,WAAW,KAAK,MAAM;AACxC,WAAK,OAAO,KAAK,gBAAgB;AAAA,IACnC,CAAC;AAED,SAAK,MAAM,iBAAiB,kBAAkB,MAAM;AAClD,YAAM,WAAW,KAAK,MAAM;AAC5B,UAAI,YAAY,SAAS,QAAQ,KAAK,WAAW,GAAG;AAClD,aAAK,OAAO,MAAM,WAAW;AAC7B,aAAK,OAAO,KAAK,kBAAkB,QAAQ;AAAA,MAC7C;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,QAAQ,MAAM;AACxC,WAAK,OAAO,MAAM,UAAU;AAC5B,WAAK,OAAO,MAAM,SAAS;AAC3B,WAAK,OAAO,MAAM,QAAQ;AAC1B,WAAK,OAAO,KAAK,MAAM;AAEvB,UAAI,KAAK,OAAO,QAAQ,QAAQ;AAC9B,aAAK,OAAO,QAAQ,OAAO,KAAK,KAAK,MAAM;AAAA,MAC7C;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,SAAS,MAAM;AACzC,WAAK,OAAO,MAAM,UAAU;AAC5B,WAAK,OAAO,MAAM,SAAS;AAC3B,WAAK,OAAO,KAAK,OAAO;AAExB,UAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,aAAK,OAAO,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,MAC9C;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,SAAS,MAAM;AACzC,WAAK,OAAO,MAAM,UAAU;AAC5B,WAAK,OAAO,MAAM,SAAS;AAC3B,WAAK,OAAO,MAAM,QAAQ;AAC1B,WAAK,OAAO,KAAK,OAAO;AAExB,UAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,aAAK,OAAO,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,MAC9C;AAEA,UAAI,KAAK,OAAO,QAAQ,MAAM;AAC5B,aAAK,OAAO,KAAK,CAAC;AAClB,aAAK,OAAO,KAAK;AAAA,MACnB;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,cAAc,MAAM;AAC9C,WAAK,OAAO,MAAM,cAAc,KAAK,MAAM;AAC3C,WAAK,OAAO,KAAK,cAAc,KAAK,MAAM,WAAW;AAErD,UAAI,KAAK,OAAO,QAAQ,cAAc;AACpC,aAAK,OAAO,QAAQ,aAAa,KAAK,KAAK,QAAQ,KAAK,MAAM,WAAW;AAAA,MAC3E;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,gBAAgB,MAAM;AAChD,WAAK,OAAO,MAAM,SAAS,KAAK,MAAM;AACtC,WAAK,OAAO,MAAM,QAAQ,KAAK,MAAM;AACrC,WAAK,OAAO,KAAK,gBAAgB,KAAK,MAAM,MAAM;AAAA,IACpD,CAAC;AAED,SAAK,MAAM,iBAAiB,WAAW,MAAM;AAC3C,WAAK,OAAO,MAAM,YAAY;AAC9B,WAAK,OAAO,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,SAAK,MAAM,iBAAiB,WAAW,MAAM;AAC3C,WAAK,OAAO,MAAM,YAAY;AAC9B,WAAK,OAAO,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,SAAK,MAAM,iBAAiB,SAAS,MAAM;AACzC,WAAK,OAAO,YAAY,KAAK,MAAM,KAAK;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,MAAW;AAExB,SAAK,OAAO,IAAI,qBAAqB,KAAK,IAAI,cAAc,KAAK,OAAO,YAAY,KAAK,KAAK,IAAI,MAAM;AACxG,QAAI,KAAK,UAAU;AACjB,WAAK,OAAO,IAAI,kBAAkB,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,GAAG,IAAI,MAAM;AAAA,IAC3F;AAEA,QAAI,KAAK,OAAO;AACd,cAAQ,KAAK,MAAM;AAAA,QACjB,KAAK,OAAO,IAAK,WAAW;AAC1B,eAAK,OAAO,IAAI,6CAA6C,OAAO;AACpE,eAAK,OAAO,IAAI,0BAA0B,KAAK,OAAO,IAAI,OAAO;AACjE,qBAAW,MAAM;AACf,iBAAK,IAAI,UAAU;AAAA,UACrB,GAAG,GAAI;AACP;AAAA,QAEF,KAAK,OAAO,IAAK,WAAW;AAC1B,eAAK,OAAO,IAAI,2CAA2C,OAAO;AAClE,eAAK,IAAI,kBAAkB;AAC3B;AAAA,QAEF;AACE,eAAK,OAAO,IAAI,+BAA+B,OAAO;AACtD,eAAK,OAAO,YAAY,IAAI,MAAM,cAAc,KAAK,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;AAC9E,eAAK,IAAI,QAAQ;AACjB;AAAA,MACJ;AAAA,IACF,OAAO;AACL,WAAK,OAAO,IAAI,0BAA0B,KAAK,SAAS,MAAM;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe;AACb,QAAI,CAAC,KAAK,OAAO,QAAQ,WAAW;AAClC;AAAA,IACF;AAIA,QAAI,CAAC,KAAK,KAAK;AACb;AAAA,IACF;AAEA,QAAI,KAAK,kBAAkB;AACzB;AAAA,IACF;AAEA,UAAM,MAAM,KAAK,eAAe,KAAK,OAAO,kBAAkB,KAAK,OAAO;AAC1E,QAAI,CAAC,KAAK;AACR;AAAA,IACF;AAEA,QAAI;AACF,WAAK,IAAI,WAAW,GAAG;AACvB,WAAK,mBAAmB;AAGxB,WAAK,IAAI,UAAU;AAAA,IACrB,SAAS,GAAG;AAAA,IAEZ;AAAA,EACF;AAAA,EAEA,OAAO;AAEL,UAAM,UAAU,OAAO;AACvB,UAAM,UAAU,OAAO;AAGvB,QAAI,KAAK,OAAO,QAAQ,aAAa,KAAK,OAAO,CAAC,KAAK,kBAAkB;AACvE,YAAM,MAAM,KAAK,eAAe,KAAK,OAAO;AAC5C,UAAI,KAAK;AACP,YAAI;AACF,eAAK,IAAI,WAAW,GAAG;AACvB,eAAK,IAAI,UAAU;AACnB,eAAK,mBAAmB;AAAA,QAC1B,SAAS,GAAG;AAAA,QAEZ;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,MAAM,KAAK;AAGhC,WAAO,SAAS,SAAS,OAAO;AAEhC,QAAI,YAAY,QAAW;AACzB,cAAQ,MAAM,WAAS;AACrB,aAAK,OAAO,IAAI,gBAAgB,OAAO,MAAM;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,QAAQ;AACN,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,KAAK,MAAc;AACjB,SAAK,MAAM,cAAc;AAAA,EAC3B;AAAA,EAEA,UAAU,QAAgB;AACxB,SAAK,MAAM,SAAS;AAAA,EACtB;AAAA,EAEA,SAAS,OAAgB;AACvB,SAAK,MAAM,QAAQ;AAAA,EACrB;AAAA,EAEA,iBAAiB,OAAe;AAC9B,SAAK,MAAM,eAAe;AAAA,EAC5B;AAAA,EAEA,cAAc,YAAoB;AAChC,QAAI,KAAK,KAAK;AACZ,WAAK,IAAI,eAAe;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,eAAe;AACb,QAAI,KAAK,OAAO,KAAK,IAAI,QAAQ;AAI/B,YAAM,WAAW,oBAAI,IAAI;AAEzB,WAAK,IAAI,OAAO,QAAQ,CAAC,OAAY,UAAkB;AACrD,cAAM,SAAS,OAAO,MAAM,MAAM,KAAK;AACvC,cAAM,UAAU,OAAO,MAAM,OAAO,KAAK;AACzC,cAAM,MAAM,SAAS,IAAI,SAAS,MAAM,OAAO;AAC/C,cAAM,WAAW,SAAS,IAAI,GAAG;AAEjC,YAAI,CAAC,YAAY,WAAW,SAAS,WAAW,IAAI;AAClD,mBAAS,IAAI,KAAK,EAAE,OAAO,QAAQ,MAAM,QAAQ,OAAO,MAAM,OAAO,SAAS,MAAM,CAAC;AAAA,QACvF;AAAA,MACF,CAAC;AAED,aAAO,MAAM,KAAK,SAAS,OAAO,CAAC,EAAE,IAAI,CAAC,UAAe;AACvD,cAAM,SAAS,OAAO,MAAM,MAAM,KAAK;AACvC,cAAM,KAAK,MAAM,UAAU,IAAI,KAAK,MAAM,MAAM,UAAU,GAAI,IAAI;AAClE,cAAM,OAAO,SAAS,IAAI,GAAG,MAAM,MAAO,KAAK,IAAI,GAAG,EAAE,QAAQ;AAChE,eAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,OAAO,MAAM,OAAO,SAAS,MAAM,SAAS,KAAK;AAAA,MACtG,CAAC;AAAA,IACH;AACA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,oBAAoB;AAClB,QAAI,KAAK,KAAK;AACZ,aAAO,KAAK,IAAI;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,sBAAsB;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB;AACd,WAAO,KAAK,KAAK,iBAAiB;AAAA,EACpC;AAAA,EAEA,UAAU;AACR,SAAK,sBAAsB;AAC3B,SAAK,qBAAqB;AAC1B,QAAI,KAAK,KAAK;AACZ,WAAK,IAAI,QAAQ;AACjB,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -127,7 +127,7 @@ var CaptionManager = class {
127
127
  const entry = {
128
128
  track,
129
129
  language: track.language,
130
- label: track.label,
130
+ label: this.deriveTrackLabel(track.label, track.language),
131
131
  kind: track.kind,
132
132
  index: i,
133
133
  isDefault,
@@ -146,6 +146,41 @@ var CaptionManager = class {
146
146
  });
147
147
  }
148
148
  }
149
+ /**
150
+ * Derive a human-readable label for a TextTrack when the source manifest
151
+ * (DASH AdaptationSet, HLS rendition, etc.) didn't provide one. dash.js
152
+ * falls back to the AdaptationSet @id (typically a digit like "2", "3")
153
+ * when no <Label> child element is present, which surfaces as cryptic
154
+ * "2"/"3" entries in the captions menu.
155
+ *
156
+ * dash.js 5.x additionally derives the label as `element.id ?? element.lang`.
157
+ * When neither is present in the MPD, the value is JS `null`, and the
158
+ * browser's TextTrack API stringifies it to the literal "null". We treat
159
+ * "null"/"undefined" (any casing) as placeholders too, and fall back to a
160
+ * localized language name via Intl.DisplayNames.
161
+ */
162
+ deriveTrackLabel(rawLabel, language) {
163
+ const cleanLabel = (rawLabel ?? "").trim();
164
+ const cleanLang = (language ?? "").trim();
165
+ const looksLikePlaceholder = cleanLabel === "" || /^\d+$/.test(cleanLabel) || /^(null|undefined)$/i.test(cleanLabel);
166
+ if (!looksLikePlaceholder) {
167
+ return cleanLabel;
168
+ }
169
+ const cleanLangIsUsable = cleanLang !== "" && !/^(null|undefined)$/i.test(cleanLang);
170
+ if (cleanLangIsUsable) {
171
+ try {
172
+ const uiLang = i18n.getLanguage() || "en";
173
+ const displayNames = new Intl.DisplayNames([uiLang, "en"], { type: "language" });
174
+ const name = displayNames.of(cleanLang);
175
+ if (name && name.toLowerCase() !== cleanLang.toLowerCase()) {
176
+ return name;
177
+ }
178
+ } catch {
179
+ }
180
+ return cleanLang.toUpperCase();
181
+ }
182
+ return i18n.t("player.captions");
183
+ }
149
184
  /**
150
185
  * Sync hls.js subtitle rendition to match the given language.
151
186
  * Matches by lang, language, or falls back to name/label.
@@ -477,4 +512,4 @@ export {
477
512
  rafWithTimeout,
478
513
  CaptionManager
479
514
  };
480
- //# sourceMappingURL=vidply.chunk-2RIPRXWI.js.map
515
+ //# sourceMappingURL=vidply.chunk-JBW74LP7.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/PerformanceUtils.ts", "../../src/controls/CaptionManager.ts"],
4
+ "sourcesContent": ["export function debounce<T extends (...args: unknown[]) => void>(func: T, wait = 100): T {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n return function executedFunction(this: unknown, ...args: unknown[]) {\n const later = () => {\n clearTimeout(timeout);\n func.apply(this, args);\n };\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n } as unknown as T;\n}\n\nexport function throttle<T extends (...args: unknown[]) => void>(func: T, limit = 100): T {\n let inThrottle = false;\n return function executedFunction(this: unknown, ...args: unknown[]) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => inThrottle = false, limit);\n }\n } as unknown as T;\n}\n\nexport function isMobile(breakpoint = 768): boolean {\n return window.innerWidth < breakpoint;\n}\n\nexport function rafWithTimeout(callback: () => void, timeout = 100): void {\n let called = false;\n\n const execute = () => {\n if (!called) {\n called = true;\n callback();\n }\n };\n\n requestAnimationFrame(execute);\n setTimeout(execute, timeout);\n}\n", "/**\r\n * Caption/Subtitle Manager\r\n */\r\n\r\nimport {DOMUtils} from '../utils/DOMUtils.js';\r\nimport {i18n} from '../i18n/i18n.js';\r\nimport {StorageManager} from '../utils/StorageManager.js';\r\nimport {debounce, isMobile, rafWithTimeout} from '../utils/PerformanceUtils.js';\r\nimport type { Player } from '../core/Player.js';\r\n\r\nexport class CaptionManager {\r\n player: Player;\r\n _altCueChangeHandler: any;\r\n cueChangeHandler: any;\r\n currentCue: any;\r\n currentTrack: any;\r\n debouncedPositionCaptions: any;\r\n element: any;\r\n storage: StorageManager;\r\n tracks: any[];\r\n\r\n constructor(player: Player) {\r\n this.player = player;\r\n this.element = null;\r\n this.tracks = [];\r\n this.currentTrack = null;\r\n this.currentCue = null;\r\n \r\n // Storage manager\r\n this.storage = new StorageManager('vidply');\r\n \r\n // Load saved preferences\r\n this.loadSavedPreferences();\r\n\r\n this.init();\r\n }\r\n \r\n loadSavedPreferences() {\r\n const saved = this.storage.getCaptionPreferences();\r\n if (saved) {\r\n // Override player options with saved preferences\r\n if (saved.fontSize) this.player.options.captionsFontSize = saved.fontSize;\r\n if (saved.fontFamily) this.player.options.captionsFontFamily = saved.fontFamily;\r\n if (saved.color) this.player.options.captionsColor = saved.color;\r\n if (saved.backgroundColor) this.player.options.captionsBackgroundColor = saved.backgroundColor;\r\n if (saved.opacity !== undefined) this.player.options.captionsOpacity = saved.opacity;\r\n }\r\n }\r\n \r\n saveCaptionPreferences() {\r\n this.storage.saveCaptionPreferences({\r\n fontSize: this.player.options.captionsFontSize,\r\n fontFamily: this.player.options.captionsFontFamily,\r\n color: this.player.options.captionsColor,\r\n backgroundColor: this.player.options.captionsBackgroundColor,\r\n opacity: this.player.options.captionsOpacity\r\n });\r\n }\r\n\r\n init() {\r\n this.createElement();\r\n this.loadTracks();\r\n this.attachEvents();\r\n\r\n // Only enable captions via captionsDefault option if no default track was found\r\n // (loadTracks() already enables tracks with the default attribute)\r\n if (this.player.options.captionsDefault && this.tracks.length > 0 && !this.currentTrack) {\r\n this.enable();\r\n }\r\n }\r\n\r\n createElement() {\r\n this.element = DOMUtils.createElement('div', {\r\n className: `${this.player.options.classPrefix}-captions`,\r\n attributes: {\r\n 'role': 'region',\r\n 'aria-label': i18n.t('player.captions')\r\n }\r\n });\r\n\r\n // Apply caption styles\r\n this.updateStyles();\r\n\r\n // Append to videoWrapper if it exists, otherwise to container\r\n const target = this.player.videoWrapper || this.player.container;\r\n target.appendChild(this.element);\r\n }\r\n\r\n loadTracks() {\r\n const textTracks = this.player.element.textTracks;\r\n let defaultTrackIndex = -1;\r\n\r\n // Safari's native HLS can expose both SUBTITLES (WebVTT sidecar) and\r\n // CLOSED-CAPTIONS (inband CEA-608) groups as separate TextTrack objects\r\n // with the same language and label. Deduplicate to one menu entry per\r\n // language+label, storing the extras as alternatives. enable() will\r\n // listen on all of them and use whichever delivers cues first.\r\n const seen = new Map();\r\n\r\n for (let i = 0; i < textTracks.length; i++) {\r\n const track = textTracks[i];\r\n\r\n if ((track.kind === 'subtitles' || track.kind === 'captions') && !track._vidplyStale) {\r\n track.mode = 'hidden';\r\n\r\n const dedupeKey = `${track.language}|${track.label}`;\r\n const existing = seen.get(dedupeKey);\r\n\r\n if (existing) {\r\n existing.alternatives.push(track);\r\n continue;\r\n }\r\n\r\n const trackElement = this.player.findTrackElement(track);\r\n const isDefault = trackElement && trackElement.hasAttribute('default');\r\n const entry = {\r\n track,\r\n language: track.language,\r\n label: this.deriveTrackLabel(track.label, track.language),\r\n kind: track.kind,\r\n index: i,\r\n isDefault,\r\n alternatives: [] as TextTrack[]\r\n };\r\n\r\n this.tracks.push(entry);\r\n seen.set(dedupeKey, entry);\r\n\r\n if (isDefault) {\r\n defaultTrackIndex = this.tracks.length - 1;\r\n }\r\n }\r\n }\r\n \r\n if (defaultTrackIndex >= 0) {\r\n requestAnimationFrame(() => {\r\n this.enable(defaultTrackIndex);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Derive a human-readable label for a TextTrack when the source manifest\r\n * (DASH AdaptationSet, HLS rendition, etc.) didn't provide one. dash.js\r\n * falls back to the AdaptationSet @id (typically a digit like \"2\", \"3\")\r\n * when no <Label> child element is present, which surfaces as cryptic\r\n * \"2\"/\"3\" entries in the captions menu.\r\n *\r\n * dash.js 5.x additionally derives the label as `element.id ?? element.lang`.\r\n * When neither is present in the MPD, the value is JS `null`, and the\r\n * browser's TextTrack API stringifies it to the literal \"null\". We treat\r\n * \"null\"/\"undefined\" (any casing) as placeholders too, and fall back to a\r\n * localized language name via Intl.DisplayNames.\r\n */\r\n private deriveTrackLabel(rawLabel: string | null | undefined, language: string | null | undefined): string {\r\n const cleanLabel = (rawLabel ?? '').trim();\r\n const cleanLang = (language ?? '').trim();\r\n\r\n const looksLikePlaceholder =\r\n cleanLabel === '' ||\r\n /^\\d+$/.test(cleanLabel) ||\r\n /^(null|undefined)$/i.test(cleanLabel);\r\n if (!looksLikePlaceholder) {\r\n return cleanLabel;\r\n }\r\n\r\n const cleanLangIsUsable =\r\n cleanLang !== '' && !/^(null|undefined)$/i.test(cleanLang);\r\n\r\n if (cleanLangIsUsable) {\r\n try {\r\n const uiLang = i18n.getLanguage() || 'en';\r\n const displayNames = new Intl.DisplayNames([uiLang, 'en'], { type: 'language' });\r\n const name = displayNames.of(cleanLang);\r\n if (name && name.toLowerCase() !== cleanLang.toLowerCase()) {\r\n return name;\r\n }\r\n } catch {\r\n // Intl.DisplayNames may be unavailable — fall through to the code.\r\n }\r\n return cleanLang.toUpperCase();\r\n }\r\n\r\n // No usable label and no usable language — return a generic fallback\r\n // so the menu never displays \"null\" or an empty menu item.\r\n return i18n.t('player.captions');\r\n }\r\n\r\n /**\r\n * Sync hls.js subtitle rendition to match the given language.\r\n * Matches by lang, language, or falls back to name/label.\r\n */\r\n private _syncHlsSubtitleTrack(targetLang: string, targetLabel?: string) {\r\n const renderer = (this.player as any).renderer;\r\n if (!renderer?.hls || !renderer.hls.subtitleTracks?.length) return;\r\n\r\n const tracks = renderer.hls.subtitleTracks;\r\n let hlsIndex = tracks.findIndex(\r\n (t: any) => t.lang === targetLang\r\n );\r\n // Fallback: match by name/label\r\n if (hlsIndex < 0 && targetLabel) {\r\n hlsIndex = tracks.findIndex(\r\n (t: any) => t.name === targetLabel\r\n );\r\n }\r\n if (hlsIndex >= 0 && renderer.hls.subtitleTrack !== hlsIndex) {\r\n renderer.hls.subtitleTrack = hlsIndex;\r\n this.player.log(`HLS subtitle track set to index ${hlsIndex} (${targetLang})`, 'info');\r\n }\r\n }\r\n\r\n attachEvents() {\r\n this.player.on('timeupdate', () => {\r\n this.updateCaptions();\r\n });\r\n\r\n // When hls.js finishes loading new subtitle cues, refresh captions\r\n this.player.on('textcuesupdate', () => {\r\n this.updateCaptions();\r\n });\r\n\r\n this.player.on('captionschange', () => {\r\n this.updateStyles();\r\n });\r\n \r\n // Debounced resize handler to avoid excessive recalculations\r\n this.debouncedPositionCaptions = debounce(() => {\r\n this.positionCaptionsOnMobile();\r\n }, 150);\r\n \r\n window.addEventListener('resize', this.debouncedPositionCaptions);\r\n \r\n // Recalculate on fullscreen change with RAF\r\n this.player.on('enterfullscreen', () => {\r\n rafWithTimeout(() => this.positionCaptionsOnMobile(), 100);\r\n });\r\n \r\n this.player.on('exitfullscreen', () => {\r\n rafWithTimeout(() => this.positionCaptionsOnMobile(), 100);\r\n });\r\n }\r\n\r\n enable(trackIndex = 0) {\r\n if (this.tracks.length === 0) {\r\n return;\r\n }\r\n\r\n // Disable current track and clean up alternative listeners\r\n this._cleanupTrackListeners();\r\n\r\n // Enable selected track\r\n const selectedTrack = this.tracks[trackIndex];\r\n\r\n if (selectedTrack && selectedTrack.track) {\r\n selectedTrack.track.mode = 'hidden';\r\n this.currentTrack = selectedTrack;\r\n this.player.state.captionsEnabled = true;\r\n \r\n if (selectedTrack.language) {\r\n this.element.setAttribute('lang', selectedTrack.language);\r\n }\r\n\r\n this.cueChangeHandler = () => {\r\n this.updateCaptions();\r\n };\r\n selectedTrack.track.addEventListener('cuechange', this.cueChangeHandler);\r\n\r\n // Native HLS dedup: Safari can expose duplicate TextTrack objects\r\n // for the same language (SUBTITLES vs CLOSED-CAPTIONS groups) but\r\n // only one actually delivers cues. Listen on all alternatives and\r\n // swap to whichever fires first with real cues.\r\n if (selectedTrack.alternatives && selectedTrack.alternatives.length > 0) {\r\n this._altCueChangeHandler = () => {\r\n if (this.currentTrack !== selectedTrack) return;\r\n for (const alt of selectedTrack.alternatives) {\r\n if (alt.activeCues && alt.activeCues.length > 0) {\r\n this.player.log(`Switching to alternative caption track for \"${selectedTrack.label}\"`, 'info');\r\n selectedTrack.track.removeEventListener('cuechange', this.cueChangeHandler);\r\n selectedTrack.alternatives.forEach((a: TextTrack) => a.removeEventListener('cuechange', this._altCueChangeHandler));\r\n selectedTrack.track = alt;\r\n selectedTrack.track.addEventListener('cuechange', this.cueChangeHandler);\r\n this._altCueChangeHandler = null;\r\n this.updateCaptions();\r\n return;\r\n }\r\n }\r\n };\r\n selectedTrack.alternatives.forEach((alt: TextTrack) => {\r\n alt.mode = 'hidden';\r\n alt.addEventListener('cuechange', this._altCueChangeHandler);\r\n });\r\n }\r\n\r\n const ensureTrackReady = () => {\r\n if (selectedTrack.track.readyState < 2) {\r\n const onTrackLoad = () => {\r\n selectedTrack.track.removeEventListener('load', onTrackLoad);\r\n selectedTrack.track.removeEventListener('error', onTrackLoad);\r\n requestAnimationFrame(() => {\r\n if (this.currentTrack && this.currentTrack.track === selectedTrack.track) {\r\n this.updateCaptions();\r\n }\r\n });\r\n };\r\n selectedTrack.track.addEventListener('load', onTrackLoad, { once: true });\r\n selectedTrack.track.addEventListener('error', onTrackLoad, { once: true });\r\n } else {\r\n requestAnimationFrame(() => {\r\n if (this.currentTrack && this.currentTrack.track === selectedTrack.track) {\r\n this.updateCaptions();\r\n }\r\n });\r\n }\r\n };\r\n\r\n requestAnimationFrame(() => {\r\n if (this.currentTrack && this.currentTrack.track === selectedTrack.track) {\r\n ensureTrackReady();\r\n }\r\n });\r\n\r\n // Sync hls.js subtitle rendition to match the selected track language\r\n this._syncHlsSubtitleTrack(selectedTrack.language, selectedTrack.label);\r\n\r\n this.player.emit('captionsenabled', selectedTrack);\r\n }\r\n }\r\n\r\n _cleanupTrackListeners() {\r\n if (this.currentTrack && this.currentTrack.track) {\r\n if (this.cueChangeHandler) {\r\n this.currentTrack.track.removeEventListener('cuechange', this.cueChangeHandler);\r\n }\r\n if (this._altCueChangeHandler && this.currentTrack.alternatives) {\r\n this.currentTrack.alternatives.forEach((alt: TextTrack) => {\r\n alt.removeEventListener('cuechange', this._altCueChangeHandler);\r\n });\r\n }\r\n this.currentTrack.track.mode = 'hidden';\r\n }\r\n this._altCueChangeHandler = null;\r\n }\r\n\r\n disable() {\r\n this._cleanupTrackListeners();\r\n this.currentTrack = null;\r\n\r\n this.element.style.display = 'none';\r\n this.element.innerHTML = '';\r\n this.element.removeAttribute('lang');\r\n this.currentCue = null;\r\n this.player.state.captionsEnabled = false;\r\n this.player.emit('captionsdisabled');\r\n }\r\n\r\n updateCaptions() {\r\n if (!this.currentTrack || !this.currentTrack.track) {\r\n return;\r\n }\r\n\r\n // When the renderer handles its own caption display (e.g. dash.js TTML\r\n // rendering div), skip VidPly's caption overlay entirely.\r\n if (this.player.renderer?.handlesOwnCaptions?.()) {\r\n return;\r\n }\r\n\r\n // Ensure track mode is set to 'hidden' (not 'disabled') to receive cue updates\r\n // 'hidden' mode loads cues and fires cuechange events, but doesn't show native captions\r\n if (this.currentTrack.track.mode === 'disabled') {\r\n this.currentTrack.track.mode = 'hidden';\r\n }\r\n\r\n if (this.currentTrack.track.mode === 'showing') {\r\n this.currentTrack.track.mode = 'hidden';\r\n }\r\n\r\n if (!this.currentTrack.track.activeCues) {\r\n if (this.currentTrack.track.cues && this.currentTrack.track.cues.length > 0) {\r\n if (this.currentCue) {\r\n this.element.innerHTML = '';\r\n this.element.style.display = 'none';\r\n this.currentCue = null;\r\n }\r\n }\r\n return;\r\n }\r\n\r\n const activeCues = this.currentTrack.track.activeCues;\r\n const isAudioPlayer = this.player.element.tagName.toLowerCase() === 'audio';\r\n\r\n if (activeCues.length > 0) {\r\n const cue = activeCues[0];\r\n\r\n if (this.currentCue !== cue) {\r\n this.currentCue = cue;\r\n\r\n let text = cue.text || '';\r\n text = this.parseVTTFormatting(text);\r\n const sanitized = DOMUtils.sanitizeHTML(text);\r\n\r\n if (!sanitized.trim()) {\r\n return;\r\n }\r\n\r\n if (isAudioPlayer) {\r\n const existingCues = this.element.querySelectorAll(`.${this.player.options.classPrefix}-caption-cue`);\r\n existingCues.forEach((el: Element) => el.classList.remove(`${this.player.options.classPrefix}-caption-active`));\r\n \r\n const cueId = `cue-${cue.startTime}-${cue.endTime}`;\r\n let cueElement = this.element.querySelector(`[data-cue-id=\"${cueId}\"]`);\r\n \r\n if (!cueElement) {\r\n cueElement = document.createElement('div');\r\n cueElement.className = `${this.player.options.classPrefix}-caption-cue`;\r\n cueElement.setAttribute('data-cue-id', cueId);\r\n cueElement.innerHTML = sanitized;\r\n this.element.appendChild(cueElement);\r\n }\r\n \r\n cueElement.classList.add(`${this.player.options.classPrefix}-caption-active`);\r\n \r\n requestAnimationFrame(() => {\r\n if (cueElement) {\r\n cueElement.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n }\r\n });\r\n } else {\r\n this.element.innerHTML = sanitized;\r\n }\r\n\r\n this.element.style.display = 'block';\r\n this.positionCaptionsOnMobile();\r\n this.player.emit('captionchange', cue);\r\n }\r\n } else if (this.currentCue) {\r\n if (!isAudioPlayer) {\r\n this.element.innerHTML = '';\r\n this.element.style.display = 'none';\r\n }\r\n this.currentCue = null;\r\n }\r\n }\r\n \r\n positionCaptionsOnMobile() {\r\n if (!this.element || this.element.style.display === 'none') {\r\n return;\r\n }\r\n \r\n const isFullscreen = this.player.state?.fullscreen || false;\r\n const mobile = isMobile();\r\n \r\n if (!mobile && !isFullscreen) {\r\n // Reset to CSS defaults on desktop\r\n this.element.style.bottom = '';\r\n return;\r\n }\r\n \r\n const controls = this.player.controlBar?.element;\r\n if (!controls) {\r\n return;\r\n }\r\n \r\n // Use requestAnimationFrame to ensure layout is complete\r\n requestAnimationFrame(() => {\r\n if (!this.element || this.element.style.display === 'none') {\r\n return;\r\n }\r\n \r\n const controlsRect = controls.getBoundingClientRect();\r\n const wrapperRect = this.player.videoWrapper.getBoundingClientRect();\r\n const bottomOffset = wrapperRect.bottom - controlsRect.top + 16;\r\n \r\n this.element.style.bottom = `${bottomOffset}px`;\r\n \r\n if (this.player.options.debug) {\r\n console.log('[VidPly] Caption position:', {\r\n mobile,\r\n isFullscreen,\r\n controlsHeight: controlsRect.height,\r\n bottomOffset: `${bottomOffset}px`\r\n });\r\n }\r\n });\r\n }\r\n\r\n parseVTTFormatting(text: string) {\r\n // Basic VTT tag support\r\n text = text.replace(/<c[^>]*>(.*?)<\\/c>/g, '<span class=\"caption-class\">$1</span>');\r\n text = text.replace(/<b>(.*?)<\\/b>/g, '<strong>$1</strong>');\r\n text = text.replace(/<i>(.*?)<\\/i>/g, '<em>$1</em>');\r\n text = text.replace(/<u>(.*?)<\\/u>/g, '<u>$1</u>');\r\n\r\n // Voice tags\r\n text = text.replace(/<v\\s+([^>]+)>(.*?)<\\/v>/g, '<span class=\"caption-voice\" data-voice=\"$1\">$2</span>');\r\n\r\n return text;\r\n }\r\n\r\n updateStyles() {\r\n if (!this.element) return;\r\n\r\n const options = this.player.options;\r\n\r\n this.element.style.fontSize = options.captionsFontSize;\r\n this.element.style.fontFamily = options.captionsFontFamily;\r\n this.element.style.color = options.captionsColor;\r\n this.element.style.backgroundColor = this.hexToRgba(\r\n options.captionsBackgroundColor,\r\n options.captionsOpacity\r\n );\r\n }\r\n\r\n hexToRgba(hex: string, alpha: number) {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n if (result) {\r\n return `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${alpha})`;\r\n }\r\n return hex;\r\n }\r\n\r\n setCaptionStyle(property: string, value: string | number) {\r\n switch (property) {\r\n case 'fontSize':\r\n this.player.options.captionsFontSize = value;\r\n break;\r\n case 'fontFamily':\r\n this.player.options.captionsFontFamily = value;\r\n break;\r\n case 'color':\r\n this.player.options.captionsColor = value;\r\n break;\r\n case 'backgroundColor':\r\n this.player.options.captionsBackgroundColor = value;\r\n break;\r\n case 'opacity':\r\n this.player.options.captionsOpacity = value;\r\n break;\r\n }\r\n\r\n this.updateStyles();\r\n this.saveCaptionPreferences();\r\n this.player.emit('captionschange');\r\n }\r\n\r\n getAvailableTracks() {\r\n return this.tracks.map((t: any, index: number) => ({\r\n index,\r\n language: t.language,\r\n label: t.label || t.language,\r\n kind: t.kind\r\n }));\r\n }\r\n\r\n /**\r\n * Refresh tracks list - useful when HLS adds subtitle tracks dynamically\r\n */\r\n refreshTracks() {\r\n // Store current track info to restore after refresh\r\n const currentLanguage = this.currentTrack?.language;\r\n const wasEnabled = this.player.state.captionsEnabled;\r\n \r\n // Disable current caption\r\n if (this.currentTrack) {\r\n this.disable();\r\n }\r\n \r\n // Clear existing tracks\r\n this.tracks = [];\r\n \r\n // Reload tracks from video element\r\n this.loadTracks();\r\n \r\n this.player.log(`Caption tracks refreshed, found ${this.tracks.length} tracks`, 'info');\r\n \r\n // Try to restore previous track if it exists\r\n if (wasEnabled && currentLanguage && this.tracks.length > 0) {\r\n const matchingIndex = this.tracks.findIndex((t: any) => t.language === currentLanguage);\r\n if (matchingIndex >= 0) {\r\n this.enable(matchingIndex);\r\n }\r\n }\r\n \r\n return this.tracks.length;\r\n }\r\n\r\n switchTrack(trackIndex: number) {\r\n if (trackIndex >= 0 && trackIndex < this.tracks.length) {\r\n this.disable();\r\n this.enable(trackIndex);\r\n }\r\n }\r\n\r\n destroy() {\r\n this.disable();\r\n\r\n if (this.element && this.element.parentNode) {\r\n this.element.parentNode.removeChild(this.element);\r\n }\r\n }\r\n}\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -15,7 +15,7 @@ import {
15
15
  isMobile,
16
16
  rafWithTimeout,
17
17
  throttle
18
- } from "./vidply.chunk-2RIPRXWI.js";
18
+ } from "./vidply.chunk-JBW74LP7.js";
19
19
  import {
20
20
  StorageManager
21
21
  } from "./vidply.chunk-X6PJOVWZ.js";
@@ -1027,7 +1027,7 @@ var ControlBar = class {
1027
1027
  this.previewVideoInitialized = true;
1028
1028
  return;
1029
1029
  }
1030
- const isStreamingRenderer = renderer.hls && typeof renderer.hls.loadLevel !== "undefined" || renderer.dash && typeof renderer.dash.getQualityFor === "function";
1030
+ const isStreamingRenderer = renderer.isStreaming === true || renderer.hls && typeof renderer.hls.loadLevel !== "undefined" || renderer.dash && (typeof renderer.dash.getQualityFor === "function" || typeof renderer.dash.getCurrentRepresentationForType === "function" || typeof renderer.dash.getRepresentationsByType === "function" || typeof renderer.dash.attachSource === "function");
1031
1031
  const isHTML5Renderer = hasVideoMedia && renderer.media === this.player.element && !isStreamingRenderer && typeof renderer.seek === "function";
1032
1032
  if (isStreamingRenderer) {
1033
1033
  this.previewVideo = null;
@@ -3617,7 +3617,7 @@ var SignLanguageManagerModule = null;
3617
3617
  var FloatingPlayerManagerModule = null;
3618
3618
  async function loadAudioDescriptionManager() {
3619
3619
  if (!AudioDescriptionManagerModule) {
3620
- const module = await import("./vidply.AudioDescriptionManager-DCZFE3N2.js");
3620
+ const module = await import("./vidply.AudioDescriptionManager-HUWRAHX4.js");
3621
3621
  AudioDescriptionManagerModule = module.AudioDescriptionManager;
3622
3622
  }
3623
3623
  return AudioDescriptionManagerModule;
@@ -4827,10 +4827,10 @@ var Player = class _Player extends EventEmitter {
4827
4827
  const module = await import("./vidply.VimeoRenderer-6CLUVHOQ.js");
4828
4828
  return module.VimeoRenderer || module.default;
4829
4829
  } else if (src.includes(".m3u8")) {
4830
- const module = await import("./vidply.HLSRenderer-IVT5CQQ4.js");
4830
+ const module = await import("./vidply.HLSRenderer-7XRBH6P3.js");
4831
4831
  return module.HLSRenderer || module.default;
4832
4832
  } else if (src.includes(".mpd")) {
4833
- const module = await import("./vidply.DASHRenderer-HP7BXLGV.js");
4833
+ const module = await import("./vidply.DASHRenderer-DAIMQ7NC.js");
4834
4834
  return module.DASHRenderer || module.default;
4835
4835
  } else if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
4836
4836
  const module = await import("./vidply.SoundCloudRenderer-T64HDIWO.js");
@@ -5225,6 +5225,9 @@ var Player = class _Player extends EventEmitter {
5225
5225
  if (typeof this.renderer._hlsSourceLoaded === "boolean") {
5226
5226
  this.renderer._hlsSourceLoaded = false;
5227
5227
  }
5228
+ if (typeof this.renderer._dashSourceLoaded === "boolean") {
5229
+ this.renderer._dashSourceLoaded = false;
5230
+ }
5228
5231
  if ("_pendingSrc" in this.renderer) {
5229
5232
  this.renderer._pendingSrc = this._pendingSource || this.currentSource || null;
5230
5233
  }