@livepeer-frameworks/player-wc 0.2.9 → 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 (37) hide show
  1. package/dist/esm/components/controls/fw-fullscreen-button.js +1 -1
  2. package/dist/esm/components/controls/fw-live-badge.js +1 -1
  3. package/dist/esm/components/controls/fw-play-button.js +1 -1
  4. package/dist/esm/components/controls/fw-skip-button.js +1 -1
  5. package/dist/esm/components/controls/fw-time-display.js +1 -1
  6. package/dist/esm/components/controls/fw-volume-control.js +1 -1
  7. package/dist/esm/components/fw-context-menu.js +1 -1
  8. package/dist/esm/components/fw-dev-mode-panel.js +1 -1
  9. package/dist/esm/components/fw-dvd-logo.js +1 -1
  10. package/dist/esm/components/fw-error-overlay.js +1 -1
  11. package/dist/esm/components/fw-idle-screen.js +1 -1
  12. package/dist/esm/components/fw-loading-screen.js +1 -1
  13. package/dist/esm/components/fw-loading-spinner.js +1 -1
  14. package/dist/esm/components/fw-player-controls.js +2 -6
  15. package/dist/esm/components/fw-player-controls.js.map +1 -1
  16. package/dist/esm/components/fw-player.js +1 -1
  17. package/dist/esm/components/fw-seek-bar.js +1 -1
  18. package/dist/esm/components/fw-settings-menu.js +3 -3
  19. package/dist/esm/components/fw-settings-menu.js.map +1 -1
  20. package/dist/esm/components/fw-skip-indicator.js +1 -1
  21. package/dist/esm/components/fw-speed-indicator.js +1 -1
  22. package/dist/esm/components/fw-stats-panel.js +1 -1
  23. package/dist/esm/components/fw-stream-state-overlay.js +1 -1
  24. package/dist/esm/components/fw-subtitle-renderer.js +1 -1
  25. package/dist/esm/components/fw-thumbnail-overlay.js +1 -1
  26. package/dist/esm/components/fw-title-overlay.js +1 -1
  27. package/dist/esm/components/fw-toast.js +1 -1
  28. package/dist/esm/components/fw-volume-control.js +32 -8
  29. package/dist/esm/components/fw-volume-control.js.map +1 -1
  30. 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
  31. package/dist/fw-player.iife.js +79 -79
  32. package/dist/types/components/fw-volume-control.d.ts +3 -0
  33. package/package.json +3 -3
  34. package/src/components/fw-player-controls.ts +1 -5
  35. package/src/components/fw-settings-menu.ts +2 -1
  36. package/src/components/fw-volume-control.ts +33 -7
  37. /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, html } from 'lit';
3
3
  import { state, 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, html } from 'lit';
3
3
  import { state, 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, html } from 'lit';
3
3
  import { state, 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, html } 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, html } from 'lit';
3
3
  import { state, customElement } from 'lit/decorators.js';
4
4
  import { formatTimeDisplay } 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, html } from 'lit';
3
3
  import { state, 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 } from 'lit';
3
3
  import { 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, nothing, html } 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, state, 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 { 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, nothing } from 'lit';
3
3
  import { property, query, state, 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 } from 'lit';
3
3
  import { property, query, state, 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 } 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, query, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
