@livepeer-frameworks/player-wc 0.2.7 → 0.2.11

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 (55) hide show
  1. package/LICENSE.md +24 -0
  2. package/README.md +30 -30
  3. package/dist/esm/components/controls/fw-fullscreen-button.js +1 -1
  4. package/dist/esm/components/controls/fw-live-badge.js +1 -1
  5. package/dist/esm/components/controls/fw-play-button.js +1 -1
  6. package/dist/esm/components/controls/fw-skip-button.js +2 -2
  7. package/dist/esm/components/controls/fw-skip-button.js.map +1 -1
  8. package/dist/esm/components/controls/fw-time-display.js +1 -1
  9. package/dist/esm/components/controls/fw-volume-control.js +1 -1
  10. package/dist/esm/components/fw-context-menu.js +1 -1
  11. package/dist/esm/components/fw-dev-mode-panel.js +22 -12
  12. package/dist/esm/components/fw-dev-mode-panel.js.map +1 -1
  13. package/dist/esm/components/fw-dvd-logo.js +1 -1
  14. package/dist/esm/components/fw-error-overlay.js +1 -1
  15. package/dist/esm/components/fw-idle-screen.js +1 -1
  16. package/dist/esm/components/fw-loading-screen.js +1 -1
  17. package/dist/esm/components/fw-loading-spinner.js +1 -1
  18. package/dist/esm/components/fw-player-controls.js +8 -11
  19. package/dist/esm/components/fw-player-controls.js.map +1 -1
  20. package/dist/esm/components/fw-player.js +18 -14
  21. package/dist/esm/components/fw-player.js.map +1 -1
  22. package/dist/esm/components/fw-seek-bar.js +19 -11
  23. package/dist/esm/components/fw-seek-bar.js.map +1 -1
  24. package/dist/esm/components/fw-settings-menu.js +3 -3
  25. package/dist/esm/components/fw-settings-menu.js.map +1 -1
  26. package/dist/esm/components/fw-skip-indicator.js +1 -1
  27. package/dist/esm/components/fw-speed-indicator.js +1 -1
  28. package/dist/esm/components/fw-stats-panel.js +1 -1
  29. package/dist/esm/components/fw-stream-state-overlay.js +1 -1
  30. package/dist/esm/components/fw-subtitle-renderer.js +3 -3
  31. package/dist/esm/components/fw-subtitle-renderer.js.map +1 -1
  32. package/dist/esm/components/fw-thumbnail-overlay.js +1 -1
  33. package/dist/esm/components/fw-title-overlay.js +1 -1
  34. package/dist/esm/components/fw-toast.js +1 -1
  35. package/dist/esm/components/fw-volume-control.js +32 -8
  36. package/dist/esm/components/fw-volume-control.js.map +1 -1
  37. package/dist/esm/controllers/player-controller-host.js +6 -2
  38. package/dist/esm/controllers/player-controller-host.js.map +1 -1
  39. package/dist/esm/node_modules/.pnpm/{@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3 → @rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3}/node_modules/tslib/tslib.es6.js.map +1 -1
  40. package/dist/esm/styles/shared-styles.js +40 -4
  41. package/dist/esm/styles/shared-styles.js.map +1 -1
  42. package/dist/fw-player.iife.js +251 -204
  43. package/dist/types/components/fw-volume-control.d.ts +3 -0
  44. package/package.json +16 -16
  45. package/src/components/controls/fw-skip-button.ts +1 -1
  46. package/src/components/fw-dev-mode-panel.ts +21 -11
  47. package/src/components/fw-player-controls.ts +11 -12
  48. package/src/components/fw-player.ts +17 -13
  49. package/src/components/fw-seek-bar.ts +18 -10
  50. package/src/components/fw-settings-menu.ts +2 -1
  51. package/src/components/fw-subtitle-renderer.ts +2 -2
  52. package/src/components/fw-volume-control.ts +33 -7
  53. package/src/controllers/player-controller-host.ts +6 -2
  54. package/src/styles/shared-styles.ts +40 -4
  55. /package/dist/esm/node_modules/.pnpm/{@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3 → @rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3}/node_modules/tslib/tslib.es6.js +0 -0
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, nothing, html } from 'lit';
3
3
  import { property, state, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
@@ -26,7 +26,7 @@ let FwSeekBar = class FwSeekBar extends LitElement {
26
26
  if (this.disabled) {
27
27
  return;
28
28
  }
29
- const step = event.shiftKey ? 10 : 5;
29
+ const step = event.shiftKey ? 10000 : 5000;
30
30
  const rawRangeEnd = this.isLive ? this._effectiveLiveEdge : this.duration;
31
31
  const rangeEnd = Number.isFinite(rawRangeEnd) ? rawRangeEnd : this.currentTime + step;
32
32
  const rangeStart = this.isLive ? this.seekableStart : 0;
@@ -157,8 +157,9 @@ let FwSeekBar = class FwSeekBar extends LitElement {
157
157
  }
158
158
  const segments = [];
159
159
  for (let i = 0; i < buffered.length; i += 1) {
160
- const start = buffered.start(i);
161
- const end = buffered.end(i);
160
+ // buffered TimeRanges are in seconds (browser API), convert to ms
161
+ const start = buffered.start(i) * 1000;
162
+ const end = buffered.end(i) * 1000;
162
163
  const relativeStart = start - rangeStart;
163
164
  const relativeEnd = end - rangeStart;
164
165
  segments.push({
@@ -168,11 +169,11 @@ let FwSeekBar = class FwSeekBar extends LitElement {
168
169
  }
169
170
  return segments;
170
171
  }
171
- _formatTime(seconds) {
172
- if (!Number.isFinite(seconds) || seconds < 0) {
172
+ _formatTime(ms) {
173
+ if (!Number.isFinite(ms) || ms < 0) {
173
174
  return "0:00";
174
175
  }
175
- const total = Math.floor(seconds);
176
+ const total = Math.floor(ms / 1000);
176
177
  const hours = Math.floor(total / 3600);
177
178
  const minutes = Math.floor((total % 3600) / 60);
178
179
  const secs = total % 60;
@@ -181,12 +182,12 @@ let FwSeekBar = class FwSeekBar extends LitElement {
181
182
  }
182
183
  return `${minutes}:${String(secs).padStart(2, "0")}`;
183
184
  }
184
- _formatLiveTime(seconds, edge) {
185
- const behindSeconds = edge - seconds;
186
- if (behindSeconds < 1) {
185
+ _formatLiveTime(ms, edgeMs) {
186
+ const behindMs = edgeMs - ms;
187
+ if (behindMs < 1000) {
187
188
  return "LIVE";
188
189
  }
189
- const total = Math.floor(behindSeconds);
190
+ const total = Math.floor(behindMs / 1000);
190
191
  const hours = Math.floor(total / 3600);
191
192
  const minutes = Math.floor((total % 3600) / 60);
192
193
  const secs = total % 60;
@@ -289,6 +290,13 @@ let FwSeekBar = class FwSeekBar extends LitElement {
289
290
  ></div>
290
291
  `)}
291
292
  <div class="fw-seek-progress" style=${styleMap({ width: `${progressPercent}%` })}></div>
293
+ ${this._hovering && !this._dragging
294
+ ? html `<div
295
+ class="fw-seek-hover-line"
296
+ style=${styleMap({ left: `${this._hoverPosition}%` })}
297
+ ></div>`
298
+ : nothing}
299
+ ${this.isLive ? html `<div class="fw-seek-live-edge"></div>` : nothing}
292
300
  </div>
293
301
 
294
302
  <div
@@ -1 +1 @@
1
- {"version":3,"file":"fw-seek-bar.js","sources":["../../../../src/components/fw-seek-bar.ts"],"sourcesContent":["/**\n * <fw-seek-bar> — Video seek bar with buffer visualization, drag, and live tooltips.\n * Behavioral parity with react/svelte SeekBar implementations.\n */\nimport { LitElement, html, css, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { sharedStyles } from \"../styles/shared-styles.js\";\n\ninterface BufferedSegment {\n startPercent: number;\n endPercent: number;\n}\n\n@customElement(\"fw-seek-bar\")\nexport class FwSeekBar extends LitElement {\n @property({ type: Number }) currentTime = 0;\n @property({ type: Number }) duration = 0;\n @property({ attribute: false }) buffered: TimeRanges | null = null;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean, attribute: \"is-live\" }) isLive = false;\n @property({ type: Number, attribute: \"seekable-start\" }) seekableStart = 0;\n @property({ type: Number, attribute: \"live-edge\" }) liveEdge?: number;\n @property({ type: Boolean, attribute: \"commit-on-release\" }) commitOnRelease = false;\n\n @state() private _hovering = false;\n @state() private _dragging = false;\n @state() private _dragTime: number | null = null;\n @state() private _hoverPosition = 0;\n @state() private _hoverTime = 0;\n\n private _trackRect: DOMRect | null = null;\n private _activePointerId: number | null = null;\n\n static styles = [\n sharedStyles,\n css`\n :host {\n display: block;\n width: 100%;\n }\n\n .seek-root {\n position: relative;\n width: 100%;\n height: 1.5rem;\n display: flex;\n align-items: center;\n cursor: pointer;\n }\n\n .seek-root--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n ];\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._detachDragListeners();\n }\n\n private get _effectiveLiveEdge(): number {\n if (typeof this.liveEdge === \"number\" && Number.isFinite(this.liveEdge)) {\n return this.liveEdge;\n }\n return this.duration;\n }\n\n private get _seekableWindow(): number {\n return this._effectiveLiveEdge - this.seekableStart;\n }\n\n private get _displayTime(): number {\n return this._dragTime ?? this.currentTime;\n }\n\n private get _progressPercent(): number {\n const displayTime = this._displayTime;\n\n if (this.isLive && this._seekableWindow > 0) {\n const positionInWindow = displayTime - this.seekableStart;\n return Math.min(100, Math.max(0, (positionInWindow / this._seekableWindow) * 100));\n }\n\n if (!Number.isFinite(this.duration) || this.duration <= 0) {\n return 0;\n }\n\n return Math.min(100, Math.max(0, (displayTime / this.duration) * 100));\n }\n\n private get _bufferedSegments(): BufferedSegment[] {\n const buffered = this.buffered;\n if (!buffered || buffered.length === 0) {\n return [];\n }\n\n const rangeEnd = this.isLive ? this._effectiveLiveEdge : this.duration;\n const rangeStart = this.isLive ? this.seekableStart : 0;\n const rangeSize = rangeEnd - rangeStart;\n\n if (!Number.isFinite(rangeSize) || rangeSize <= 0) {\n return [];\n }\n\n const segments: BufferedSegment[] = [];\n for (let i = 0; i < buffered.length; i += 1) {\n const start = buffered.start(i);\n const end = buffered.end(i);\n const relativeStart = start - rangeStart;\n const relativeEnd = end - rangeStart;\n\n segments.push({\n startPercent: Math.min(100, Math.max(0, (relativeStart / rangeSize) * 100)),\n endPercent: Math.min(100, Math.max(0, (relativeEnd / rangeSize) * 100)),\n });\n }\n\n return segments;\n }\n\n private _formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) {\n return \"0:00\";\n }\n\n const total = Math.floor(seconds);\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const secs = total % 60;\n\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`;\n }\n\n return `${minutes}:${String(secs).padStart(2, \"0\")}`;\n }\n\n private _formatLiveTime(seconds: number, edge: number): string {\n const behindSeconds = edge - seconds;\n if (behindSeconds < 1) {\n return \"LIVE\";\n }\n\n const total = Math.floor(behindSeconds);\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const secs = total % 60;\n\n if (hours > 0) {\n return `-${hours}:${String(minutes).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`;\n }\n\n return `-${minutes}:${String(secs).padStart(2, \"0\")}`;\n }\n\n private _getTrackRect(): DOMRect | null {\n const track = this.renderRoot.querySelector(\".seek-root\") as HTMLDivElement | null;\n if (!track) {\n return null;\n }\n\n this._trackRect = track.getBoundingClientRect();\n return this._trackRect;\n }\n\n private _getTimeFromClientX(clientX: number): number {\n const rect = this._getTrackRect();\n if (!rect || rect.width <= 0) {\n return 0;\n }\n\n const x = clientX - rect.left;\n const percent = Math.min(1, Math.max(0, x / rect.width));\n\n if (this.isLive && Number.isFinite(this._seekableWindow) && this._seekableWindow > 0) {\n return this.seekableStart + percent * this._seekableWindow;\n }\n\n if (Number.isFinite(this.duration) && this.duration > 0) {\n return percent * this.duration;\n }\n\n if (Number.isFinite(this._effectiveLiveEdge) && this._effectiveLiveEdge > 0) {\n const start = Number.isFinite(this.seekableStart) ? this.seekableStart : 0;\n const window = this._effectiveLiveEdge - start;\n if (window > 0) {\n return start + percent * window;\n }\n }\n\n return percent * (this.currentTime || 1);\n }\n\n private _updateHover(clientX: number): void {\n const rect = this._getTrackRect();\n if (!rect || rect.width <= 0) {\n return;\n }\n\n const x = clientX - rect.left;\n const percent = Math.min(1, Math.max(0, x / rect.width));\n this._hoverPosition = percent * 100;\n this._hoverTime = this._getTimeFromClientX(clientX);\n }\n\n private _emitSeek(time: number): void {\n this.dispatchEvent(\n new CustomEvent(\"fw-seek\", { detail: { time }, bubbles: true, composed: true })\n );\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) {\n return;\n }\n\n const step = event.shiftKey ? 10 : 5;\n const rawRangeEnd = this.isLive ? this._effectiveLiveEdge : this.duration;\n const rangeEnd = Number.isFinite(rawRangeEnd) ? rawRangeEnd : this.currentTime + step;\n const rangeStart = this.isLive ? this.seekableStart : 0;\n\n let newTime: number | null = null;\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowDown\":\n newTime = Math.max(rangeStart, this.currentTime - step);\n break;\n case \"ArrowRight\":\n case \"ArrowUp\":\n newTime = Math.min(rangeEnd, this.currentTime + step);\n break;\n case \"Home\":\n newTime = rangeStart;\n break;\n case \"End\":\n newTime = rangeEnd;\n break;\n default:\n return;\n }\n\n if (newTime != null) {\n event.preventDefault();\n this._emitSeek(newTime);\n }\n };\n\n private _onPointerEnter = () => {\n if (this.disabled) {\n return;\n }\n this._hovering = true;\n };\n\n private _onPointerLeave = () => {\n this._hovering = false;\n this._trackRect = null;\n };\n\n private _onPointerMove = (event: PointerEvent) => {\n if (this.disabled || (!this._hovering && !this._dragging)) {\n return;\n }\n this._updateHover(event.clientX);\n };\n\n private _onPointerDown = (event: PointerEvent) => {\n if (this.disabled) {\n return;\n }\n\n if (!this.isLive && !Number.isFinite(this.duration)) {\n return;\n }\n\n event.preventDefault();\n this._activePointerId = event.pointerId;\n this._dragging = true;\n this._hovering = true;\n\n const initialTime = this._getTimeFromClientX(event.clientX);\n this._updateHover(event.clientX);\n\n if (this.commitOnRelease) {\n this._dragTime = initialTime;\n } else {\n this._emitSeek(initialTime);\n }\n\n this._attachDragListeners();\n };\n\n private _onGlobalPointerMove = (event: PointerEvent) => {\n if (!this._dragging || this._activePointerId !== event.pointerId) {\n return;\n }\n\n const time = this._getTimeFromClientX(event.clientX);\n this._updateHover(event.clientX);\n\n if (this.commitOnRelease) {\n this._dragTime = time;\n } else {\n this._emitSeek(time);\n }\n };\n\n private _onGlobalPointerUp = (event: PointerEvent) => {\n if (!this._dragging || this._activePointerId !== event.pointerId) {\n return;\n }\n\n if (this.commitOnRelease && this._dragTime != null) {\n this._emitSeek(this._dragTime);\n }\n\n this._dragging = false;\n this._dragTime = null;\n this._activePointerId = null;\n this._detachDragListeners();\n };\n\n private _attachDragListeners(): void {\n window.addEventListener(\"pointermove\", this._onGlobalPointerMove);\n window.addEventListener(\"pointerup\", this._onGlobalPointerUp);\n window.addEventListener(\"pointercancel\", this._onGlobalPointerUp);\n }\n\n private _detachDragListeners(): void {\n window.removeEventListener(\"pointermove\", this._onGlobalPointerMove);\n window.removeEventListener(\"pointerup\", this._onGlobalPointerUp);\n window.removeEventListener(\"pointercancel\", this._onGlobalPointerUp);\n }\n\n protected render() {\n const progressPercent = this._progressPercent;\n const showThumb = this._hovering || this._dragging;\n const canShowTooltip = this.isLive ? this._seekableWindow > 0 : Number.isFinite(this.duration);\n\n return html`\n <div\n class=${classMap({\n \"seek-root\": true,\n \"seek-root--disabled\": this.disabled,\n \"fw-seek-root\": true,\n })}\n @pointerenter=${this._onPointerEnter}\n @pointerleave=${this._onPointerLeave}\n @pointermove=${this._onPointerMove}\n @pointerdown=${this._onPointerDown}\n role=\"slider\"\n aria-label=\"Seek\"\n aria-valuemin=${this.isLive ? this.seekableStart : 0}\n aria-valuemax=${this.isLive\n ? this._effectiveLiveEdge\n : Number.isFinite(this.duration)\n ? this.duration\n : 100}\n aria-valuenow=${this._displayTime}\n aria-valuetext=${this.isLive\n ? this._formatLiveTime(this._displayTime, this._effectiveLiveEdge)\n : this._formatTime(this._displayTime)}\n tabindex=${this.disabled ? -1 : 0}\n @keydown=${this._onKeyDown}\n >\n <div class=${classMap({ \"fw-seek-track\": true, \"fw-seek-track--active\": this._dragging })}>\n ${this._bufferedSegments.map(\n (segment) => html`\n <div\n class=\"fw-seek-buffered\"\n style=${styleMap({\n left: `${segment.startPercent}%`,\n width: `${segment.endPercent - segment.startPercent}%`,\n })}\n ></div>\n `\n )}\n <div class=\"fw-seek-progress\" style=${styleMap({ width: `${progressPercent}%` })}></div>\n </div>\n\n <div\n class=${classMap({\n \"fw-seek-thumb\": true,\n \"fw-seek-thumb--active\": showThumb,\n \"fw-seek-thumb--hidden\": !showThumb,\n })}\n style=${styleMap({ left: `${progressPercent}%` })}\n ></div>\n\n ${this._hovering && !this._dragging && canShowTooltip\n ? html`\n <div class=\"fw-seek-tooltip\" style=${styleMap({ left: `${this._hoverPosition}%` })}>\n ${this.isLive\n ? this._formatLiveTime(this._hoverTime, this._effectiveLiveEdge)\n : this._formatTime(this._hoverTime)}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-seek-bar\": FwSeekBar;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fw-seek-bar.js","sources":["../../../../src/components/fw-seek-bar.ts"],"sourcesContent":["/**\n * <fw-seek-bar> — Video seek bar with buffer visualization, drag, and live tooltips.\n * Behavioral parity with react/svelte SeekBar implementations.\n */\nimport { LitElement, html, css, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { sharedStyles } from \"../styles/shared-styles.js\";\n\ninterface BufferedSegment {\n startPercent: number;\n endPercent: number;\n}\n\n@customElement(\"fw-seek-bar\")\nexport class FwSeekBar extends LitElement {\n @property({ type: Number }) currentTime = 0;\n @property({ type: Number }) duration = 0;\n @property({ attribute: false }) buffered: TimeRanges | null = null;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean, attribute: \"is-live\" }) isLive = false;\n @property({ type: Number, attribute: \"seekable-start\" }) seekableStart = 0;\n @property({ type: Number, attribute: \"live-edge\" }) liveEdge?: number;\n @property({ type: Boolean, attribute: \"commit-on-release\" }) commitOnRelease = false;\n\n @state() private _hovering = false;\n @state() private _dragging = false;\n @state() private _dragTime: number | null = null;\n @state() private _hoverPosition = 0;\n @state() private _hoverTime = 0;\n\n private _trackRect: DOMRect | null = null;\n private _activePointerId: number | null = null;\n\n static styles = [\n sharedStyles,\n css`\n :host {\n display: block;\n width: 100%;\n }\n\n .seek-root {\n position: relative;\n width: 100%;\n height: 1.5rem;\n display: flex;\n align-items: center;\n cursor: pointer;\n }\n\n .seek-root--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n ];\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._detachDragListeners();\n }\n\n private get _effectiveLiveEdge(): number {\n if (typeof this.liveEdge === \"number\" && Number.isFinite(this.liveEdge)) {\n return this.liveEdge;\n }\n return this.duration;\n }\n\n private get _seekableWindow(): number {\n return this._effectiveLiveEdge - this.seekableStart;\n }\n\n private get _displayTime(): number {\n return this._dragTime ?? this.currentTime;\n }\n\n private get _progressPercent(): number {\n const displayTime = this._displayTime;\n\n if (this.isLive && this._seekableWindow > 0) {\n const positionInWindow = displayTime - this.seekableStart;\n return Math.min(100, Math.max(0, (positionInWindow / this._seekableWindow) * 100));\n }\n\n if (!Number.isFinite(this.duration) || this.duration <= 0) {\n return 0;\n }\n\n return Math.min(100, Math.max(0, (displayTime / this.duration) * 100));\n }\n\n private get _bufferedSegments(): BufferedSegment[] {\n const buffered = this.buffered;\n if (!buffered || buffered.length === 0) {\n return [];\n }\n\n const rangeEnd = this.isLive ? this._effectiveLiveEdge : this.duration;\n const rangeStart = this.isLive ? this.seekableStart : 0;\n const rangeSize = rangeEnd - rangeStart;\n\n if (!Number.isFinite(rangeSize) || rangeSize <= 0) {\n return [];\n }\n\n const segments: BufferedSegment[] = [];\n for (let i = 0; i < buffered.length; i += 1) {\n // buffered TimeRanges are in seconds (browser API), convert to ms\n const start = buffered.start(i) * 1000;\n const end = buffered.end(i) * 1000;\n const relativeStart = start - rangeStart;\n const relativeEnd = end - rangeStart;\n\n segments.push({\n startPercent: Math.min(100, Math.max(0, (relativeStart / rangeSize) * 100)),\n endPercent: Math.min(100, Math.max(0, (relativeEnd / rangeSize) * 100)),\n });\n }\n\n return segments;\n }\n\n private _formatTime(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) {\n return \"0:00\";\n }\n\n const total = Math.floor(ms / 1000);\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const secs = total % 60;\n\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`;\n }\n\n return `${minutes}:${String(secs).padStart(2, \"0\")}`;\n }\n\n private _formatLiveTime(ms: number, edgeMs: number): string {\n const behindMs = edgeMs - ms;\n if (behindMs < 1000) {\n return \"LIVE\";\n }\n\n const total = Math.floor(behindMs / 1000);\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const secs = total % 60;\n\n if (hours > 0) {\n return `-${hours}:${String(minutes).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`;\n }\n\n return `-${minutes}:${String(secs).padStart(2, \"0\")}`;\n }\n\n private _getTrackRect(): DOMRect | null {\n const track = this.renderRoot.querySelector(\".seek-root\") as HTMLDivElement | null;\n if (!track) {\n return null;\n }\n\n this._trackRect = track.getBoundingClientRect();\n return this._trackRect;\n }\n\n private _getTimeFromClientX(clientX: number): number {\n const rect = this._getTrackRect();\n if (!rect || rect.width <= 0) {\n return 0;\n }\n\n const x = clientX - rect.left;\n const percent = Math.min(1, Math.max(0, x / rect.width));\n\n if (this.isLive && Number.isFinite(this._seekableWindow) && this._seekableWindow > 0) {\n return this.seekableStart + percent * this._seekableWindow;\n }\n\n if (Number.isFinite(this.duration) && this.duration > 0) {\n return percent * this.duration;\n }\n\n if (Number.isFinite(this._effectiveLiveEdge) && this._effectiveLiveEdge > 0) {\n const start = Number.isFinite(this.seekableStart) ? this.seekableStart : 0;\n const window = this._effectiveLiveEdge - start;\n if (window > 0) {\n return start + percent * window;\n }\n }\n\n return percent * (this.currentTime || 1);\n }\n\n private _updateHover(clientX: number): void {\n const rect = this._getTrackRect();\n if (!rect || rect.width <= 0) {\n return;\n }\n\n const x = clientX - rect.left;\n const percent = Math.min(1, Math.max(0, x / rect.width));\n this._hoverPosition = percent * 100;\n this._hoverTime = this._getTimeFromClientX(clientX);\n }\n\n private _emitSeek(time: number): void {\n this.dispatchEvent(\n new CustomEvent(\"fw-seek\", { detail: { time }, bubbles: true, composed: true })\n );\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) {\n return;\n }\n\n const step = event.shiftKey ? 10000 : 5000;\n const rawRangeEnd = this.isLive ? this._effectiveLiveEdge : this.duration;\n const rangeEnd = Number.isFinite(rawRangeEnd) ? rawRangeEnd : this.currentTime + step;\n const rangeStart = this.isLive ? this.seekableStart : 0;\n\n let newTime: number | null = null;\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowDown\":\n newTime = Math.max(rangeStart, this.currentTime - step);\n break;\n case \"ArrowRight\":\n case \"ArrowUp\":\n newTime = Math.min(rangeEnd, this.currentTime + step);\n break;\n case \"Home\":\n newTime = rangeStart;\n break;\n case \"End\":\n newTime = rangeEnd;\n break;\n default:\n return;\n }\n\n if (newTime != null) {\n event.preventDefault();\n this._emitSeek(newTime);\n }\n };\n\n private _onPointerEnter = () => {\n if (this.disabled) {\n return;\n }\n this._hovering = true;\n };\n\n private _onPointerLeave = () => {\n this._hovering = false;\n this._trackRect = null;\n };\n\n private _onPointerMove = (event: PointerEvent) => {\n if (this.disabled || (!this._hovering && !this._dragging)) {\n return;\n }\n this._updateHover(event.clientX);\n };\n\n private _onPointerDown = (event: PointerEvent) => {\n if (this.disabled) {\n return;\n }\n\n if (!this.isLive && !Number.isFinite(this.duration)) {\n return;\n }\n\n event.preventDefault();\n this._activePointerId = event.pointerId;\n this._dragging = true;\n this._hovering = true;\n\n const initialTime = this._getTimeFromClientX(event.clientX);\n this._updateHover(event.clientX);\n\n if (this.commitOnRelease) {\n this._dragTime = initialTime;\n } else {\n this._emitSeek(initialTime);\n }\n\n this._attachDragListeners();\n };\n\n private _onGlobalPointerMove = (event: PointerEvent) => {\n if (!this._dragging || this._activePointerId !== event.pointerId) {\n return;\n }\n\n const time = this._getTimeFromClientX(event.clientX);\n this._updateHover(event.clientX);\n\n if (this.commitOnRelease) {\n this._dragTime = time;\n } else {\n this._emitSeek(time);\n }\n };\n\n private _onGlobalPointerUp = (event: PointerEvent) => {\n if (!this._dragging || this._activePointerId !== event.pointerId) {\n return;\n }\n\n if (this.commitOnRelease && this._dragTime != null) {\n this._emitSeek(this._dragTime);\n }\n\n this._dragging = false;\n this._dragTime = null;\n this._activePointerId = null;\n this._detachDragListeners();\n };\n\n private _attachDragListeners(): void {\n window.addEventListener(\"pointermove\", this._onGlobalPointerMove);\n window.addEventListener(\"pointerup\", this._onGlobalPointerUp);\n window.addEventListener(\"pointercancel\", this._onGlobalPointerUp);\n }\n\n private _detachDragListeners(): void {\n window.removeEventListener(\"pointermove\", this._onGlobalPointerMove);\n window.removeEventListener(\"pointerup\", this._onGlobalPointerUp);\n window.removeEventListener(\"pointercancel\", this._onGlobalPointerUp);\n }\n\n protected render() {\n const progressPercent = this._progressPercent;\n const showThumb = this._hovering || this._dragging;\n const canShowTooltip = this.isLive ? this._seekableWindow > 0 : Number.isFinite(this.duration);\n\n return html`\n <div\n class=${classMap({\n \"seek-root\": true,\n \"seek-root--disabled\": this.disabled,\n \"fw-seek-root\": true,\n })}\n @pointerenter=${this._onPointerEnter}\n @pointerleave=${this._onPointerLeave}\n @pointermove=${this._onPointerMove}\n @pointerdown=${this._onPointerDown}\n role=\"slider\"\n aria-label=\"Seek\"\n aria-valuemin=${this.isLive ? this.seekableStart : 0}\n aria-valuemax=${this.isLive\n ? this._effectiveLiveEdge\n : Number.isFinite(this.duration)\n ? this.duration\n : 100}\n aria-valuenow=${this._displayTime}\n aria-valuetext=${this.isLive\n ? this._formatLiveTime(this._displayTime, this._effectiveLiveEdge)\n : this._formatTime(this._displayTime)}\n tabindex=${this.disabled ? -1 : 0}\n @keydown=${this._onKeyDown}\n >\n <div class=${classMap({ \"fw-seek-track\": true, \"fw-seek-track--active\": this._dragging })}>\n ${this._bufferedSegments.map(\n (segment) => html`\n <div\n class=\"fw-seek-buffered\"\n style=${styleMap({\n left: `${segment.startPercent}%`,\n width: `${segment.endPercent - segment.startPercent}%`,\n })}\n ></div>\n `\n )}\n <div class=\"fw-seek-progress\" style=${styleMap({ width: `${progressPercent}%` })}></div>\n ${this._hovering && !this._dragging\n ? html`<div\n class=\"fw-seek-hover-line\"\n style=${styleMap({ left: `${this._hoverPosition}%` })}\n ></div>`\n : nothing}\n ${this.isLive ? html`<div class=\"fw-seek-live-edge\"></div>` : nothing}\n </div>\n\n <div\n class=${classMap({\n \"fw-seek-thumb\": true,\n \"fw-seek-thumb--active\": showThumb,\n \"fw-seek-thumb--hidden\": !showThumb,\n })}\n style=${styleMap({ left: `${progressPercent}%` })}\n ></div>\n\n ${this._hovering && !this._dragging && canShowTooltip\n ? html`\n <div class=\"fw-seek-tooltip\" style=${styleMap({ left: `${this._hoverPosition}%` })}>\n ${this.isLive\n ? this._formatLiveTime(this._hoverTime, this._effectiveLiveEdge)\n : this._formatTime(this._hoverTime)}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-seek-bar\": FwSeekBar;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, nothing, html } from 'lit';
3
3
  import { property, state, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
5
5
  import { sharedStyles } from '../styles/shared-styles.js';
6
6
  import { utilityStyles } from '../styles/utility-styles.js';
7
- import { supportsPlaybackRate, SPEED_PRESETS, getAvailableLocales, getLocaleDisplayName } from '@livepeer-frameworks/player-core';
7
+ import { formatQualityLabel, supportsPlaybackRate, SPEED_PRESETS, getAvailableLocales, getLocaleDisplayName } from '@livepeer-frameworks/player-core';
8
8
 
9
9
  let FwSettingsMenu = class FwSettingsMenu extends LitElement {
10
10
  constructor() {
@@ -88,7 +88,7 @@ let FwSettingsMenu = class FwSettingsMenu extends LitElement {
88
88
  .filter(([, track]) => track?.type === "video")
89
89
  .map(([id, track]) => ({
90
90
  id,
91
- label: track.height ? `${track.height}p` : (track.codec ?? id),
91
+ label: formatQualityLabel(track.width, track.height, track.bps),
92
92
  width: track.width,
93
93
  height: track.height,
94
94
  bitrate: track.bps,
@@ -1 +1 @@
1
- {"version":3,"file":"fw-settings-menu.js","sources":["../../../../src/components/fw-settings-menu.ts"],"sourcesContent":["/**\n * <fw-settings-menu> — Mode, speed, quality, and captions settings popup.\n */\nimport { LitElement, html, css, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { sharedStyles } from \"../styles/shared-styles.js\";\nimport { utilityStyles } from \"../styles/utility-styles.js\";\nimport {\n SPEED_PRESETS,\n supportsPlaybackRate as coreSupportsPlaybackRate,\n getAvailableLocales,\n getLocaleDisplayName,\n} from \"@livepeer-frameworks/player-core\";\nimport type { PlaybackMode, FwLocale } from \"@livepeer-frameworks/player-core\";\nimport type { PlayerControllerHost } from \"../controllers/player-controller-host.js\";\n\n@customElement(\"fw-settings-menu\")\nexport class FwSettingsMenu extends LitElement {\n @property({ attribute: false }) pc!: PlayerControllerHost;\n @property({ type: Boolean }) open = false;\n @property({ type: String }) playbackMode: PlaybackMode = \"auto\";\n @property({ type: Boolean, attribute: \"is-content-live\" }) isContentLive = true;\n @property({ type: Number, attribute: \"playback-rate\" }) playbackRate?: number;\n @property({ type: String, attribute: \"quality-value\" }) qualityValue?: string;\n @property({ type: String, attribute: \"caption-value\" }) captionValue?: string;\n @property({ type: Boolean, attribute: \"supports-playback-rate\" }) supportsPlaybackRate?: boolean;\n @property({ attribute: \"active-locale\" }) activeLocale?: FwLocale;\n\n @state() private _playbackRate = 1;\n\n static styles = [\n sharedStyles,\n utilityStyles,\n css`\n :host {\n display: contents;\n }\n `,\n ];\n\n protected updated(): void {\n if (!this.open) {\n return;\n }\n\n if (Number.isFinite(this.playbackRate)) {\n this._playbackRate = this.playbackRate as number;\n return;\n }\n\n const video = this.pc?.s.videoElement;\n if (video && Number.isFinite(video.playbackRate)) {\n this._playbackRate = video.playbackRate;\n }\n }\n\n private _close(): void {\n this.dispatchEvent(new CustomEvent(\"fw-close\", { bubbles: true, composed: true }));\n }\n\n private _handleModeChange(mode: \"auto\" | \"low-latency\" | \"quality\"): void {\n this.pc.setDevModeOptions({ playbackMode: mode });\n this.dispatchEvent(\n new CustomEvent(\"fw-mode-change\", {\n detail: { mode },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleSpeedChange(rate: number): void {\n this._playbackRate = rate;\n this.pc.setPlaybackRate(rate);\n this.dispatchEvent(\n new CustomEvent(\"fw-speed-change\", {\n detail: { rate },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleQualityChange(id: string): void {\n this.pc.selectQuality(id);\n this.dispatchEvent(\n new CustomEvent(\"fw-quality-change\", {\n detail: { quality: id },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleCaptionChange(id: string): void {\n if (id === \"none\") {\n this.pc.selectTextTrack(null);\n } else {\n this.pc.selectTextTrack(id);\n }\n this.dispatchEvent(\n new CustomEvent(\"fw-caption-change\", {\n detail: { caption: id },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleLocaleChange(locale: FwLocale): void {\n this.dispatchEvent(\n new CustomEvent(\"fw-locale-change\", {\n detail: { locale },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private _deriveFallbackQualities(): Array<{\n id: string;\n label: string;\n bitrate?: number;\n width?: number;\n height?: number;\n isAuto?: boolean;\n active?: boolean;\n }> {\n const tracks = (\n this.pc?.s.streamState?.streamInfo as\n | {\n meta?: {\n tracks?: Record<\n string,\n { type?: string; codec?: string; width?: number; height?: number; bps?: number }\n >;\n };\n }\n | undefined\n )?.meta?.tracks;\n\n if (!tracks) {\n return [];\n }\n\n return Object.entries(tracks)\n .filter(([, track]) => track?.type === \"video\")\n .map(([id, track]) => ({\n id,\n label: track.height ? `${track.height}p` : (track.codec ?? id),\n width: track.width,\n height: track.height,\n bitrate: track.bps,\n }))\n .sort((a, b) => (b.height ?? 0) - (a.height ?? 0));\n }\n\n protected render() {\n if (!this.open) {\n return nothing;\n }\n\n const state = this.pc.s;\n const controllerQualities = state.qualities ?? [];\n const qualities =\n controllerQualities.length > 0 ? controllerQualities : this._deriveFallbackQualities();\n const textTracks = state.textTracks ?? [];\n const activeQuality =\n this.qualityValue ?? qualities.find((quality) => quality.active)?.id ?? \"auto\";\n const activeCaption =\n this.captionValue ?? textTracks.find((track) => track.active)?.id ?? \"none\";\n\n const supportsPlaybackRate =\n this.supportsPlaybackRate ?? coreSupportsPlaybackRate(state.videoElement);\n\n return html`\n <div class=\"fw-settings-menu\" role=\"menu\" aria-label=${this.pc.t(\"settings\")}>\n ${this.isContentLive\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"mode\")}</div>\n <div class=\"fw-settings-options\">\n ${([\"auto\", \"low-latency\", \"quality\"] as const).map(\n (mode) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-btn\": true,\n \"fw-settings-btn--active\": this.playbackMode === mode,\n })}\n @click=${() => this._handleModeChange(mode)}\n >\n ${mode === \"low-latency\"\n ? this.pc.t(\"fast\")\n : mode === \"quality\"\n ? this.pc.t(\"stable\")\n : this.pc.t(\"auto\")}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${supportsPlaybackRate\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"speed\")}</div>\n <div class=\"fw-settings-options fw-settings-options--wrap\">\n ${SPEED_PRESETS.map(\n (rate) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-btn\": true,\n \"fw-settings-btn--active\": this._playbackRate === rate,\n })}\n @click=${() => this._handleSpeedChange(rate)}\n >\n ${rate}x\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${qualities.length > 0\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"quality\")}</div>\n <div class=\"fw-settings-list\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeQuality === \"auto\",\n })}\n @click=${() => this._handleQualityChange(\"auto\")}\n >\n ${this.pc.t(\"auto\")}\n </button>\n ${qualities.map(\n (quality) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeQuality === quality.id,\n })}\n @click=${() => this._handleQualityChange(quality.id)}\n >\n ${quality.label}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${textTracks.length > 0\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"captions\")}</div>\n <div class=\"fw-settings-list\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeCaption === \"none\",\n })}\n @click=${() => this._handleCaptionChange(\"none\")}\n >\n ${this.pc.t(\"captionsOff\")}\n </button>\n ${textTracks.map(\n (track) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeCaption === track.id,\n })}\n @click=${() => this._handleCaptionChange(track.id)}\n >\n ${track.label || track.id}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${this.activeLocale !== undefined\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"language\")}</div>\n <div class=\"fw-settings-list\">\n ${getAvailableLocales().map(\n (loc) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": this.activeLocale === loc,\n })}\n @click=${() => this._handleLocaleChange(loc)}\n >\n ${getLocaleDisplayName(loc)}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-settings-menu\": FwSettingsMenu;\n }\n}\n"],"names":["supportsPlaybackRate","coreSupportsPlaybackRate"],"mappings":"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"}
1
+ {"version":3,"file":"fw-settings-menu.js","sources":["../../../../src/components/fw-settings-menu.ts"],"sourcesContent":["/**\n * <fw-settings-menu> — Mode, speed, quality, and captions settings popup.\n */\nimport { LitElement, html, css, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { sharedStyles } from \"../styles/shared-styles.js\";\nimport { utilityStyles } from \"../styles/utility-styles.js\";\nimport {\n SPEED_PRESETS,\n supportsPlaybackRate as coreSupportsPlaybackRate,\n getAvailableLocales,\n getLocaleDisplayName,\n formatQualityLabel,\n} from \"@livepeer-frameworks/player-core\";\nimport type { PlaybackMode, FwLocale } from \"@livepeer-frameworks/player-core\";\nimport type { PlayerControllerHost } from \"../controllers/player-controller-host.js\";\n\n@customElement(\"fw-settings-menu\")\nexport class FwSettingsMenu extends LitElement {\n @property({ attribute: false }) pc!: PlayerControllerHost;\n @property({ type: Boolean }) open = false;\n @property({ type: String }) playbackMode: PlaybackMode = \"auto\";\n @property({ type: Boolean, attribute: \"is-content-live\" }) isContentLive = true;\n @property({ type: Number, attribute: \"playback-rate\" }) playbackRate?: number;\n @property({ type: String, attribute: \"quality-value\" }) qualityValue?: string;\n @property({ type: String, attribute: \"caption-value\" }) captionValue?: string;\n @property({ type: Boolean, attribute: \"supports-playback-rate\" }) supportsPlaybackRate?: boolean;\n @property({ attribute: \"active-locale\" }) activeLocale?: FwLocale;\n\n @state() private _playbackRate = 1;\n\n static styles = [\n sharedStyles,\n utilityStyles,\n css`\n :host {\n display: contents;\n }\n `,\n ];\n\n protected updated(): void {\n if (!this.open) {\n return;\n }\n\n if (Number.isFinite(this.playbackRate)) {\n this._playbackRate = this.playbackRate as number;\n return;\n }\n\n const video = this.pc?.s.videoElement;\n if (video && Number.isFinite(video.playbackRate)) {\n this._playbackRate = video.playbackRate;\n }\n }\n\n private _close(): void {\n this.dispatchEvent(new CustomEvent(\"fw-close\", { bubbles: true, composed: true }));\n }\n\n private _handleModeChange(mode: \"auto\" | \"low-latency\" | \"quality\"): void {\n this.pc.setDevModeOptions({ playbackMode: mode });\n this.dispatchEvent(\n new CustomEvent(\"fw-mode-change\", {\n detail: { mode },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleSpeedChange(rate: number): void {\n this._playbackRate = rate;\n this.pc.setPlaybackRate(rate);\n this.dispatchEvent(\n new CustomEvent(\"fw-speed-change\", {\n detail: { rate },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleQualityChange(id: string): void {\n this.pc.selectQuality(id);\n this.dispatchEvent(\n new CustomEvent(\"fw-quality-change\", {\n detail: { quality: id },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleCaptionChange(id: string): void {\n if (id === \"none\") {\n this.pc.selectTextTrack(null);\n } else {\n this.pc.selectTextTrack(id);\n }\n this.dispatchEvent(\n new CustomEvent(\"fw-caption-change\", {\n detail: { caption: id },\n bubbles: true,\n composed: true,\n })\n );\n this._close();\n }\n\n private _handleLocaleChange(locale: FwLocale): void {\n this.dispatchEvent(\n new CustomEvent(\"fw-locale-change\", {\n detail: { locale },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private _deriveFallbackQualities(): Array<{\n id: string;\n label: string;\n bitrate?: number;\n width?: number;\n height?: number;\n isAuto?: boolean;\n active?: boolean;\n }> {\n const tracks = (\n this.pc?.s.streamState?.streamInfo as\n | {\n meta?: {\n tracks?: Record<\n string,\n { type?: string; codec?: string; width?: number; height?: number; bps?: number }\n >;\n };\n }\n | undefined\n )?.meta?.tracks;\n\n if (!tracks) {\n return [];\n }\n\n return Object.entries(tracks)\n .filter(([, track]) => track?.type === \"video\")\n .map(([id, track]) => ({\n id,\n label: formatQualityLabel(track.width, track.height, track.bps),\n width: track.width,\n height: track.height,\n bitrate: track.bps,\n }))\n .sort((a, b) => (b.height ?? 0) - (a.height ?? 0));\n }\n\n protected render() {\n if (!this.open) {\n return nothing;\n }\n\n const state = this.pc.s;\n const controllerQualities = state.qualities ?? [];\n const qualities =\n controllerQualities.length > 0 ? controllerQualities : this._deriveFallbackQualities();\n const textTracks = state.textTracks ?? [];\n const activeQuality =\n this.qualityValue ?? qualities.find((quality) => quality.active)?.id ?? \"auto\";\n const activeCaption =\n this.captionValue ?? textTracks.find((track) => track.active)?.id ?? \"none\";\n\n const supportsPlaybackRate =\n this.supportsPlaybackRate ?? coreSupportsPlaybackRate(state.videoElement);\n\n return html`\n <div class=\"fw-settings-menu\" role=\"menu\" aria-label=${this.pc.t(\"settings\")}>\n ${this.isContentLive\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"mode\")}</div>\n <div class=\"fw-settings-options\">\n ${([\"auto\", \"low-latency\", \"quality\"] as const).map(\n (mode) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-btn\": true,\n \"fw-settings-btn--active\": this.playbackMode === mode,\n })}\n @click=${() => this._handleModeChange(mode)}\n >\n ${mode === \"low-latency\"\n ? this.pc.t(\"fast\")\n : mode === \"quality\"\n ? this.pc.t(\"stable\")\n : this.pc.t(\"auto\")}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${supportsPlaybackRate\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"speed\")}</div>\n <div class=\"fw-settings-options fw-settings-options--wrap\">\n ${SPEED_PRESETS.map(\n (rate) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-btn\": true,\n \"fw-settings-btn--active\": this._playbackRate === rate,\n })}\n @click=${() => this._handleSpeedChange(rate)}\n >\n ${rate}x\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${qualities.length > 0\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"quality\")}</div>\n <div class=\"fw-settings-list\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeQuality === \"auto\",\n })}\n @click=${() => this._handleQualityChange(\"auto\")}\n >\n ${this.pc.t(\"auto\")}\n </button>\n ${qualities.map(\n (quality) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeQuality === quality.id,\n })}\n @click=${() => this._handleQualityChange(quality.id)}\n >\n ${quality.label}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${textTracks.length > 0\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"captions\")}</div>\n <div class=\"fw-settings-list\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeCaption === \"none\",\n })}\n @click=${() => this._handleCaptionChange(\"none\")}\n >\n ${this.pc.t(\"captionsOff\")}\n </button>\n ${textTracks.map(\n (track) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": activeCaption === track.id,\n })}\n @click=${() => this._handleCaptionChange(track.id)}\n >\n ${track.label || track.id}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n ${this.activeLocale !== undefined\n ? html`\n <div class=\"fw-settings-section\">\n <div class=\"fw-settings-label\">${this.pc.t(\"language\")}</div>\n <div class=\"fw-settings-list\">\n ${getAvailableLocales().map(\n (loc) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-settings-list-item\": true,\n \"fw-settings-list-item--active\": this.activeLocale === loc,\n })}\n @click=${() => this._handleLocaleChange(loc)}\n >\n ${getLocaleDisplayName(loc)}\n </button>\n `\n )}\n </div>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-settings-menu\": FwSettingsMenu;\n }\n}\n"],"names":["supportsPlaybackRate","coreSupportsPlaybackRate"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, html, nothing } from 'lit';
3
3
  import { property, state, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, html } from 'lit';
3
3
  import { property, customElement } from 'lit/decorators.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, html } from 'lit';
3
3
  import { property, customElement } from 'lit/decorators.js';
4
4
  import { sharedStyles } from '../styles/shared-styles.js';
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, html, nothing } from 'lit';
3
3
  import { property, customElement } from 'lit/decorators.js';
4
4
  import { createTranslator } from '@livepeer-frameworks/player-core';
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, nothing, html } from 'lit';
3
3
  import { property, state, customElement } from 'lit/decorators.js';
4
4
  import { styleMap } from 'lit/directives/style-map.js';
@@ -106,7 +106,7 @@ let FwSubtitleRenderer = class FwSubtitleRenderer extends LitElement {
106
106
  }
107
107
  return;
108
108
  }
109
- const currentTimeMs = this.currentTime * 1000;
109
+ const currentTimeMs = this.currentTime;
110
110
  const activeCue = this._getAllCues().find((cue) => currentTimeMs >= cue.startTime && currentTimeMs < cue.endTime);
111
111
  const nextText = activeCue?.text ?? "";
112
112
  if (nextText !== this._displayedText) {
@@ -117,7 +117,7 @@ let FwSubtitleRenderer = class FwSubtitleRenderer extends LitElement {
117
117
  if (this._liveCues.length === 0) {
118
118
  return;
119
119
  }
120
- const currentTimeMs = this.currentTime * 1000;
120
+ const currentTimeMs = this.currentTime;
121
121
  const filtered = this._liveCues.filter((cue) => {
122
122
  const endTime = cue.endTime === Infinity ? cue.startTime + 10000 : cue.endTime;
123
123
  return endTime >= currentTimeMs - 30000;
@@ -1 +1 @@
1
- {"version":3,"file":"fw-subtitle-renderer.js","sources":["../../../../src/components/fw-subtitle-renderer.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\n\ninterface SubtitleCue {\n id?: string;\n text: string;\n startTime: number;\n endTime: number;\n lang?: string;\n}\n\ninterface MetaTrackEvent {\n type: string;\n data: unknown;\n}\n\ninterface SubtitleStyle {\n fontSize?: string;\n fontFamily?: string;\n color?: string;\n backgroundColor?: string;\n textShadow?: string;\n bottom?: string;\n maxWidth?: string;\n padding?: string;\n borderRadius?: string;\n}\n\nconst DEFAULT_STYLE: Required<SubtitleStyle> = {\n fontSize: \"1.5rem\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n color: \"white\",\n backgroundColor: \"rgba(0, 0, 0, 0.75)\",\n textShadow: \"2px 2px 4px rgba(0, 0, 0, 0.5)\",\n bottom: \"5%\",\n maxWidth: \"90%\",\n padding: \"0.5em 1em\",\n borderRadius: \"4px\",\n};\n\n@customElement(\"fw-subtitle-renderer\")\nexport class FwSubtitleRenderer extends LitElement {\n @property({ type: Number }) currentTime = 0;\n @property({ type: Boolean }) enabled = true;\n @property({ attribute: false }) cues: SubtitleCue[] = [];\n @property({ attribute: false })\n subscribeToMetaTrack?: (trackId: string, callback: (event: MetaTrackEvent) => void) => () => void;\n @property({ type: String, attribute: \"meta-track-id\" }) metaTrackId?: string;\n @property({ attribute: false }) subtitleStyle?: SubtitleStyle;\n @property({ type: String, attribute: \"class-name\" }) className = \"\";\n\n @state() private _liveCues: SubtitleCue[] = [];\n @state() private _displayedText = \"\";\n\n private _unsubscribe: (() => void) | null = null;\n\n static styles = css`\n :host {\n display: contents;\n }\n\n .subtitle-container {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n z-index: 30;\n text-align: center;\n pointer-events: none;\n }\n\n .subtitle-text {\n display: inline-block;\n white-space: pre-wrap;\n }\n `;\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardownSubscription();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n if (\n changed.has(\"enabled\") ||\n changed.has(\"subscribeToMetaTrack\") ||\n changed.has(\"metaTrackId\")\n ) {\n this._syncSubscription();\n }\n\n if (changed.has(\"currentTime\") || changed.has(\"_liveCues\")) {\n this._pruneExpiredLiveCues();\n }\n\n if (\n changed.has(\"enabled\") ||\n changed.has(\"currentTime\") ||\n changed.has(\"cues\") ||\n changed.has(\"_liveCues\")\n ) {\n this._syncDisplayedCue();\n }\n }\n\n private _syncSubscription(): void {\n this._teardownSubscription();\n\n if (!this.enabled || !this.subscribeToMetaTrack || !this.metaTrackId) {\n return;\n }\n\n this._unsubscribe = this.subscribeToMetaTrack(this.metaTrackId, this._handleMetaEvent);\n }\n\n private _teardownSubscription(): void {\n if (this._unsubscribe) {\n this._unsubscribe();\n this._unsubscribe = null;\n }\n }\n\n private _handleMetaEvent = (event: MetaTrackEvent): void => {\n if (event.type !== \"subtitle\") {\n return;\n }\n\n const cue = this._parseSubtitleCue(event.data);\n if (!cue) {\n return;\n }\n\n this._liveCues = (() => {\n const existing = this._liveCues.find((value) => value.id === cue.id);\n if (existing) {\n return this._liveCues;\n }\n return [...this._liveCues, cue].slice(-50);\n })();\n };\n\n private _parseSubtitleCue(data: unknown): SubtitleCue | null {\n if (typeof data !== \"object\" || data === null) {\n return null;\n }\n\n const obj = data as Record<string, unknown>;\n const text = typeof obj.text === \"string\" ? obj.text : String(obj.text ?? \"\");\n if (!text) {\n return null;\n }\n\n const rawStart =\n \"startTime\" in obj ? Number(obj.startTime) : \"start\" in obj ? Number(obj.start) : 0;\n const rawEnd =\n \"endTime\" in obj ? Number(obj.endTime) : \"end\" in obj ? Number(obj.end) : Infinity;\n const startTime = Number.isFinite(rawStart) ? rawStart : 0;\n const endTime = Number.isFinite(rawEnd) ? rawEnd : Infinity;\n const id = typeof obj.id === \"string\" ? obj.id : String(Date.now() + Math.random());\n\n return {\n id,\n text,\n startTime,\n endTime,\n lang: typeof obj.lang === \"string\" ? obj.lang : undefined,\n };\n }\n\n private _getAllCues(): SubtitleCue[] {\n return [...(this.cues ?? []), ...this._liveCues];\n }\n\n private _syncDisplayedCue(): void {\n if (!this.enabled) {\n if (this._displayedText) {\n this._displayedText = \"\";\n }\n return;\n }\n\n const currentTimeMs = this.currentTime * 1000;\n const activeCue = this._getAllCues().find(\n (cue) => currentTimeMs >= cue.startTime && currentTimeMs < cue.endTime\n );\n const nextText = activeCue?.text ?? \"\";\n\n if (nextText !== this._displayedText) {\n this._displayedText = nextText;\n }\n }\n\n private _pruneExpiredLiveCues(): void {\n if (this._liveCues.length === 0) {\n return;\n }\n\n const currentTimeMs = this.currentTime * 1000;\n const filtered = this._liveCues.filter((cue) => {\n const endTime = cue.endTime === Infinity ? cue.startTime + 10000 : cue.endTime;\n return endTime >= currentTimeMs - 30000;\n });\n\n if (filtered.length !== this._liveCues.length) {\n this._liveCues = filtered;\n }\n }\n\n protected render() {\n if (!this.enabled || !this._displayedText) {\n return nothing;\n }\n\n const mergedStyle: Required<SubtitleStyle> = {\n ...DEFAULT_STYLE,\n ...(this.subtitleStyle ?? {}),\n };\n\n return html`\n <div\n class=\"subtitle-container ${this.className}\"\n style=${styleMap({\n bottom: mergedStyle.bottom,\n maxWidth: mergedStyle.maxWidth,\n })}\n role=\"region\"\n aria-live=\"polite\"\n aria-label=\"Subtitles\"\n >\n <span\n class=\"subtitle-text\"\n style=${styleMap({\n fontSize: mergedStyle.fontSize,\n fontFamily: mergedStyle.fontFamily,\n color: mergedStyle.color,\n backgroundColor: mergedStyle.backgroundColor,\n textShadow: mergedStyle.textShadow,\n padding: mergedStyle.padding,\n borderRadius: mergedStyle.borderRadius,\n })}\n >\n ${this._displayedText}\n </span>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-subtitle-renderer\": FwSubtitleRenderer;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fw-subtitle-renderer.js","sources":["../../../../src/components/fw-subtitle-renderer.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\n\ninterface SubtitleCue {\n id?: string;\n text: string;\n startTime: number;\n endTime: number;\n lang?: string;\n}\n\ninterface MetaTrackEvent {\n type: string;\n data: unknown;\n}\n\ninterface SubtitleStyle {\n fontSize?: string;\n fontFamily?: string;\n color?: string;\n backgroundColor?: string;\n textShadow?: string;\n bottom?: string;\n maxWidth?: string;\n padding?: string;\n borderRadius?: string;\n}\n\nconst DEFAULT_STYLE: Required<SubtitleStyle> = {\n fontSize: \"1.5rem\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n color: \"white\",\n backgroundColor: \"rgba(0, 0, 0, 0.75)\",\n textShadow: \"2px 2px 4px rgba(0, 0, 0, 0.5)\",\n bottom: \"5%\",\n maxWidth: \"90%\",\n padding: \"0.5em 1em\",\n borderRadius: \"4px\",\n};\n\n@customElement(\"fw-subtitle-renderer\")\nexport class FwSubtitleRenderer extends LitElement {\n @property({ type: Number }) currentTime = 0;\n @property({ type: Boolean }) enabled = true;\n @property({ attribute: false }) cues: SubtitleCue[] = [];\n @property({ attribute: false })\n subscribeToMetaTrack?: (trackId: string, callback: (event: MetaTrackEvent) => void) => () => void;\n @property({ type: String, attribute: \"meta-track-id\" }) metaTrackId?: string;\n @property({ attribute: false }) subtitleStyle?: SubtitleStyle;\n @property({ type: String, attribute: \"class-name\" }) className = \"\";\n\n @state() private _liveCues: SubtitleCue[] = [];\n @state() private _displayedText = \"\";\n\n private _unsubscribe: (() => void) | null = null;\n\n static styles = css`\n :host {\n display: contents;\n }\n\n .subtitle-container {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n z-index: 30;\n text-align: center;\n pointer-events: none;\n }\n\n .subtitle-text {\n display: inline-block;\n white-space: pre-wrap;\n }\n `;\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardownSubscription();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n if (\n changed.has(\"enabled\") ||\n changed.has(\"subscribeToMetaTrack\") ||\n changed.has(\"metaTrackId\")\n ) {\n this._syncSubscription();\n }\n\n if (changed.has(\"currentTime\") || changed.has(\"_liveCues\")) {\n this._pruneExpiredLiveCues();\n }\n\n if (\n changed.has(\"enabled\") ||\n changed.has(\"currentTime\") ||\n changed.has(\"cues\") ||\n changed.has(\"_liveCues\")\n ) {\n this._syncDisplayedCue();\n }\n }\n\n private _syncSubscription(): void {\n this._teardownSubscription();\n\n if (!this.enabled || !this.subscribeToMetaTrack || !this.metaTrackId) {\n return;\n }\n\n this._unsubscribe = this.subscribeToMetaTrack(this.metaTrackId, this._handleMetaEvent);\n }\n\n private _teardownSubscription(): void {\n if (this._unsubscribe) {\n this._unsubscribe();\n this._unsubscribe = null;\n }\n }\n\n private _handleMetaEvent = (event: MetaTrackEvent): void => {\n if (event.type !== \"subtitle\") {\n return;\n }\n\n const cue = this._parseSubtitleCue(event.data);\n if (!cue) {\n return;\n }\n\n this._liveCues = (() => {\n const existing = this._liveCues.find((value) => value.id === cue.id);\n if (existing) {\n return this._liveCues;\n }\n return [...this._liveCues, cue].slice(-50);\n })();\n };\n\n private _parseSubtitleCue(data: unknown): SubtitleCue | null {\n if (typeof data !== \"object\" || data === null) {\n return null;\n }\n\n const obj = data as Record<string, unknown>;\n const text = typeof obj.text === \"string\" ? obj.text : String(obj.text ?? \"\");\n if (!text) {\n return null;\n }\n\n const rawStart =\n \"startTime\" in obj ? Number(obj.startTime) : \"start\" in obj ? Number(obj.start) : 0;\n const rawEnd =\n \"endTime\" in obj ? Number(obj.endTime) : \"end\" in obj ? Number(obj.end) : Infinity;\n const startTime = Number.isFinite(rawStart) ? rawStart : 0;\n const endTime = Number.isFinite(rawEnd) ? rawEnd : Infinity;\n const id = typeof obj.id === \"string\" ? obj.id : String(Date.now() + Math.random());\n\n return {\n id,\n text,\n startTime,\n endTime,\n lang: typeof obj.lang === \"string\" ? obj.lang : undefined,\n };\n }\n\n private _getAllCues(): SubtitleCue[] {\n return [...(this.cues ?? []), ...this._liveCues];\n }\n\n private _syncDisplayedCue(): void {\n if (!this.enabled) {\n if (this._displayedText) {\n this._displayedText = \"\";\n }\n return;\n }\n\n const currentTimeMs = this.currentTime;\n const activeCue = this._getAllCues().find(\n (cue) => currentTimeMs >= cue.startTime && currentTimeMs < cue.endTime\n );\n const nextText = activeCue?.text ?? \"\";\n\n if (nextText !== this._displayedText) {\n this._displayedText = nextText;\n }\n }\n\n private _pruneExpiredLiveCues(): void {\n if (this._liveCues.length === 0) {\n return;\n }\n\n const currentTimeMs = this.currentTime;\n const filtered = this._liveCues.filter((cue) => {\n const endTime = cue.endTime === Infinity ? cue.startTime + 10000 : cue.endTime;\n return endTime >= currentTimeMs - 30000;\n });\n\n if (filtered.length !== this._liveCues.length) {\n this._liveCues = filtered;\n }\n }\n\n protected render() {\n if (!this.enabled || !this._displayedText) {\n return nothing;\n }\n\n const mergedStyle: Required<SubtitleStyle> = {\n ...DEFAULT_STYLE,\n ...(this.subtitleStyle ?? {}),\n };\n\n return html`\n <div\n class=\"subtitle-container ${this.className}\"\n style=${styleMap({\n bottom: mergedStyle.bottom,\n maxWidth: mergedStyle.maxWidth,\n })}\n role=\"region\"\n aria-live=\"polite\"\n aria-label=\"Subtitles\"\n >\n <span\n class=\"subtitle-text\"\n style=${styleMap({\n fontSize: mergedStyle.fontSize,\n fontFamily: mergedStyle.fontFamily,\n color: mergedStyle.color,\n backgroundColor: mergedStyle.backgroundColor,\n textShadow: mergedStyle.textShadow,\n padding: mergedStyle.padding,\n borderRadius: mergedStyle.borderRadius,\n })}\n >\n ${this._displayedText}\n </span>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-subtitle-renderer\": FwSubtitleRenderer;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, nothing, html } from 'lit';
3
3
  import { property, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, nothing, html } from 'lit';
3
3
  import { property, customElement } from 'lit/decorators.js';
4
4
  import { sharedStyles } from '../styles/shared-styles.js';
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, nothing, html } from 'lit';
3
3
  import { property, customElement } from 'lit/decorators.js';
4
4
  import { closeIcon } from '../icons/index.js';
@@ -1,4 +1,4 @@
1
- import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.57.1_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
1
+ import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.59.0_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js';
2
2
  import { css, LitElement, html } from 'lit';
3
3
  import { property, state, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
@@ -15,6 +15,8 @@ let FwVolumeControl = class FwVolumeControl extends LitElement {
15
15
  this._hasAudio = true;
16
16
  this._activePointerId = null;
17
17
  this._activeSliderTarget = null;
18
+ this._boundStream = null;
19
+ this._onStreamTrackChange = null;
18
20
  this._onGlobalPointerMove = (event) => {
19
21
  if (!this._dragging || this._activePointerId !== event.pointerId) {
20
22
  return;
@@ -82,24 +84,46 @@ let FwVolumeControl = class FwVolumeControl extends LitElement {
82
84
  disconnectedCallback() {
83
85
  super.disconnectedCallback();
84
86
  this._endDragInteraction();
87
+ this._unbindStreamListeners();
85
88
  }
86
89
  updated() {
87
90
  this._updateHasAudio();
88
91
  }
89
- _updateHasAudio() {
90
- // Primary: trust MistServer stream metadata (matches ddvtech embed approach)
91
- const mistHasAudio = this.pc?.s.streamState?.streamInfo?.hasAudio;
92
- if (mistHasAudio !== undefined) {
93
- this._hasAudio = mistHasAudio;
94
- return;
92
+ _unbindStreamListeners() {
93
+ if (this._boundStream && this._onStreamTrackChange) {
94
+ this._boundStream.removeEventListener("addtrack", this._onStreamTrackChange);
95
+ this._boundStream.removeEventListener("removetrack", this._onStreamTrackChange);
95
96
  }
97
+ this._boundStream = null;
98
+ this._onStreamTrackChange = null;
99
+ }
100
+ _updateHasAudio() {
96
101
  const video = this.pc?.s.videoElement;
97
102
  if (!video) {
103
+ this._unbindStreamListeners();
98
104
  this._hasAudio = true;
99
105
  return;
100
106
  }
107
+ // MediaStream: bind track change listeners (WebRTC tracks arrive async)
101
108
  if (video.srcObject instanceof MediaStream) {
102
- this._hasAudio = video.srcObject.getAudioTracks().length > 0;
109
+ const stream = video.srcObject;
110
+ if (stream !== this._boundStream) {
111
+ this._unbindStreamListeners();
112
+ this._boundStream = stream;
113
+ this._onStreamTrackChange = () => {
114
+ this._hasAudio = stream.getAudioTracks().length > 0;
115
+ };
116
+ stream.addEventListener("addtrack", this._onStreamTrackChange);
117
+ stream.addEventListener("removetrack", this._onStreamTrackChange);
118
+ }
119
+ this._hasAudio = stream.getAudioTracks().length > 0;
120
+ return;
121
+ }
122
+ this._unbindStreamListeners();
123
+ // Fallback: metadata for non-MediaStream sources.
124
+ const mistHasAudio = this.pc?.s.streamState?.streamInfo?.hasAudio;
125
+ if (mistHasAudio !== undefined) {
126
+ this._hasAudio = mistHasAudio;
103
127
  return;
104
128
  }
105
129
  const maybeWithTracks = video;