@@ -132,11 +132,7 @@ let FwPlayerControls = class FwPlayerControls extends LitElement {
132
132
  const bufferWindowMs = mistStreamInfo?.meta?.buffer_window ??
133
133
  this._deriveBufferWindowMs(mistStreamInfo?.meta?.tracks);
134
134
  const isWebRTC = isMediaStreamSource(state.videoElement);
135
- const allowMediaStreamDvr = isMediaStreamSource(state.videoElement) &&
136
- bufferWindowMs !== undefined &&
137
- bufferWindowMs > 0 &&
138
- sourceType !== "whep" &&
139
- sourceType !== "webrtc";
135
+ const allowMediaStreamDvr = isMediaStreamSource(state.videoElement) && bufferWindowMs !== undefined && bufferWindowMs > 0;
140
136
  const calculatedRange = calculateSeekableRange({
141
137
  isLive,
142
138
  video: state.videoElement,
@@ -1 +1 @@
1
- {"version":3,"file":"fw-player-controls.js","sources":["../../../../src/components/fw-player-controls.ts"],"sourcesContent":["/**\n * <fw-player-controls> — Player controls with seek, volume, live state, and settings.\n * Parity port of React/Svelte control behavior.\n */\nimport { LitElement, html, css, nothing, type PropertyValues } from \"lit\";\nimport { customElement, property, query, 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 playIcon,\n pauseIcon,\n fullscreenIcon,\n fullscreenExitIcon,\n settingsIcon,\n seekToLiveIcon,\n skipBackIcon,\n skipForwardIcon,\n statsIcon,\n} from \"../icons/index.js\";\nimport {\n calculateIsNearLive,\n calculateLiveThresholds,\n calculateSeekableRange,\n canSeekStream,\n formatTimeDisplay,\n isLiveContent,\n isMediaStreamSource,\n type MistStreamInfo,\n type PlaybackMode,\n type FwLocale,\n} from \"@livepeer-frameworks/player-core\";\nimport type { PlayerControllerHost } from \"../controllers/player-controller-host.js\";\n\ninterface SeekingContext {\n mistStreamInfo?: MistStreamInfo;\n isLive: boolean;\n sourceType?: string;\n seekableStart: number;\n liveEdge: number;\n hasDvrWindow: boolean;\n canSeek: boolean;\n commitOnRelease: boolean;\n liveThresholds: ReturnType<typeof calculateLiveThresholds>;\n}\n\n@customElement(\"fw-player-controls\")\nexport class FwPlayerControls extends LitElement {\n @property({ attribute: false }) pc!: PlayerControllerHost;\n @property({ type: String }) playbackMode: PlaybackMode = \"auto\";\n @property({ type: Boolean, attribute: \"is-content-live\" }) isContentLive = false;\n @property({ type: Boolean, attribute: \"dev-mode\" }) devMode = false;\n @property({ type: Boolean, attribute: \"show-stats-button\" }) showStatsButton = false;\n @property({ type: Boolean, attribute: \"is-stats-open\" }) isStatsOpen = false;\n @property({ attribute: \"active-locale\" }) activeLocale?: FwLocale;\n\n @state() private _settingsOpen = false;\n @state() private _isNearLiveState = true;\n @state() private _buffered: TimeRanges | null = null;\n @query(\".fw-settings-anchor\") private _settingsAnchorEl!: HTMLElement | null;\n\n private _boundVideo: HTMLVideoElement | null = null;\n private _onBufferedUpdate: (() => void) | null = null;\n\n static styles = [\n sharedStyles,\n utilityStyles,\n css`\n :host {\n display: contents;\n }\n\n .fw-settings-anchor {\n position: relative;\n }\n `,\n ];\n\n connectedCallback(): void {\n super.connectedCallback();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._unbindVideoEvents();\n this._detachWindowClickListener();\n }\n\n protected updated(changed: PropertyValues<this>): void {\n this._bindVideoEvents();\n this._reconcileNearLiveState();\n\n if (changed.has(\"_settingsOpen\" as keyof FwPlayerControls)) {\n if (this._settingsOpen) {\n this._attachWindowClickListener();\n } else {\n this._detachWindowClickListener();\n }\n }\n }\n\n private _bindVideoEvents(): void {\n const video = this.pc?.s.videoElement ?? null;\n if (video === this._boundVideo) {\n return;\n }\n\n this._unbindVideoEvents();\n this._boundVideo = video;\n\n if (!video) {\n this._buffered = null;\n return;\n }\n\n const updateBuffered = () => {\n this._buffered = this.pc.getBufferedRanges() ?? video.buffered;\n };\n\n updateBuffered();\n video.addEventListener(\"progress\", updateBuffered);\n video.addEventListener(\"loadeddata\", updateBuffered);\n this._onBufferedUpdate = updateBuffered;\n }\n\n private _unbindVideoEvents(): void {\n if (!this._boundVideo) {\n return;\n }\n\n const updateBuffered = this._onBufferedUpdate;\n if (updateBuffered) {\n this._boundVideo.removeEventListener(\"progress\", updateBuffered);\n this._boundVideo.removeEventListener(\"loadeddata\", updateBuffered);\n }\n\n this._boundVideo = null;\n this._onBufferedUpdate = null;\n }\n\n private _attachWindowClickListener(): void {\n window.setTimeout(() => {\n if (!this._settingsOpen) {\n return;\n }\n window.addEventListener(\"click\", this._onWindowClick);\n }, 0);\n }\n\n private _detachWindowClickListener(): void {\n window.removeEventListener(\"click\", this._onWindowClick);\n }\n\n private _onWindowClick = (event: MouseEvent): void => {\n const path = event.composedPath();\n const anchor = this._settingsAnchorEl;\n const insideControls =\n anchor !== null &&\n path.some((entry) => {\n if (!(entry instanceof Node)) {\n return false;\n }\n return anchor.contains(entry);\n });\n\n if (!insideControls) {\n this._settingsOpen = false;\n }\n };\n\n private _deriveBufferWindowMs(\n tracks?: Record<string, { type?: string; firstms?: number; lastms?: number }>\n ): number | undefined {\n if (!tracks) {\n return undefined;\n }\n\n // Filter out meta tracks and tracks with lastms <= 0 (same as PlayerController)\n const trackValues = Object.values(tracks).filter(\n (t) => t.type !== \"meta\" && (t.lastms === undefined || t.lastms > 0)\n );\n if (trackValues.length === 0) {\n return undefined;\n }\n\n const firstmsValues = trackValues\n .map((track) => track.firstms)\n .filter((value): value is number => typeof value === \"number\");\n const lastmsValues = trackValues\n .map((track) => track.lastms)\n .filter((value): value is number => typeof value === \"number\");\n\n if (firstmsValues.length === 0 || lastmsValues.length === 0) {\n return undefined;\n }\n\n const firstms = Math.min(...firstmsValues);\n const lastms = Math.max(...lastmsValues);\n const window = lastms - firstms;\n\n if (!Number.isFinite(window) || window <= 0) {\n return undefined;\n }\n\n return window;\n }\n\n private _getSeekingContext(): SeekingContext {\n const state = this.pc.s;\n const controller = this.pc.getController();\n const sourceType = state.currentSourceInfo?.type;\n const mistStreamInfo = state.streamState?.streamInfo as MistStreamInfo | undefined;\n\n const isLive = isLiveContent(this.isContentLive, mistStreamInfo, state.duration);\n const bufferWindowMs =\n mistStreamInfo?.meta?.buffer_window ??\n this._deriveBufferWindowMs(\n mistStreamInfo?.meta?.tracks as\n | Record<string, { type?: string; firstms?: number; lastms?: number }>\n | undefined\n );\n\n const isWebRTC = isMediaStreamSource(state.videoElement);\n\n const allowMediaStreamDvr =\n isMediaStreamSource(state.videoElement) &&\n bufferWindowMs !== undefined &&\n bufferWindowMs > 0 &&\n sourceType !== \"whep\" &&\n sourceType !== \"webrtc\";\n\n const calculatedRange = calculateSeekableRange({\n isLive,\n video: state.videoElement,\n mistStreamInfo,\n currentTime: state.currentTime,\n duration: state.duration,\n allowMediaStreamDvr,\n });\n\n const controllerSeekableStart = this.pc.getSeekableStart();\n const controllerLiveEdge = this.pc.getLiveEdge();\n\n const useControllerRange =\n Number.isFinite(controllerSeekableStart) &&\n Number.isFinite(controllerLiveEdge) &&\n controllerLiveEdge >= controllerSeekableStart &&\n (controllerLiveEdge > 0 || controllerSeekableStart > 0);\n\n const seekableStart = useControllerRange\n ? controllerSeekableStart\n : calculatedRange.seekableStart;\n const liveEdge = useControllerRange ? controllerLiveEdge : calculatedRange.liveEdge;\n\n const hasDvrWindow =\n isLive &&\n Number.isFinite(liveEdge) &&\n Number.isFinite(seekableStart) &&\n liveEdge > seekableStart;\n\n const baseCanSeek =\n controller?.canSeekStream?.() ??\n canSeekStream({\n video: state.videoElement,\n isLive,\n duration: state.duration,\n bufferWindowMs,\n });\n\n const liveThresholds = calculateLiveThresholds(sourceType, isWebRTC, bufferWindowMs);\n\n return {\n mistStreamInfo,\n isLive,\n sourceType,\n seekableStart,\n liveEdge,\n hasDvrWindow,\n canSeek: baseCanSeek && (!isLive || hasDvrWindow),\n commitOnRelease: isLive,\n liveThresholds,\n };\n }\n\n private _reconcileNearLiveState(): void {\n const context = this._getSeekingContext();\n\n if (!context.isLive) {\n if (!this._isNearLiveState) {\n this._isNearLiveState = true;\n }\n return;\n }\n\n const next = calculateIsNearLive(\n this.pc.s.currentTime,\n context.liveEdge,\n context.liveThresholds,\n this._isNearLiveState\n );\n\n if (next !== this._isNearLiveState) {\n this._isNearLiveState = next;\n }\n }\n\n private _handleModeChange(\n event: CustomEvent<{ mode: \"auto\" | \"low-latency\" | \"quality\" }>\n ): void {\n const { mode } = event.detail;\n this.dispatchEvent(\n new CustomEvent(\"fw-mode-change\", {\n detail: { mode },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n protected render() {\n const state = this.pc.s;\n const disabled = !state.videoElement;\n const context = this._getSeekingContext();\n const shouldShowControls =\n state.shouldShowControls ||\n state.isPaused ||\n !state.hasPlaybackStarted ||\n state.shouldShowIdleScreen ||\n !!state.error ||\n this._settingsOpen;\n\n const timeDisplay = formatTimeDisplay({\n isLive: context.isLive,\n currentTime: state.currentTime,\n duration: state.duration,\n liveEdge: context.liveEdge,\n seekableStart: context.seekableStart,\n unixoffset: context.mistStreamInfo?.unixoffset,\n });\n const showTimeDisplay = !(context.isLive && timeDisplay === \"LIVE\");\n\n const liveButtonDisabled = !context.hasDvrWindow || this._isNearLiveState;\n\n return html`\n <div\n class=${classMap({\n \"fw-controls-wrapper\": true,\n \"fw-controls-wrapper--visible\": shouldShowControls,\n \"fw-controls-wrapper--hidden\": !shouldShowControls,\n })}\n >\n <div class=\"fw-control-bar\" @click=${(event: Event) => event.stopPropagation()}>\n ${context.canSeek\n ? html`\n <div class=\"fw-seek-wrapper\">\n <fw-seek-bar\n .currentTime=${state.currentTime}\n .duration=${state.duration}\n .buffered=${this._buffered}\n .disabled=${disabled}\n .isLive=${context.isLive}\n .seekableStart=${context.seekableStart}\n .liveEdge=${context.liveEdge}\n .commitOnRelease=${context.commitOnRelease}\n @fw-seek=${(event: CustomEvent<{ time: number }>) =>\n this.pc.seek(event.detail.time)}\n ></fw-seek-bar>\n </div>\n `\n : nothing}\n\n <div class=\"fw-controls-row\">\n <div class=\"fw-controls-left\">\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n class=\"fw-btn-flush\"\n ?disabled=${disabled}\n aria-label=${state.isPlaying ? this.pc.t(\"pause\") : this.pc.t(\"play\")}\n @click=${() => this.pc.togglePlay()}\n >\n ${state.isPlaying ? pauseIcon(18) : playIcon(18)}\n </button>\n\n ${context.canSeek\n ? html`\n <button\n type=\"button\"\n class=\"fw-btn-flush hidden sm:flex\"\n ?disabled=${disabled}\n aria-label=${this.pc.t(\"skipBackward\")}\n @click=${() => this.pc.seekBy(-10000)}\n >\n ${skipBackIcon(16)}\n </button>\n <button\n type=\"button\"\n class=\"fw-btn-flush hidden sm:flex\"\n ?disabled=${disabled}\n aria-label=${this.pc.t(\"skipForward\")}\n @click=${() => this.pc.seekBy(10000)}\n >\n ${skipForwardIcon(16)}\n </button>\n `\n : nothing}\n </div>\n\n <div class=\"fw-control-group\">\n <fw-volume-control .pc=${this.pc}></fw-volume-control>\n </div>\n\n ${showTimeDisplay\n ? html`\n <div class=\"fw-control-group\">\n <span class=\"fw-time-display\">${timeDisplay}</span>\n </div>\n `\n : nothing}\n ${context.isLive\n ? html`\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n @click=${() => this.pc.jumpToLive()}\n ?disabled=${liveButtonDisabled}\n class=${classMap({\n \"fw-live-badge\": true,\n \"fw-live-badge--active\": liveButtonDisabled,\n \"fw-live-badge--behind\": !liveButtonDisabled,\n })}\n title=${!context.hasDvrWindow\n ? this.pc.t(\"live\")\n : this._isNearLiveState\n ? this.pc.t(\"live\")\n : this.pc.t(\"live\")}\n >\n ${this.pc.t(\"live\").toUpperCase()}\n ${!this._isNearLiveState && context.hasDvrWindow\n ? seekToLiveIcon(10)\n : nothing}\n </button>\n </div>\n `\n : nothing}\n </div>\n\n <div class=\"fw-controls-right\">\n ${this.showStatsButton\n ? html`\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-btn-flush\": true,\n \"fw-btn-flush--active\": this.isStatsOpen,\n })}\n aria-label=${this.pc.t(\"showStats\")}\n title=${this.pc.t(\"showStats\")}\n @click=${() =>\n this.dispatchEvent(\n new CustomEvent(\"fw-stats-toggle\", {\n bubbles: true,\n composed: true,\n })\n )}\n >\n ${statsIcon(16)}\n </button>\n </div>\n `\n : nothing}\n <div class=\"fw-control-group fw-settings-anchor\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-btn-flush\": true,\n group: true,\n \"fw-btn-flush--active\": this._settingsOpen,\n })}\n aria-label=${this.pc.t(\"settings\")}\n title=${this.pc.t(\"settings\")}\n ?disabled=${disabled}\n @click=${(event: MouseEvent) => {\n event.stopPropagation();\n if (disabled) {\n return;\n }\n this._settingsOpen = !this._settingsOpen;\n }}\n >\n <span class=\"transition-transform group-hover:rotate-90\"\n >${settingsIcon(16)}</span\n >\n </button>\n\n <fw-settings-menu\n .pc=${this.pc}\n .open=${this._settingsOpen}\n .playbackMode=${this.playbackMode}\n .isContentLive=${this.isContentLive}\n .activeLocale=${this.activeLocale}\n @click=${(event: MouseEvent) => event.stopPropagation()}\n @fw-close=${() => {\n this._settingsOpen = false;\n }}\n @fw-mode-change=${this._handleModeChange}\n ></fw-settings-menu>\n </div>\n\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n class=\"fw-btn-flush\"\n ?disabled=${disabled}\n aria-label=${state.isFullscreen\n ? this.pc.t(\"exitFullscreen\")\n : this.pc.t(\"fullscreen\")}\n @click=${() => this.pc.toggleFullscreen()}\n >\n ${state.isFullscreen ? fullscreenExitIcon(16) : fullscreenIcon(16)}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-player-controls\": FwPlayerControls;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fw-player-controls.js","sources":["../../../../src/components/fw-player-controls.ts"],"sourcesContent":["/**\n * <fw-player-controls> — Player controls with seek, volume, live state, and settings.\n * Parity port of React/Svelte control behavior.\n */\nimport { LitElement, html, css, nothing, type PropertyValues } from \"lit\";\nimport { customElement, property, query, 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 playIcon,\n pauseIcon,\n fullscreenIcon,\n fullscreenExitIcon,\n settingsIcon,\n seekToLiveIcon,\n skipBackIcon,\n skipForwardIcon,\n statsIcon,\n} from \"../icons/index.js\";\nimport {\n calculateIsNearLive,\n calculateLiveThresholds,\n calculateSeekableRange,\n canSeekStream,\n formatTimeDisplay,\n isLiveContent,\n isMediaStreamSource,\n type MistStreamInfo,\n type PlaybackMode,\n type FwLocale,\n} from \"@livepeer-frameworks/player-core\";\nimport type { PlayerControllerHost } from \"../controllers/player-controller-host.js\";\n\ninterface SeekingContext {\n mistStreamInfo?: MistStreamInfo;\n isLive: boolean;\n sourceType?: string;\n seekableStart: number;\n liveEdge: number;\n hasDvrWindow: boolean;\n canSeek: boolean;\n commitOnRelease: boolean;\n liveThresholds: ReturnType<typeof calculateLiveThresholds>;\n}\n\n@customElement(\"fw-player-controls\")\nexport class FwPlayerControls extends LitElement {\n @property({ attribute: false }) pc!: PlayerControllerHost;\n @property({ type: String }) playbackMode: PlaybackMode = \"auto\";\n @property({ type: Boolean, attribute: \"is-content-live\" }) isContentLive = false;\n @property({ type: Boolean, attribute: \"dev-mode\" }) devMode = false;\n @property({ type: Boolean, attribute: \"show-stats-button\" }) showStatsButton = false;\n @property({ type: Boolean, attribute: \"is-stats-open\" }) isStatsOpen = false;\n @property({ attribute: \"active-locale\" }) activeLocale?: FwLocale;\n\n @state() private _settingsOpen = false;\n @state() private _isNearLiveState = true;\n @state() private _buffered: TimeRanges | null = null;\n @query(\".fw-settings-anchor\") private _settingsAnchorEl!: HTMLElement | null;\n\n private _boundVideo: HTMLVideoElement | null = null;\n private _onBufferedUpdate: (() => void) | null = null;\n\n static styles = [\n sharedStyles,\n utilityStyles,\n css`\n :host {\n display: contents;\n }\n\n .fw-settings-anchor {\n position: relative;\n }\n `,\n ];\n\n connectedCallback(): void {\n super.connectedCallback();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._unbindVideoEvents();\n this._detachWindowClickListener();\n }\n\n protected updated(changed: PropertyValues<this>): void {\n this._bindVideoEvents();\n this._reconcileNearLiveState();\n\n if (changed.has(\"_settingsOpen\" as keyof FwPlayerControls)) {\n if (this._settingsOpen) {\n this._attachWindowClickListener();\n } else {\n this._detachWindowClickListener();\n }\n }\n }\n\n private _bindVideoEvents(): void {\n const video = this.pc?.s.videoElement ?? null;\n if (video === this._boundVideo) {\n return;\n }\n\n this._unbindVideoEvents();\n this._boundVideo = video;\n\n if (!video) {\n this._buffered = null;\n return;\n }\n\n const updateBuffered = () => {\n this._buffered = this.pc.getBufferedRanges() ?? video.buffered;\n };\n\n updateBuffered();\n video.addEventListener(\"progress\", updateBuffered);\n video.addEventListener(\"loadeddata\", updateBuffered);\n this._onBufferedUpdate = updateBuffered;\n }\n\n private _unbindVideoEvents(): void {\n if (!this._boundVideo) {\n return;\n }\n\n const updateBuffered = this._onBufferedUpdate;\n if (updateBuffered) {\n this._boundVideo.removeEventListener(\"progress\", updateBuffered);\n this._boundVideo.removeEventListener(\"loadeddata\", updateBuffered);\n }\n\n this._boundVideo = null;\n this._onBufferedUpdate = null;\n }\n\n private _attachWindowClickListener(): void {\n window.setTimeout(() => {\n if (!this._settingsOpen) {\n return;\n }\n window.addEventListener(\"click\", this._onWindowClick);\n }, 0);\n }\n\n private _detachWindowClickListener(): void {\n window.removeEventListener(\"click\", this._onWindowClick);\n }\n\n private _onWindowClick = (event: MouseEvent): void => {\n const path = event.composedPath();\n const anchor = this._settingsAnchorEl;\n const insideControls =\n anchor !== null &&\n path.some((entry) => {\n if (!(entry instanceof Node)) {\n return false;\n }\n return anchor.contains(entry);\n });\n\n if (!insideControls) {\n this._settingsOpen = false;\n }\n };\n\n private _deriveBufferWindowMs(\n tracks?: Record<string, { type?: string; firstms?: number; lastms?: number }>\n ): number | undefined {\n if (!tracks) {\n return undefined;\n }\n\n // Filter out meta tracks and tracks with lastms <= 0 (same as PlayerController)\n const trackValues = Object.values(tracks).filter(\n (t) => t.type !== \"meta\" && (t.lastms === undefined || t.lastms > 0)\n );\n if (trackValues.length === 0) {\n return undefined;\n }\n\n const firstmsValues = trackValues\n .map((track) => track.firstms)\n .filter((value): value is number => typeof value === \"number\");\n const lastmsValues = trackValues\n .map((track) => track.lastms)\n .filter((value): value is number => typeof value === \"number\");\n\n if (firstmsValues.length === 0 || lastmsValues.length === 0) {\n return undefined;\n }\n\n const firstms = Math.min(...firstmsValues);\n const lastms = Math.max(...lastmsValues);\n const window = lastms - firstms;\n\n if (!Number.isFinite(window) || window <= 0) {\n return undefined;\n }\n\n return window;\n }\n\n private _getSeekingContext(): SeekingContext {\n const state = this.pc.s;\n const controller = this.pc.getController();\n const sourceType = state.currentSourceInfo?.type;\n const mistStreamInfo = state.streamState?.streamInfo as MistStreamInfo | undefined;\n\n const isLive = isLiveContent(this.isContentLive, mistStreamInfo, state.duration);\n const bufferWindowMs =\n mistStreamInfo?.meta?.buffer_window ??\n this._deriveBufferWindowMs(\n mistStreamInfo?.meta?.tracks as\n | Record<string, { type?: string; firstms?: number; lastms?: number }>\n | undefined\n );\n\n const isWebRTC = isMediaStreamSource(state.videoElement);\n\n const allowMediaStreamDvr =\n isMediaStreamSource(state.videoElement) && bufferWindowMs !== undefined && bufferWindowMs > 0;\n\n const calculatedRange = calculateSeekableRange({\n isLive,\n video: state.videoElement,\n mistStreamInfo,\n currentTime: state.currentTime,\n duration: state.duration,\n allowMediaStreamDvr,\n });\n\n const controllerSeekableStart = this.pc.getSeekableStart();\n const controllerLiveEdge = this.pc.getLiveEdge();\n\n const useControllerRange =\n Number.isFinite(controllerSeekableStart) &&\n Number.isFinite(controllerLiveEdge) &&\n controllerLiveEdge >= controllerSeekableStart &&\n (controllerLiveEdge > 0 || controllerSeekableStart > 0);\n\n const seekableStart = useControllerRange\n ? controllerSeekableStart\n : calculatedRange.seekableStart;\n const liveEdge = useControllerRange ? controllerLiveEdge : calculatedRange.liveEdge;\n\n const hasDvrWindow =\n isLive &&\n Number.isFinite(liveEdge) &&\n Number.isFinite(seekableStart) &&\n liveEdge > seekableStart;\n\n const baseCanSeek =\n controller?.canSeekStream?.() ??\n canSeekStream({\n video: state.videoElement,\n isLive,\n duration: state.duration,\n bufferWindowMs,\n });\n\n const liveThresholds = calculateLiveThresholds(sourceType, isWebRTC, bufferWindowMs);\n\n return {\n mistStreamInfo,\n isLive,\n sourceType,\n seekableStart,\n liveEdge,\n hasDvrWindow,\n canSeek: baseCanSeek && (!isLive || hasDvrWindow),\n commitOnRelease: isLive,\n liveThresholds,\n };\n }\n\n private _reconcileNearLiveState(): void {\n const context = this._getSeekingContext();\n\n if (!context.isLive) {\n if (!this._isNearLiveState) {\n this._isNearLiveState = true;\n }\n return;\n }\n\n const next = calculateIsNearLive(\n this.pc.s.currentTime,\n context.liveEdge,\n context.liveThresholds,\n this._isNearLiveState\n );\n\n if (next !== this._isNearLiveState) {\n this._isNearLiveState = next;\n }\n }\n\n private _handleModeChange(\n event: CustomEvent<{ mode: \"auto\" | \"low-latency\" | \"quality\" }>\n ): void {\n const { mode } = event.detail;\n this.dispatchEvent(\n new CustomEvent(\"fw-mode-change\", {\n detail: { mode },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n protected render() {\n const state = this.pc.s;\n const disabled = !state.videoElement;\n const context = this._getSeekingContext();\n const shouldShowControls =\n state.shouldShowControls ||\n state.isPaused ||\n !state.hasPlaybackStarted ||\n state.shouldShowIdleScreen ||\n !!state.error ||\n this._settingsOpen;\n\n const timeDisplay = formatTimeDisplay({\n isLive: context.isLive,\n currentTime: state.currentTime,\n duration: state.duration,\n liveEdge: context.liveEdge,\n seekableStart: context.seekableStart,\n unixoffset: context.mistStreamInfo?.unixoffset,\n });\n const showTimeDisplay = !(context.isLive && timeDisplay === \"LIVE\");\n\n const liveButtonDisabled = !context.hasDvrWindow || this._isNearLiveState;\n\n return html`\n <div\n class=${classMap({\n \"fw-controls-wrapper\": true,\n \"fw-controls-wrapper--visible\": shouldShowControls,\n \"fw-controls-wrapper--hidden\": !shouldShowControls,\n })}\n >\n <div class=\"fw-control-bar\" @click=${(event: Event) => event.stopPropagation()}>\n ${context.canSeek\n ? html`\n <div class=\"fw-seek-wrapper\">\n <fw-seek-bar\n .currentTime=${state.currentTime}\n .duration=${state.duration}\n .buffered=${this._buffered}\n .disabled=${disabled}\n .isLive=${context.isLive}\n .seekableStart=${context.seekableStart}\n .liveEdge=${context.liveEdge}\n .commitOnRelease=${context.commitOnRelease}\n @fw-seek=${(event: CustomEvent<{ time: number }>) =>\n this.pc.seek(event.detail.time)}\n ></fw-seek-bar>\n </div>\n `\n : nothing}\n\n <div class=\"fw-controls-row\">\n <div class=\"fw-controls-left\">\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n class=\"fw-btn-flush\"\n ?disabled=${disabled}\n aria-label=${state.isPlaying ? this.pc.t(\"pause\") : this.pc.t(\"play\")}\n @click=${() => this.pc.togglePlay()}\n >\n ${state.isPlaying ? pauseIcon(18) : playIcon(18)}\n </button>\n\n ${context.canSeek\n ? html`\n <button\n type=\"button\"\n class=\"fw-btn-flush hidden sm:flex\"\n ?disabled=${disabled}\n aria-label=${this.pc.t(\"skipBackward\")}\n @click=${() => this.pc.seekBy(-10000)}\n >\n ${skipBackIcon(16)}\n </button>\n <button\n type=\"button\"\n class=\"fw-btn-flush hidden sm:flex\"\n ?disabled=${disabled}\n aria-label=${this.pc.t(\"skipForward\")}\n @click=${() => this.pc.seekBy(10000)}\n >\n ${skipForwardIcon(16)}\n </button>\n `\n : nothing}\n </div>\n\n <div class=\"fw-control-group\">\n <fw-volume-control .pc=${this.pc}></fw-volume-control>\n </div>\n\n ${showTimeDisplay\n ? html`\n <div class=\"fw-control-group\">\n <span class=\"fw-time-display\">${timeDisplay}</span>\n </div>\n `\n : nothing}\n ${context.isLive\n ? html`\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n @click=${() => this.pc.jumpToLive()}\n ?disabled=${liveButtonDisabled}\n class=${classMap({\n \"fw-live-badge\": true,\n \"fw-live-badge--active\": liveButtonDisabled,\n \"fw-live-badge--behind\": !liveButtonDisabled,\n })}\n title=${!context.hasDvrWindow\n ? this.pc.t(\"live\")\n : this._isNearLiveState\n ? this.pc.t(\"live\")\n : this.pc.t(\"live\")}\n >\n ${this.pc.t(\"live\").toUpperCase()}\n ${!this._isNearLiveState && context.hasDvrWindow\n ? seekToLiveIcon(10)\n : nothing}\n </button>\n </div>\n `\n : nothing}\n </div>\n\n <div class=\"fw-controls-right\">\n ${this.showStatsButton\n ? html`\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-btn-flush\": true,\n \"fw-btn-flush--active\": this.isStatsOpen,\n })}\n aria-label=${this.pc.t(\"showStats\")}\n title=${this.pc.t(\"showStats\")}\n @click=${() =>\n this.dispatchEvent(\n new CustomEvent(\"fw-stats-toggle\", {\n bubbles: true,\n composed: true,\n })\n )}\n >\n ${statsIcon(16)}\n </button>\n </div>\n `\n : nothing}\n <div class=\"fw-control-group fw-settings-anchor\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-btn-flush\": true,\n group: true,\n \"fw-btn-flush--active\": this._settingsOpen,\n })}\n aria-label=${this.pc.t(\"settings\")}\n title=${this.pc.t(\"settings\")}\n ?disabled=${disabled}\n @click=${(event: MouseEvent) => {\n event.stopPropagation();\n if (disabled) {\n return;\n }\n this._settingsOpen = !this._settingsOpen;\n }}\n >\n <span class=\"transition-transform group-hover:rotate-90\"\n >${settingsIcon(16)}</span\n >\n </button>\n\n <fw-settings-menu\n .pc=${this.pc}\n .open=${this._settingsOpen}\n .playbackMode=${this.playbackMode}\n .isContentLive=${this.isContentLive}\n .activeLocale=${this.activeLocale}\n @click=${(event: MouseEvent) => event.stopPropagation()}\n @fw-close=${() => {\n this._settingsOpen = false;\n }}\n @fw-mode-change=${this._handleModeChange}\n ></fw-settings-menu>\n </div>\n\n <div class=\"fw-control-group\">\n <button\n type=\"button\"\n class=\"fw-btn-flush\"\n ?disabled=${disabled}\n aria-label=${state.isFullscreen\n ? this.pc.t(\"exitFullscreen\")\n : this.pc.t(\"fullscreen\")}\n @click=${() => this.pc.toggleFullscreen()}\n >\n ${state.isFullscreen ? fullscreenExitIcon(16) : fullscreenIcon(16)}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-player-controls\": FwPlayerControls;\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, state, query, 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, state, customElement } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
@@ -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';
@@ -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;