@livepeer-frameworks/player-wc 0.2.5 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <https://unlicense.org>
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # @livepeer-frameworks/player-wc
2
+
3
+ Web Components wrapper for the FrameWorks player. Registers `<fw-player>` and composable sub-elements via Lit.
4
+
5
+ **Docs:** https://logbook.frameworks.network
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @livepeer-frameworks/player-wc
11
+ # or
12
+ npm i @livepeer-frameworks/player-wc
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Auto-register elements (side-effect import)
18
+
19
+ ```js
20
+ import "@livepeer-frameworks/player-wc/define";
21
+ ```
22
+
23
+ ```html
24
+ <fw-player
25
+ content-id="pk_..."
26
+ content-type="live"
27
+ gateway-url="https://your-bridge/graphql"
28
+ autoplay
29
+ muted
30
+ ></fw-player>
31
+ ```
32
+
33
+ ### Class import (no auto-registration)
34
+
35
+ ```js
36
+ import { FwPlayer } from "@livepeer-frameworks/player-wc";
37
+ ```
38
+
39
+ ### CDN / Script Tag
40
+
41
+ ```html
42
+ <script src="https://unpkg.com/@livepeer-frameworks/player-wc/dist/fw-player.iife.js"></script>
43
+
44
+ <fw-player content-id="pk_..." content-type="live"></fw-player>
45
+ ```
46
+
47
+ Notes:
48
+
49
+ - There is **no default gateway**; provide `gatewayUrl` unless you pass `endpoints` or `mistUrl`.
50
+
51
+ ### Direct MistServer Node (mistUrl)
52
+
53
+ ```html
54
+ <fw-player
55
+ content-id="pk_..."
56
+ content-type="live"
57
+ mist-url="https://edge-egress.example.com"
58
+ ></fw-player>
59
+ ```
60
+
61
+ ## Attributes
62
+
63
+ | Attribute | Type | Default | Description |
64
+ | ---------------- | --------- | -------- | --------------------------------------- |
65
+ | `content-id` | `string` | `""` | Playback ID |
66
+ | `content-type` | `string` | — | `"live"` · `"dvr"` · `"clip"` · `"vod"` |
67
+ | `gateway-url` | `string` | — | Gateway GraphQL endpoint |
68
+ | `mist-url` | `string` | — | Direct MistServer endpoint |
69
+ | `auth-token` | `string` | — | Auth token |
70
+ | `autoplay` | `boolean` | `true` | Auto-start playback |
71
+ | `muted` | `boolean` | `true` | Start muted |
72
+ | `playback-mode` | `string` | `"auto"` | `"auto"` · `"hls"` · `"webrtc"` · etc. |
73
+ | `stock-controls` | `boolean` | `false` | Use native browser controls |
74
+ | `thumbnail-url` | `string` | — | Poster / thumbnail URL |
75
+ | `theme` | `string` | — | Theme preset name |
76
+ | `locale` | `string` | `"en"` | UI language |
77
+ | `debug` | `boolean` | `false` | Debug logging |
78
+ | `dev-mode` | `boolean` | `false` | Show dev panel |
79
+
80
+ ## Methods
81
+
82
+ ```js
83
+ const player = document.querySelector("fw-player");
84
+
85
+ player.play();
86
+ player.pause();
87
+ player.togglePlay();
88
+ player.seek(30000);
89
+ player.seekBy(-10000);
90
+ player.jumpToLive();
91
+ player.setVolume(0.5);
92
+ player.toggleMute();
93
+ player.toggleLoop();
94
+ player.toggleFullscreen();
95
+ player.togglePiP();
96
+ player.toggleSubtitles();
97
+ player.getQualities();
98
+ player.selectQuality(id);
99
+ player.retry();
100
+ player.reload();
101
+ player.destroy();
102
+ ```
103
+
104
+ ## Events
105
+
106
+ | Event | Detail |
107
+ | ---------------------- | ----------------------------------- |
108
+ | `fw-state-change` | Player state updated |
109
+ | `fw-ready` | Player attached, `{ videoElement }` |
110
+ | `fw-stream-state` | Stream health state changed |
111
+ | `fw-time-update` | `{ currentTime, duration }` (ms) |
112
+ | `fw-volume-change` | `{ volume, muted }` |
113
+ | `fw-fullscreen-change` | `{ isFullscreen }` |
114
+ | `fw-pip-change` | `{ isPiP }` |
115
+ | `fw-error` | `{ error }` |
116
+ | `fw-protocol-swapped` | Transport protocol changed |
117
+ | `fw-playback-failed` | Playback failed after retries |
118
+
119
+ ## Theming
120
+
121
+ Set a preset via the `theme` attribute, or pass a CSS variable object to the `themeOverrides` JS property:
122
+
123
+ ```js
124
+ player.themeOverrides = {
125
+ "--fw-color-accent": "#ff6600",
126
+ };
127
+ ```
128
+
129
+ ## Sub-elements
130
+
131
+ `<fw-player>` bundles a full UI. All sub-elements are also exported for custom layouts:
132
+
133
+ `<fw-player-controls>` · `<fw-seek-bar>` · `<fw-volume-control>` · `<fw-settings-menu>` · `<fw-idle-screen>` · `<fw-loading-spinner>` · `<fw-loading-screen>` · `<fw-stream-state-overlay>` · `<fw-thumbnail-overlay>` · `<fw-title-overlay>` · `<fw-error-overlay>` · `<fw-toast>` · `<fw-stats-panel>` · `<fw-dev-mode-panel>` · `<fw-subtitle-renderer>` · `<fw-skip-indicator>` · `<fw-speed-indicator>` · `<fw-context-menu>` · `<fw-play-button>` · `<fw-skip-button>` · `<fw-time-display>` · `<fw-live-badge>` · `<fw-fullscreen-button>` · `<fw-dvd-logo>`
134
+
135
+ ## Controls & Shortcuts
136
+
137
+ The player ships with keyboard/mouse shortcuts when the player is focused (click/tap once).
138
+
139
+ **Keyboard**
140
+ | Shortcut | Action | Notes |
141
+ |---|---|---|
142
+ | Space | Play/Pause | Hold = 2x speed (when seekable) |
143
+ | K | Play/Pause | YouTube-style |
144
+ | J / Left | Skip back 10s | Disabled on live-only |
145
+ | L / Right | Skip forward 10s | Disabled on live-only |
146
+ | Up / Down | Volume +/-10% | - |
147
+ | M | Mute/Unmute | - |
148
+ | F | Fullscreen toggle | - |
149
+ | C | Captions toggle | - |
150
+ | 0-9 | Seek to 0-90% | Disabled on live-only |
151
+ | , / . | Prev/Next frame (paused) | WebCodecs = true step; others = buffered-only |
152
+
153
+ **Mouse / Touch**
154
+ | Gesture | Action | Notes |
155
+ |---|---|---|
156
+ | Double-click | Fullscreen toggle | Desktop |
157
+ | Double-tap (left/right) | Skip +/-10s | Touch only, disabled on live-only |
158
+ | Click/Tap and hold | 2x speed | Disabled on live-only |
159
+
160
+ **Constraints**
161
+
162
+ - Live-only streams disable seeking/skip/2x hold and frame-step.
163
+ - Live with DVR buffer enables the same shortcuts as VOD.
164
+ - Frame stepping only moves within already buffered ranges (no network seek). WebCodecs supports true frame stepping when paused.
@@ -24,7 +24,7 @@ let FwSkipButton = class FwSkipButton extends LitElement {
24
24
  this._player = this._resolvePlayer();
25
25
  }
26
26
  handleClick() {
27
- const delta = this.direction === "back" ? -this.seconds : this.seconds;
27
+ const delta = (this.direction === "back" ? -this.seconds : this.seconds) * 1000;
28
28
  this._player?.pc?.seekBy(delta);
29
29
  }
30
30
  render() {
@@ -1 +1 @@
1
- {"version":3,"file":"fw-skip-button.js","sources":["../../../../../src/components/controls/fw-skip-button.ts"],"sourcesContent":["import { LitElement, html, css } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { createTranslator, type TranslateFn } from \"@livepeer-frameworks/player-core\";\n\n@customElement(\"fw-skip-button\")\nexport class FwSkipButton extends LitElement {\n @property({ type: String }) direction: \"back\" | \"forward\" = \"forward\";\n @property({ type: Number }) seconds = 10;\n private _player: any = null;\n\n private get _t(): TranslateFn {\n return this._player?.pc?.t ?? createTranslator({ locale: \"en\" });\n }\n\n static styles = css`\n :host {\n display: inline-flex;\n align-items: center;\n }\n `;\n\n private _resolvePlayer(): HTMLElement | null {\n const forId = this.getAttribute(\"for\");\n if (forId) return document.getElementById(forId);\n return this.closest(\"fw-player\");\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._player = this._resolvePlayer();\n }\n\n private handleClick() {\n const delta = this.direction === \"back\" ? -this.seconds : this.seconds;\n this._player?.pc?.seekBy(delta);\n }\n\n render() {\n const label = this.direction === \"back\" ? this._t(\"skipBackward\") : this._t(\"skipForward\");\n const icon = this.direction === \"back\" ? \"\\u23EA\" : \"\\u23E9\";\n const shortcut = this.direction === \"back\" ? \"j\" : \"l\";\n\n return html`<button\n type=\"button\"\n class=\"fw-btn-flush\"\n aria-label=${label}\n title=\"${label} (${shortcut})\"\n @click=${this.handleClick}\n >\n ${icon} ${this.seconds}s\n </button>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-skip-button\": FwSkipButton;\n }\n}\n"],"names":[],"mappings":";;;;;AAKO,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU,CAAA;AAArC,IAAA,WAAA,GAAA;;QACuB,IAAA,CAAA,SAAS,GAAuB,SAAS;QACzC,IAAA,CAAA,OAAO,GAAG,EAAE;QAChC,IAAA,CAAA,OAAO,GAAQ,IAAI;IA4C7B;AA1CE,IAAA,IAAY,EAAE,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAClE;IASQ,cAAc,GAAA;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;AACtC,QAAA,IAAI,KAAK;AAAE,YAAA,OAAO,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC;AAChD,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IAClC;IAEA,iBAAiB,GAAA;QACf,KAAK,CAAC,iBAAiB,EAAE;AACzB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;IACtC;IAEQ,WAAW,GAAA;QACjB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO;QACtE,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC;IACjC;IAEA,MAAM,GAAA;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC;AAC1F,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,QAAQ,GAAG,QAAQ;AAC5D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,GAAG,GAAG,GAAG;AAEtD,QAAA,OAAO,IAAI,CAAA,CAAA;;;mBAGI,KAAK;AACT,aAAA,EAAA,KAAK,KAAK,QAAQ,CAAA;AAClB,aAAA,EAAA,IAAI,CAAC,WAAW;;QAEvB,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,CAAA;cACd;IACZ;;AArCO,YAAA,CAAA,MAAM,GAAG,GAAG,CAAA;;;;;AAKlB,EAAA,CALY;AARe,UAAA,CAAA;AAA3B,IAAA,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;AAA4C,CAAA,EAAA,YAAA,CAAA,SAAA,EAAA,WAAA,EAAA,MAAA,CAAA;AAC1C,UAAA,CAAA;AAA3B,IAAA,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;AAAe,CAAA,EAAA,YAAA,CAAA,SAAA,EAAA,SAAA,EAAA,MAAA,CAAA;AAF9B,YAAY,GAAA,UAAA,CAAA;IADxB,aAAa,CAAC,gBAAgB;AAClB,CAAA,EAAA,YAAY,CA+CxB;;;;"}
1
+ {"version":3,"file":"fw-skip-button.js","sources":["../../../../../src/components/controls/fw-skip-button.ts"],"sourcesContent":["import { LitElement, html, css } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { createTranslator, type TranslateFn } from \"@livepeer-frameworks/player-core\";\n\n@customElement(\"fw-skip-button\")\nexport class FwSkipButton extends LitElement {\n @property({ type: String }) direction: \"back\" | \"forward\" = \"forward\";\n @property({ type: Number }) seconds = 10;\n private _player: any = null;\n\n private get _t(): TranslateFn {\n return this._player?.pc?.t ?? createTranslator({ locale: \"en\" });\n }\n\n static styles = css`\n :host {\n display: inline-flex;\n align-items: center;\n }\n `;\n\n private _resolvePlayer(): HTMLElement | null {\n const forId = this.getAttribute(\"for\");\n if (forId) return document.getElementById(forId);\n return this.closest(\"fw-player\");\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._player = this._resolvePlayer();\n }\n\n private handleClick() {\n const delta = (this.direction === \"back\" ? -this.seconds : this.seconds) * 1000;\n this._player?.pc?.seekBy(delta);\n }\n\n render() {\n const label = this.direction === \"back\" ? this._t(\"skipBackward\") : this._t(\"skipForward\");\n const icon = this.direction === \"back\" ? \"\\u23EA\" : \"\\u23E9\";\n const shortcut = this.direction === \"back\" ? \"j\" : \"l\";\n\n return html`<button\n type=\"button\"\n class=\"fw-btn-flush\"\n aria-label=${label}\n title=\"${label} (${shortcut})\"\n @click=${this.handleClick}\n >\n ${icon} ${this.seconds}s\n </button>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-skip-button\": FwSkipButton;\n }\n}\n"],"names":[],"mappings":";;;;;AAKO,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU,CAAA;AAArC,IAAA,WAAA,GAAA;;QACuB,IAAA,CAAA,SAAS,GAAuB,SAAS;QACzC,IAAA,CAAA,OAAO,GAAG,EAAE;QAChC,IAAA,CAAA,OAAO,GAAQ,IAAI;IA4C7B;AA1CE,IAAA,IAAY,EAAE,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAClE;IASQ,cAAc,GAAA;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;AACtC,QAAA,IAAI,KAAK;AAAE,YAAA,OAAO,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC;AAChD,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IAClC;IAEA,iBAAiB,GAAA;QACf,KAAK,CAAC,iBAAiB,EAAE;AACzB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;IACtC;IAEQ,WAAW,GAAA;QACjB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI;QAC/E,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC;IACjC;IAEA,MAAM,GAAA;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC;AAC1F,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,QAAQ,GAAG,QAAQ;AAC5D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM,GAAG,GAAG,GAAG,GAAG;AAEtD,QAAA,OAAO,IAAI,CAAA,CAAA;;;mBAGI,KAAK;AACT,aAAA,EAAA,KAAK,KAAK,QAAQ,CAAA;AAClB,aAAA,EAAA,IAAI,CAAC,WAAW;;QAEvB,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,CAAA;cACd;IACZ;;AArCO,YAAA,CAAA,MAAM,GAAG,GAAG,CAAA;;;;;AAKlB,EAAA,CALY;AARe,UAAA,CAAA;AAA3B,IAAA,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;AAA4C,CAAA,EAAA,YAAA,CAAA,SAAA,EAAA,WAAA,EAAA,MAAA,CAAA;AAC1C,UAAA,CAAA;AAA3B,IAAA,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;AAAe,CAAA,EAAA,YAAA,CAAA,SAAA,EAAA,SAAA,EAAA,MAAA,CAAA;AAF9B,YAAY,GAAA,UAAA,CAAA;IADxB,aAAa,CAAC,gBAAgB;AAClB,CAAA,EAAA,YAAY,CA+CxB;;;;"}
@@ -610,14 +610,16 @@ let FwDevModePanel = class FwDevModePanel extends LitElement {
610
610
  : html `
611
611
  ${allCombinations.map((combo, index) => {
612
612
  const isCodecIncompatible = combo.codecIncompatible === true;
613
- if (!combo.compatible && !isCodecIncompatible && !this._showDisabledPlayers) {
613
+ const isPartial = (combo.missingTracks?.length ?? 0) > 0;
614
+ const isWarn = isCodecIncompatible || isPartial;
615
+ if (!combo.compatible && !isWarn && !this._showDisabledPlayers) {
614
616
  return nothing;
615
617
  }
616
618
  const isActive = activeComboIndex === index;
617
619
  const typeLabel = SOURCE_TYPE_LABELS[combo.sourceType] || combo.sourceType.split("/").pop();
618
- const scoreClass = !combo.compatible && !isCodecIncompatible
620
+ const scoreClass = !combo.compatible && !isWarn
619
621
  ? "fw-dev-combo-score--disabled"
620
- : isCodecIncompatible
622
+ : isWarn
621
623
  ? "fw-dev-combo-score--low"
622
624
  : combo.score >= 2
623
625
  ? "fw-dev-combo-score--high"
@@ -626,14 +628,14 @@ let FwDevModePanel = class FwDevModePanel extends LitElement {
626
628
  : "fw-dev-combo-score--low";
627
629
  const rankClass = isActive
628
630
  ? "fw-dev-combo-rank--active"
629
- : !combo.compatible && !isCodecIncompatible
631
+ : !combo.compatible && !isWarn
630
632
  ? "fw-dev-combo-rank--disabled"
631
- : isCodecIncompatible
633
+ : isWarn
632
634
  ? "fw-dev-combo-rank--warn"
633
635
  : "";
634
- const typeClass = !combo.compatible && !isCodecIncompatible
636
+ const typeClass = !combo.compatible && !isWarn
635
637
  ? "fw-dev-combo-type--disabled"
636
- : isCodecIncompatible
638
+ : isWarn
637
639
  ? "fw-dev-combo-type--warn"
638
640
  : "";
639
641
  return html `
@@ -650,8 +652,8 @@ let FwDevModePanel = class FwDevModePanel extends LitElement {
650
652
  class=${classMap({
651
653
  "fw-dev-combo-btn": true,
652
654
  "fw-dev-combo-btn--active": isActive,
653
- "fw-dev-combo-btn--disabled": !combo.compatible && !isCodecIncompatible,
654
- "fw-dev-combo-btn--codec-warn": isCodecIncompatible,
655
+ "fw-dev-combo-btn--disabled": !combo.compatible && !isWarn,
656
+ "fw-dev-combo-btn--codec-warn": isWarn,
655
657
  })}
656
658
  @click=${() => this._handleSelectCombo(index)}
657
659
  >
@@ -660,9 +662,9 @@ let FwDevModePanel = class FwDevModePanel extends LitElement {
660
662
  "fw-dev-combo-rank": true,
661
663
  [rankClass]: rankClass.length > 0,
662
664
  })}
663
- >${combo.compatible
665
+ >${combo.compatible && !isPartial
664
666
  ? index + 1
665
- : isCodecIncompatible
667
+ : isWarn
666
668
  ? "\u26A0"
667
669
  : "\u2014"}</span
668
670
  >
@@ -706,6 +708,14 @@ let FwDevModePanel = class FwDevModePanel extends LitElement {
706
708
  : nothing}
707
709
  </div>
708
710
 
711
+ ${combo.note
712
+ ? html `<div class="fw-dev-tooltip-note">${combo.note}</div>`
713
+ : nothing}
714
+ ${isPartial
715
+ ? html `<div class="fw-dev-tooltip-note">
716
+ No compatible ${combo.missingTracks.join(", ")} codec
717
+ </div>`
718
+ : nothing}
709
719
  ${combo.compatible && combo.scoreBreakdown
710
720
  ? html `
711
721
  <div class="fw-dev-tooltip-score">
@@ -1 +1 @@
1
- {"version":3,"file":"fw-dev-mode-panel.js","sources":["../../../../src/components/fw-dev-mode-panel.ts"],"sourcesContent":["/**\n * <fw-dev-mode-panel> — Developer mode side panel.\n * Feature parity with React/Svelte advanced panel.\n */\nimport { LitElement, html, css, nothing, type PropertyValues } 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 { closeIcon } from \"../icons/index.js\";\nimport {\n QualityMonitor,\n globalPlayerManager,\n type MistStreamInfo,\n type PlaybackMode,\n type PlayerCombination,\n type StreamInfo,\n} from \"@livepeer-frameworks/player-core\";\nimport type { PlayerControllerHost } from \"../controllers/player-controller-host.js\";\n\nconst SOURCE_TYPE_LABELS: Record<string, string> = {\n \"html5/application/vnd.apple.mpegurl\": \"HLS\",\n \"dash/video/mp4\": \"DASH\",\n \"html5/video/mp4\": \"MP4\",\n \"html5/video/webm\": \"WebM\",\n whep: \"WHEP\",\n \"mist/html\": \"Mist\",\n \"mist/legacy\": \"Auto\",\n \"ws/video/mp4\": \"MEWS\",\n};\n\n@customElement(\"fw-dev-mode-panel\")\nexport class FwDevModePanel extends LitElement {\n @property({ attribute: false }) pc!: PlayerControllerHost;\n @property({ type: String }) playbackMode: PlaybackMode = \"auto\";\n\n @state() private _activeTab: \"config\" | \"stats\" = \"config\";\n @state() private _hoveredComboIndex: number | null = null;\n @state() private _tooltipPos: { top: number; left: number } | null = null;\n @state() private _showDisabledPlayers = false;\n\n @state() private _playbackScore = 1;\n @state() private _qualityScore = 100;\n @state() private _stallCount = 0;\n @state() private _frameDropRate = 0;\n\n @state()\n private _videoStats: {\n resolution: string;\n buffered: string;\n playbackRate: string;\n currentTime: string;\n duration: string;\n readyState: number;\n networkState: number;\n } | null = null;\n\n @state() private _playerStats: unknown = null;\n\n private _qualityMonitor: QualityMonitor | null = null;\n private _qualityMonitorVideo: HTMLVideoElement | null = null;\n private _videoStatsInterval: ReturnType<typeof setInterval> | null = null;\n private _playerStatsInterval: ReturnType<typeof setInterval> | null = null;\n\n static styles = [\n sharedStyles,\n utilityStyles,\n css`\n :host {\n display: block;\n height: 100%;\n min-height: 0;\n }\n `,\n ];\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._stopQualityMonitor();\n this._stopStatsPolling();\n }\n\n protected updated(_changed: PropertyValues<this>): void {\n this._syncQualityMonitor();\n this._syncStatsPolling();\n }\n\n private _getMistStreamInfo(): MistStreamInfo | undefined {\n return this.pc.s.streamState?.streamInfo as MistStreamInfo | undefined;\n }\n\n private _getAllCombinations(): PlayerCombination[] {\n const streamInfo = this.pc.s.streamInfo as StreamInfo | null;\n if (!streamInfo) {\n return [];\n }\n\n try {\n return globalPlayerManager.getAllCombinations(streamInfo, this.playbackMode);\n } catch {\n return [];\n }\n }\n\n private _getCompatibleCombinations(): PlayerCombination[] {\n return this._getAllCombinations().filter((combo) => combo.compatible);\n }\n\n private _getActiveComboIndex(combinations: PlayerCombination[]): number {\n const currentPlayer = this.pc.s.currentPlayerInfo;\n const currentSource = this.pc.s.currentSourceInfo;\n\n if (!currentPlayer || !currentSource || combinations.length === 0) {\n return -1;\n }\n\n return combinations.findIndex(\n (combo) => combo.player === currentPlayer.shortname && combo.sourceType === currentSource.type\n );\n }\n\n private _syncQualityMonitor(): void {\n const video = this.pc.s.videoElement;\n\n if (!video) {\n this._stopQualityMonitor();\n return;\n }\n\n if (!this._qualityMonitor) {\n this._qualityMonitor = new QualityMonitor({\n sampleInterval: 500,\n onSample: (quality) => {\n this._qualityScore = quality.score;\n this._stallCount = quality.stallCount;\n this._frameDropRate = quality.frameDropRate;\n this._playbackScore = this._qualityMonitor?.getPlaybackScore() ?? 1;\n this.requestUpdate();\n },\n });\n }\n\n if (this._qualityMonitorVideo !== video) {\n this._qualityMonitor.stop();\n this._qualityMonitor.start(video);\n this._qualityMonitorVideo = video;\n }\n }\n\n private _stopQualityMonitor(): void {\n this._qualityMonitor?.stop();\n this._qualityMonitorVideo = null;\n }\n\n private _syncStatsPolling(): void {\n if (this._activeTab !== \"stats\") {\n this._stopStatsPolling();\n return;\n }\n\n if (!this._videoStatsInterval) {\n this._updateVideoStats();\n this._videoStatsInterval = setInterval(() => {\n this._updateVideoStats();\n }, 500);\n }\n\n if (!this._playerStatsInterval) {\n void this._pollPlayerStats();\n this._playerStatsInterval = setInterval(() => {\n void this._pollPlayerStats();\n }, 500);\n }\n }\n\n private _stopStatsPolling(): void {\n if (this._videoStatsInterval) {\n clearInterval(this._videoStatsInterval);\n this._videoStatsInterval = null;\n }\n\n if (this._playerStatsInterval) {\n clearInterval(this._playerStatsInterval);\n this._playerStatsInterval = null;\n }\n }\n\n private _updateVideoStats(): void {\n const video = this.pc.s.videoElement;\n if (!video) {\n this._videoStats = null;\n return;\n }\n\n this._videoStats = {\n resolution: `${video.videoWidth}x${video.videoHeight}`,\n buffered:\n video.buffered.length > 0\n ? (video.buffered.end(video.buffered.length - 1) - video.currentTime).toFixed(1)\n : \"0\",\n playbackRate: video.playbackRate.toFixed(2),\n currentTime: video.currentTime.toFixed(1),\n duration: Number.isFinite(video.duration) ? video.duration.toFixed(1) : \"live\",\n readyState: video.readyState,\n networkState: video.networkState,\n };\n }\n\n private async _pollPlayerStats(): Promise<void> {\n try {\n const stats = await this.pc.getStats();\n if (stats) {\n this._playerStats = stats;\n }\n } catch {\n // No-op for optional stats backends.\n }\n }\n\n private _handleComboMouseEnter(index: number, event: MouseEvent): void {\n this._hoveredComboIndex = index;\n const row = event.currentTarget as HTMLElement;\n const rowRect = row.getBoundingClientRect();\n this._tooltipPos = {\n top: Math.max(8, Math.min(rowRect.top, window.innerHeight - 200)),\n left: Math.max(8, rowRect.left - 228),\n };\n }\n\n private _handleModeChange(mode: \"auto\" | \"low-latency\" | \"quality\"): void {\n this.playbackMode = mode;\n void this.pc.setDevModeOptions({ playbackMode: mode });\n this.dispatchEvent(\n new CustomEvent(\"fw-playback-mode-change\", {\n detail: { mode },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private _handleReload(): void {\n this.pc.clearError();\n void this.pc.reload();\n }\n\n private _handleNextCombo(): void {\n const compatible = this._getCompatibleCombinations();\n if (compatible.length === 0) {\n return;\n }\n\n const activeCompatibleIndex = this._getActiveComboIndex(compatible);\n const startIndex = activeCompatibleIndex >= 0 ? activeCompatibleIndex : -1;\n const nextIndex = (startIndex + 1) % compatible.length;\n const next = compatible[nextIndex];\n\n void this.pc.setDevModeOptions({\n forcePlayer: next.player,\n forceType: next.sourceType,\n forceSource: next.sourceIndex,\n });\n }\n\n private _handleSelectCombo(index: number): void {\n const allCombinations = this._getAllCombinations();\n const combo = allCombinations[index];\n if (!combo) {\n return;\n }\n\n void this.pc.setDevModeOptions({\n forcePlayer: combo.player,\n forceType: combo.sourceType,\n forceSource: combo.sourceIndex,\n });\n }\n\n private _renderStatsTab(): unknown {\n const primaryEndpoint = (this.pc.s.endpoints?.primary ?? null) as {\n protocol?: string;\n nodeId?: string;\n } | null;\n\n const stats = this._videoStats;\n const playerStats = this._playerStats as any;\n const mistStreamInfo = this._getMistStreamInfo();\n const trackEntries = Object.entries(mistStreamInfo?.meta?.tracks ?? {});\n\n return html`\n <div class=\"fw-dev-body\">\n <div class=\"fw-dev-section\">\n <div class=\"fw-dev-label\">Playback Rate</div>\n <div class=\"fw-dev-rate\">\n <div\n class=${classMap({\n \"fw-dev-rate-value\": true,\n \"fw-dev-stat-value--good\":\n this._playbackScore >= 0.95 && this._playbackScore <= 1.05,\n \"fw-dev-stat-value--accent\": this._playbackScore > 1.05,\n \"fw-dev-stat-value--warn\":\n this._playbackScore >= 0.75 && this._playbackScore < 0.95,\n \"fw-dev-stat-value--bad\": this._playbackScore < 0.75,\n })}\n >\n ${this._playbackScore.toFixed(2)}x\n </div>\n <div class=\"fw-dev-rate-status\">\n ${this._playbackScore >= 0.95 && this._playbackScore <= 1.05\n ? \"realtime\"\n : this._playbackScore > 1.05\n ? \"catching up\"\n : this._playbackScore >= 0.75\n ? \"slightly slow\"\n : \"stalling\"}\n </div>\n </div>\n <div class=\"fw-dev-rate-stats\">\n <span\n class=${classMap({\n \"fw-dev-stat-value--good\": this._qualityScore >= 75,\n \"fw-dev-stat-value--bad\": this._qualityScore < 75,\n })}\n >\n Quality: ${this._qualityScore}/100\n </span>\n <span\n class=${classMap({\n \"fw-dev-stat-value--good\": this._stallCount === 0,\n \"fw-dev-stat-value--warn\": this._stallCount > 0,\n })}\n >\n Stalls: ${this._stallCount}\n </span>\n <span\n class=${classMap({\n \"fw-dev-stat-value--good\": this._frameDropRate < 1,\n \"fw-dev-stat-value--bad\": this._frameDropRate >= 1,\n })}\n >\n Drops: ${this._frameDropRate.toFixed(1)}%\n </span>\n </div>\n </div>\n\n ${stats\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Resolution</span>\n <span class=\"fw-dev-stat-value\">${stats.resolution}</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Buffer</span>\n <span class=\"fw-dev-stat-value\">${stats.buffered}s</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Playback Rate</span>\n <span class=\"fw-dev-stat-value\">${stats.playbackRate}x</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Time</span>\n <span class=\"fw-dev-stat-value\">${stats.currentTime} / ${stats.duration}</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Ready State</span>\n <span class=\"fw-dev-stat-value\">${stats.readyState}</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Network State</span>\n <span class=\"fw-dev-stat-value\">${stats.networkState}</span>\n </div>\n ${primaryEndpoint?.protocol\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Protocol</span>\n <span class=\"fw-dev-stat-value\">${primaryEndpoint.protocol}</span>\n </div>\n `\n : nothing}\n ${primaryEndpoint?.nodeId\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Node ID</span>\n <span\n class=\"fw-dev-stat-value\"\n style=\"max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\"\n >${primaryEndpoint.nodeId}</span\n >\n </div>\n `\n : nothing}\n `\n : html`<div class=\"fw-dev-list-empty\">No video element available</div>`}\n ${playerStats\n ? html`\n <div class=\"fw-dev-list-header fw-dev-section-header\">\n <span class=\"fw-dev-list-title\"\n >${playerStats.type === \"hls\"\n ? \"HLS.js Stats\"\n : playerStats.type === \"webrtc\"\n ? \"WebRTC Stats\"\n : \"Player Stats\"}</span\n >\n </div>\n\n ${playerStats.type === \"hls\"\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Bitrate</span>\n <span class=\"fw-dev-stat-value--accent\"\n >${typeof playerStats.currentBitrate === \"number\" &&\n playerStats.currentBitrate > 0\n ? `${Math.round(playerStats.currentBitrate / 1000)} kbps`\n : \"N/A\"}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Bandwidth Est.</span>\n <span class=\"fw-dev-stat-value\"\n >${typeof playerStats.bandwidthEstimate === \"number\" &&\n playerStats.bandwidthEstimate > 0\n ? `${Math.round(playerStats.bandwidthEstimate / 1000)} kbps`\n : \"N/A\"}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Level</span>\n <span class=\"fw-dev-stat-value\"\n >${typeof playerStats.currentLevel === \"number\" &&\n playerStats.currentLevel >= 0\n ? playerStats.currentLevel\n : \"Auto\"}\n / ${Array.isArray(playerStats.levels) ? playerStats.levels.length : 0}</span\n >\n </div>\n ${typeof playerStats.latency === \"number\"\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Latency</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value\": true,\n \"fw-dev-stat-value--warn\": playerStats.latency > 5000,\n })}\n >${Math.round(playerStats.latency)} ms</span\n >\n </div>\n `\n : nothing}\n `\n : nothing}\n ${playerStats.type === \"webrtc\"\n ? html`\n ${playerStats.video\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Video Bitrate</span>\n <span class=\"fw-dev-stat-value--accent\"\n >${typeof playerStats.video.bitrate === \"number\" &&\n playerStats.video.bitrate > 0\n ? `${Math.round(playerStats.video.bitrate / 1000)} kbps`\n : \"N/A\"}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">FPS</span>\n <span class=\"fw-dev-stat-value\"\n >${Math.round(\n (playerStats.video.framesPerSecond as number) || 0\n )}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Frames</span>\n <span class=\"fw-dev-stat-value\"\n >${playerStats.video.framesDecoded as number} decoded,\n <span\n class=${classMap({\n \"fw-dev-stat-value--bad\":\n ((playerStats.video.frameDropRate as number) || 0) > 1,\n \"fw-dev-stat-value--good\":\n ((playerStats.video.frameDropRate as number) || 0) <= 1,\n })}\n >${playerStats.video.framesDropped as number} dropped</span\n ></span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Packet Loss</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value--bad\":\n ((playerStats.video.packetLossRate as number) || 0) > 1,\n \"fw-dev-stat-value--good\":\n ((playerStats.video.packetLossRate as number) || 0) <= 1,\n })}\n >${(\n ((playerStats.video.packetLossRate as number) || 0) as number\n ).toFixed(2)}%</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Jitter</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value\": true,\n \"fw-dev-stat-value--warn\":\n ((playerStats.video.jitter as number) || 0) > 30,\n })}\n >${(((playerStats.video.jitter as number) || 0) as number).toFixed(1)}\n ms</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Jitter Buffer</span>\n <span class=\"fw-dev-stat-value\"\n >${(\n ((playerStats.video.jitterBufferDelay as number) || 0) as number\n ).toFixed(1)}\n ms</span\n >\n </div>\n `\n : nothing}\n ${playerStats.network\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">RTT</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value\": true,\n \"fw-dev-stat-value--warn\":\n ((playerStats.network.rtt as number) || 0) > 200,\n })}\n >${Math.round(((playerStats.network.rtt as number) || 0) as number)}\n ms</span\n >\n </div>\n `\n : nothing}\n `\n : nothing}\n `\n : nothing}\n ${trackEntries.length > 0\n ? html`\n <div class=\"fw-dev-list-header fw-dev-section-header\">\n <span class=\"fw-dev-list-title\">Tracks (${trackEntries.length})</span>\n </div>\n ${trackEntries.map(([id, track]) => {\n const typedTrack = track as {\n type: string;\n codec: string;\n width?: number;\n height?: number;\n bps?: number;\n fpks?: number;\n channels?: number;\n rate?: number;\n lang?: string;\n };\n\n return html`\n <div class=\"fw-dev-track\">\n <div class=\"fw-dev-track-header\">\n <span\n class=${classMap({\n \"fw-dev-track-badge\": true,\n \"fw-dev-track-badge--video\": typedTrack.type === \"video\",\n \"fw-dev-track-badge--audio\": typedTrack.type === \"audio\",\n \"fw-dev-track-badge--other\":\n typedTrack.type !== \"video\" && typedTrack.type !== \"audio\",\n })}\n >${typedTrack.type}</span\n >\n <span class=\"fw-dev-track-codec\">${typedTrack.codec}</span>\n <span class=\"fw-dev-track-id\">#${id}</span>\n </div>\n <div class=\"fw-dev-track-meta\">\n ${typedTrack.type === \"video\" && typedTrack.width && typedTrack.height\n ? html`<span>${typedTrack.width}x${typedTrack.height}</span>`\n : nothing}\n ${typedTrack.bps\n ? html`<span>${Math.round(typedTrack.bps / 1000)} kbps</span>`\n : nothing}\n ${typedTrack.fpks\n ? html`<span>${Math.round(typedTrack.fpks / 1000)} fps</span>`\n : nothing}\n ${typedTrack.type === \"audio\" && typedTrack.channels\n ? html`<span>${typedTrack.channels}ch</span>`\n : nothing}\n ${typedTrack.type === \"audio\" && typedTrack.rate\n ? html`<span>${typedTrack.rate} Hz</span>`\n : nothing}\n ${typedTrack.lang ? html`<span>${typedTrack.lang}</span>` : nothing}\n </div>\n </div>\n `;\n })}\n `\n : nothing}\n ${mistStreamInfo && trackEntries.length === 0\n ? html`\n <div class=\"fw-dev-no-tracks\">\n <span class=\"fw-dev-no-tracks-text\"\n >No track data available\n ${mistStreamInfo.type\n ? html`<span class=\"fw-dev-no-tracks-type\">(${mistStreamInfo.type})</span>`\n : nothing}</span\n >\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n private _renderConfigTab(): unknown {\n const allCombinations = this._getAllCombinations();\n const compatibleCombinations = allCombinations.filter((combo) => combo.compatible);\n const activeComboIndex = this._getActiveComboIndex(allCombinations);\n\n const currentPlayer = this.pc.s.currentPlayerInfo;\n const currentSource = this.pc.s.currentSourceInfo;\n\n return html`\n <div class=\"fw-dev-body\">\n <div class=\"fw-dev-section\">\n <div class=\"fw-dev-label\">Active</div>\n <div class=\"fw-dev-value\">\n ${currentPlayer?.name || \"None\"}\n <span class=\"fw-dev-value-arrow\">${\"\\u2192\"}</span>\n ${SOURCE_TYPE_LABELS[currentSource?.type || \"\"] || currentSource?.type || \"-\"}\n </div>\n ${(this.pc.s.endpoints?.primary as { nodeId?: string } | undefined)?.nodeId\n ? html`\n <div class=\"fw-dev-value-muted\">\n Node: ${(this.pc.s.endpoints?.primary as { nodeId?: string }).nodeId}\n </div>\n `\n : nothing}\n </div>\n\n <div class=\"fw-dev-section\">\n <div class=\"fw-dev-label\">Playback Mode</div>\n <div class=\"fw-dev-mode-group\">\n ${([\"auto\", \"low-latency\", \"quality\"] as const).map(\n (mode) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-mode-btn\": true,\n \"fw-dev-mode-btn--active\": this.playbackMode === mode,\n })}\n @click=${() => this._handleModeChange(mode)}\n >\n ${mode === \"low-latency\"\n ? \"Low Lat\"\n : `${mode.charAt(0).toUpperCase()}${mode.slice(1)}`}\n </button>\n `\n )}\n </div>\n <div class=\"fw-dev-mode-desc\">\n ${this.playbackMode === \"auto\"\n ? \"Balanced: MP4/WS \\u2192 WHEP \\u2192 HLS\"\n : this.playbackMode === \"low-latency\"\n ? \"WHEP/WebRTC first (<1s delay)\"\n : \"MP4/WS first, HLS fallback\"}\n </div>\n </div>\n\n <div class=\"fw-dev-actions\">\n <button type=\"button\" class=\"fw-dev-action-btn\" @click=${this._handleReload}>\n Reload\n </button>\n <button type=\"button\" class=\"fw-dev-action-btn\" @click=${this._handleNextCombo}>\n Next Option\n </button>\n </div>\n\n <div class=\"fw-dev-section\" style=\"padding:0;border-bottom:0;\">\n <div class=\"fw-dev-list-header\">\n <span class=\"fw-dev-list-title\">Player Options (${compatibleCombinations.length})</span>\n ${allCombinations.length > compatibleCombinations.length\n ? html`\n <button\n type=\"button\"\n class=\"fw-dev-list-toggle\"\n @click=${() => {\n this._showDisabledPlayers = !this._showDisabledPlayers;\n }}\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n class=${classMap({\n \"fw-dev-chevron\": true,\n \"fw-dev-chevron--open\": this._showDisabledPlayers,\n })}\n >\n <path d=\"M6 9l6 6 6-6\"></path>\n </svg>\n ${this._showDisabledPlayers ? \"Hide\" : \"Show\"} disabled\n (${allCombinations.length - compatibleCombinations.length})\n </button>\n `\n : nothing}\n </div>\n\n ${allCombinations.length === 0\n ? html`<div class=\"fw-dev-list-empty\">No stream info available</div>`\n : html`\n ${allCombinations.map((combo, index) => {\n const isCodecIncompatible = combo.codecIncompatible === true;\n if (!combo.compatible && !isCodecIncompatible && !this._showDisabledPlayers) {\n return nothing;\n }\n\n const isActive = activeComboIndex === index;\n const typeLabel =\n SOURCE_TYPE_LABELS[combo.sourceType] || combo.sourceType.split(\"/\").pop();\n\n const scoreClass =\n !combo.compatible && !isCodecIncompatible\n ? \"fw-dev-combo-score--disabled\"\n : isCodecIncompatible\n ? \"fw-dev-combo-score--low\"\n : combo.score >= 2\n ? \"fw-dev-combo-score--high\"\n : combo.score >= 1.5\n ? \"fw-dev-combo-score--mid\"\n : \"fw-dev-combo-score--low\";\n\n const rankClass = isActive\n ? \"fw-dev-combo-rank--active\"\n : !combo.compatible && !isCodecIncompatible\n ? \"fw-dev-combo-rank--disabled\"\n : isCodecIncompatible\n ? \"fw-dev-combo-rank--warn\"\n : \"\";\n\n const typeClass =\n !combo.compatible && !isCodecIncompatible\n ? \"fw-dev-combo-type--disabled\"\n : isCodecIncompatible\n ? \"fw-dev-combo-type--warn\"\n : \"\";\n\n return html`\n <div\n class=\"fw-dev-combo\"\n @mouseenter=${(event: MouseEvent) =>\n this._handleComboMouseEnter(index, event)}\n @mouseleave=${() => {\n this._hoveredComboIndex = null;\n this._tooltipPos = null;\n }}\n >\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-combo-btn\": true,\n \"fw-dev-combo-btn--active\": isActive,\n \"fw-dev-combo-btn--disabled\": !combo.compatible && !isCodecIncompatible,\n \"fw-dev-combo-btn--codec-warn\": isCodecIncompatible,\n })}\n @click=${() => this._handleSelectCombo(index)}\n >\n <span\n class=${classMap({\n \"fw-dev-combo-rank\": true,\n [rankClass]: rankClass.length > 0,\n })}\n >${combo.compatible\n ? index + 1\n : isCodecIncompatible\n ? \"\\u26A0\"\n : \"\\u2014\"}</span\n >\n\n <span class=\"fw-dev-combo-name\"\n >${combo.playerName} <span class=\"fw-dev-combo-arrow\">${\"\\u2192\"}</span>\n <span\n class=${classMap({\n \"fw-dev-combo-type\": true,\n [typeClass]: typeClass.length > 0,\n })}\n >${typeLabel}</span\n ></span\n >\n\n <span class=${classMap({ \"fw-dev-combo-score\": true, [scoreClass]: true })}\n >${combo.score.toFixed(2)}</span\n >\n </button>\n\n ${this._hoveredComboIndex === index && this._tooltipPos\n ? html`\n <div\n class=\"fw-dev-tooltip\"\n style=\"top: ${this._tooltipPos.top}px; left: ${this._tooltipPos\n .left}px;\"\n >\n <div class=\"fw-dev-tooltip-header\">\n <div class=\"fw-dev-tooltip-title\">${combo.playerName}</div>\n <div class=\"fw-dev-tooltip-subtitle\">${combo.sourceType}</div>\n ${combo.scoreBreakdown?.trackTypes &&\n combo.scoreBreakdown.trackTypes.length > 0\n ? html`\n <div class=\"fw-dev-tooltip-tracks\">\n Tracks:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.trackTypes.join(\", \")}</span\n >\n </div>\n `\n : nothing}\n </div>\n\n ${combo.compatible && combo.scoreBreakdown\n ? html`\n <div class=\"fw-dev-tooltip-score\">\n Score: ${combo.score.toFixed(2)}\n </div>\n <div class=\"fw-dev-tooltip-row\">\n Tracks [${combo.scoreBreakdown.trackTypes.join(\", \")}]:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.trackScore.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.tracks}</span\n >\n </div>\n <div class=\"fw-dev-tooltip-row\">\n Priority:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.priorityScore.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.priority}</span\n >\n </div>\n <div class=\"fw-dev-tooltip-row\">\n Source:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.sourceScore.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.source}</span\n >\n </div>\n\n ${typeof combo.scoreBreakdown.reliabilityScore === \"number\"\n ? html`\n <div class=\"fw-dev-tooltip-row\">\n Reliability:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.reliabilityScore.toFixed(\n 2\n )}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.reliability ??\n 0}</span\n >\n </div>\n `\n : nothing}\n ${typeof combo.scoreBreakdown.modeBonus === \"number\" &&\n combo.scoreBreakdown.modeBonus !== 0\n ? html`\n <div class=\"fw-dev-tooltip-row\">\n Mode (${this.playbackMode}):\n <span class=\"fw-dev-tooltip-bonus\"\n >+${combo.scoreBreakdown.modeBonus.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.mode ?? 0}</span\n >\n </div>\n `\n : nothing}\n ${typeof combo.scoreBreakdown.routingBonus === \"number\" &&\n combo.scoreBreakdown.routingBonus !== 0\n ? html`\n <div class=\"fw-dev-tooltip-row\">\n Routing:\n <span\n class=${classMap({\n \"fw-dev-tooltip-bonus\":\n combo.scoreBreakdown.routingBonus > 0,\n \"fw-dev-tooltip-penalty\":\n combo.scoreBreakdown.routingBonus < 0,\n })}\n >${combo.scoreBreakdown.routingBonus > 0\n ? \"+\"\n : \"\"}${combo.scoreBreakdown.routingBonus.toFixed(\n 2\n )}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.routing ?? 0}</span\n >\n </div>\n `\n : nothing}\n `\n : html`\n <div class=\"fw-dev-tooltip-error\">\n ${combo.incompatibleReason || \"Incompatible\"}\n </div>\n `}\n </div>\n `\n : nothing}\n </div>\n `;\n })}\n `}\n </div>\n </div>\n `;\n }\n\n protected render() {\n return html`\n <div class=\"fw-dev-panel\">\n <div class=\"fw-dev-header\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-tab\": true,\n \"fw-dev-tab--active\": this._activeTab === \"config\",\n })}\n @click=${() => {\n this._activeTab = \"config\";\n }}\n >\n Config\n </button>\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-tab\": true,\n \"fw-dev-tab--active\": this._activeTab === \"stats\",\n })}\n @click=${() => {\n this._activeTab = \"stats\";\n }}\n >\n Stats\n </button>\n <div class=\"fw-dev-spacer\"></div>\n <button\n type=\"button\"\n class=\"fw-dev-close\"\n aria-label=\"Close dev mode panel\"\n @click=${() =>\n this.dispatchEvent(new CustomEvent(\"fw-close\", { bubbles: true, composed: true }))}\n >\n ${closeIcon()}\n </button>\n </div>\n\n ${this._activeTab === \"config\" ? this._renderConfigTab() : this._renderStatsTab()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-dev-mode-panel\": FwDevModePanel;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fw-dev-mode-panel.js","sources":["../../../../src/components/fw-dev-mode-panel.ts"],"sourcesContent":["/**\n * <fw-dev-mode-panel> — Developer mode side panel.\n * Feature parity with React/Svelte advanced panel.\n */\nimport { LitElement, html, css, nothing, type PropertyValues } 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 { closeIcon } from \"../icons/index.js\";\nimport {\n QualityMonitor,\n globalPlayerManager,\n type MistStreamInfo,\n type PlaybackMode,\n type PlayerCombination,\n type StreamInfo,\n} from \"@livepeer-frameworks/player-core\";\nimport type { PlayerControllerHost } from \"../controllers/player-controller-host.js\";\n\nconst SOURCE_TYPE_LABELS: Record<string, string> = {\n \"html5/application/vnd.apple.mpegurl\": \"HLS\",\n \"dash/video/mp4\": \"DASH\",\n \"html5/video/mp4\": \"MP4\",\n \"html5/video/webm\": \"WebM\",\n whep: \"WHEP\",\n \"mist/html\": \"Mist\",\n \"mist/legacy\": \"Auto\",\n \"ws/video/mp4\": \"MEWS\",\n};\n\n@customElement(\"fw-dev-mode-panel\")\nexport class FwDevModePanel extends LitElement {\n @property({ attribute: false }) pc!: PlayerControllerHost;\n @property({ type: String }) playbackMode: PlaybackMode = \"auto\";\n\n @state() private _activeTab: \"config\" | \"stats\" = \"config\";\n @state() private _hoveredComboIndex: number | null = null;\n @state() private _tooltipPos: { top: number; left: number } | null = null;\n @state() private _showDisabledPlayers = false;\n\n @state() private _playbackScore = 1;\n @state() private _qualityScore = 100;\n @state() private _stallCount = 0;\n @state() private _frameDropRate = 0;\n\n @state()\n private _videoStats: {\n resolution: string;\n buffered: string;\n playbackRate: string;\n currentTime: string;\n duration: string;\n readyState: number;\n networkState: number;\n } | null = null;\n\n @state() private _playerStats: unknown = null;\n\n private _qualityMonitor: QualityMonitor | null = null;\n private _qualityMonitorVideo: HTMLVideoElement | null = null;\n private _videoStatsInterval: ReturnType<typeof setInterval> | null = null;\n private _playerStatsInterval: ReturnType<typeof setInterval> | null = null;\n\n static styles = [\n sharedStyles,\n utilityStyles,\n css`\n :host {\n display: block;\n height: 100%;\n min-height: 0;\n }\n `,\n ];\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._stopQualityMonitor();\n this._stopStatsPolling();\n }\n\n protected updated(_changed: PropertyValues<this>): void {\n this._syncQualityMonitor();\n this._syncStatsPolling();\n }\n\n private _getMistStreamInfo(): MistStreamInfo | undefined {\n return this.pc.s.streamState?.streamInfo as MistStreamInfo | undefined;\n }\n\n private _getAllCombinations(): PlayerCombination[] {\n const streamInfo = this.pc.s.streamInfo as StreamInfo | null;\n if (!streamInfo) {\n return [];\n }\n\n try {\n return globalPlayerManager.getAllCombinations(streamInfo, this.playbackMode);\n } catch {\n return [];\n }\n }\n\n private _getCompatibleCombinations(): PlayerCombination[] {\n return this._getAllCombinations().filter((combo) => combo.compatible);\n }\n\n private _getActiveComboIndex(combinations: PlayerCombination[]): number {\n const currentPlayer = this.pc.s.currentPlayerInfo;\n const currentSource = this.pc.s.currentSourceInfo;\n\n if (!currentPlayer || !currentSource || combinations.length === 0) {\n return -1;\n }\n\n return combinations.findIndex(\n (combo) => combo.player === currentPlayer.shortname && combo.sourceType === currentSource.type\n );\n }\n\n private _syncQualityMonitor(): void {\n const video = this.pc.s.videoElement;\n\n if (!video) {\n this._stopQualityMonitor();\n return;\n }\n\n if (!this._qualityMonitor) {\n this._qualityMonitor = new QualityMonitor({\n sampleInterval: 500,\n onSample: (quality) => {\n this._qualityScore = quality.score;\n this._stallCount = quality.stallCount;\n this._frameDropRate = quality.frameDropRate;\n this._playbackScore = this._qualityMonitor?.getPlaybackScore() ?? 1;\n this.requestUpdate();\n },\n });\n }\n\n if (this._qualityMonitorVideo !== video) {\n this._qualityMonitor.stop();\n this._qualityMonitor.start(video);\n this._qualityMonitorVideo = video;\n }\n }\n\n private _stopQualityMonitor(): void {\n this._qualityMonitor?.stop();\n this._qualityMonitorVideo = null;\n }\n\n private _syncStatsPolling(): void {\n if (this._activeTab !== \"stats\") {\n this._stopStatsPolling();\n return;\n }\n\n if (!this._videoStatsInterval) {\n this._updateVideoStats();\n this._videoStatsInterval = setInterval(() => {\n this._updateVideoStats();\n }, 500);\n }\n\n if (!this._playerStatsInterval) {\n void this._pollPlayerStats();\n this._playerStatsInterval = setInterval(() => {\n void this._pollPlayerStats();\n }, 500);\n }\n }\n\n private _stopStatsPolling(): void {\n if (this._videoStatsInterval) {\n clearInterval(this._videoStatsInterval);\n this._videoStatsInterval = null;\n }\n\n if (this._playerStatsInterval) {\n clearInterval(this._playerStatsInterval);\n this._playerStatsInterval = null;\n }\n }\n\n private _updateVideoStats(): void {\n const video = this.pc.s.videoElement;\n if (!video) {\n this._videoStats = null;\n return;\n }\n\n this._videoStats = {\n resolution: `${video.videoWidth}x${video.videoHeight}`,\n buffered:\n video.buffered.length > 0\n ? (video.buffered.end(video.buffered.length - 1) - video.currentTime).toFixed(1)\n : \"0\",\n playbackRate: video.playbackRate.toFixed(2),\n currentTime: video.currentTime.toFixed(1),\n duration: Number.isFinite(video.duration) ? video.duration.toFixed(1) : \"live\",\n readyState: video.readyState,\n networkState: video.networkState,\n };\n }\n\n private async _pollPlayerStats(): Promise<void> {\n try {\n const stats = await this.pc.getStats();\n if (stats) {\n this._playerStats = stats;\n }\n } catch {\n // No-op for optional stats backends.\n }\n }\n\n private _handleComboMouseEnter(index: number, event: MouseEvent): void {\n this._hoveredComboIndex = index;\n const row = event.currentTarget as HTMLElement;\n const rowRect = row.getBoundingClientRect();\n this._tooltipPos = {\n top: Math.max(8, Math.min(rowRect.top, window.innerHeight - 200)),\n left: Math.max(8, rowRect.left - 228),\n };\n }\n\n private _handleModeChange(mode: \"auto\" | \"low-latency\" | \"quality\"): void {\n this.playbackMode = mode;\n void this.pc.setDevModeOptions({ playbackMode: mode });\n this.dispatchEvent(\n new CustomEvent(\"fw-playback-mode-change\", {\n detail: { mode },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private _handleReload(): void {\n this.pc.clearError();\n void this.pc.reload();\n }\n\n private _handleNextCombo(): void {\n const compatible = this._getCompatibleCombinations();\n if (compatible.length === 0) {\n return;\n }\n\n const activeCompatibleIndex = this._getActiveComboIndex(compatible);\n const startIndex = activeCompatibleIndex >= 0 ? activeCompatibleIndex : -1;\n const nextIndex = (startIndex + 1) % compatible.length;\n const next = compatible[nextIndex];\n\n void this.pc.setDevModeOptions({\n forcePlayer: next.player,\n forceType: next.sourceType,\n forceSource: next.sourceIndex,\n });\n }\n\n private _handleSelectCombo(index: number): void {\n const allCombinations = this._getAllCombinations();\n const combo = allCombinations[index];\n if (!combo) {\n return;\n }\n\n void this.pc.setDevModeOptions({\n forcePlayer: combo.player,\n forceType: combo.sourceType,\n forceSource: combo.sourceIndex,\n });\n }\n\n private _renderStatsTab(): unknown {\n const primaryEndpoint = (this.pc.s.endpoints?.primary ?? null) as {\n protocol?: string;\n nodeId?: string;\n } | null;\n\n const stats = this._videoStats;\n const playerStats = this._playerStats as any;\n const mistStreamInfo = this._getMistStreamInfo();\n const trackEntries = Object.entries(mistStreamInfo?.meta?.tracks ?? {});\n\n return html`\n <div class=\"fw-dev-body\">\n <div class=\"fw-dev-section\">\n <div class=\"fw-dev-label\">Playback Rate</div>\n <div class=\"fw-dev-rate\">\n <div\n class=${classMap({\n \"fw-dev-rate-value\": true,\n \"fw-dev-stat-value--good\":\n this._playbackScore >= 0.95 && this._playbackScore <= 1.05,\n \"fw-dev-stat-value--accent\": this._playbackScore > 1.05,\n \"fw-dev-stat-value--warn\":\n this._playbackScore >= 0.75 && this._playbackScore < 0.95,\n \"fw-dev-stat-value--bad\": this._playbackScore < 0.75,\n })}\n >\n ${this._playbackScore.toFixed(2)}x\n </div>\n <div class=\"fw-dev-rate-status\">\n ${this._playbackScore >= 0.95 && this._playbackScore <= 1.05\n ? \"realtime\"\n : this._playbackScore > 1.05\n ? \"catching up\"\n : this._playbackScore >= 0.75\n ? \"slightly slow\"\n : \"stalling\"}\n </div>\n </div>\n <div class=\"fw-dev-rate-stats\">\n <span\n class=${classMap({\n \"fw-dev-stat-value--good\": this._qualityScore >= 75,\n \"fw-dev-stat-value--bad\": this._qualityScore < 75,\n })}\n >\n Quality: ${this._qualityScore}/100\n </span>\n <span\n class=${classMap({\n \"fw-dev-stat-value--good\": this._stallCount === 0,\n \"fw-dev-stat-value--warn\": this._stallCount > 0,\n })}\n >\n Stalls: ${this._stallCount}\n </span>\n <span\n class=${classMap({\n \"fw-dev-stat-value--good\": this._frameDropRate < 1,\n \"fw-dev-stat-value--bad\": this._frameDropRate >= 1,\n })}\n >\n Drops: ${this._frameDropRate.toFixed(1)}%\n </span>\n </div>\n </div>\n\n ${stats\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Resolution</span>\n <span class=\"fw-dev-stat-value\">${stats.resolution}</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Buffer</span>\n <span class=\"fw-dev-stat-value\">${stats.buffered}s</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Playback Rate</span>\n <span class=\"fw-dev-stat-value\">${stats.playbackRate}x</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Time</span>\n <span class=\"fw-dev-stat-value\">${stats.currentTime} / ${stats.duration}</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Ready State</span>\n <span class=\"fw-dev-stat-value\">${stats.readyState}</span>\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Network State</span>\n <span class=\"fw-dev-stat-value\">${stats.networkState}</span>\n </div>\n ${primaryEndpoint?.protocol\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Protocol</span>\n <span class=\"fw-dev-stat-value\">${primaryEndpoint.protocol}</span>\n </div>\n `\n : nothing}\n ${primaryEndpoint?.nodeId\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Node ID</span>\n <span\n class=\"fw-dev-stat-value\"\n style=\"max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\"\n >${primaryEndpoint.nodeId}</span\n >\n </div>\n `\n : nothing}\n `\n : html`<div class=\"fw-dev-list-empty\">No video element available</div>`}\n ${playerStats\n ? html`\n <div class=\"fw-dev-list-header fw-dev-section-header\">\n <span class=\"fw-dev-list-title\"\n >${playerStats.type === \"hls\"\n ? \"HLS.js Stats\"\n : playerStats.type === \"webrtc\"\n ? \"WebRTC Stats\"\n : \"Player Stats\"}</span\n >\n </div>\n\n ${playerStats.type === \"hls\"\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Bitrate</span>\n <span class=\"fw-dev-stat-value--accent\"\n >${typeof playerStats.currentBitrate === \"number\" &&\n playerStats.currentBitrate > 0\n ? `${Math.round(playerStats.currentBitrate / 1000)} kbps`\n : \"N/A\"}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Bandwidth Est.</span>\n <span class=\"fw-dev-stat-value\"\n >${typeof playerStats.bandwidthEstimate === \"number\" &&\n playerStats.bandwidthEstimate > 0\n ? `${Math.round(playerStats.bandwidthEstimate / 1000)} kbps`\n : \"N/A\"}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Level</span>\n <span class=\"fw-dev-stat-value\"\n >${typeof playerStats.currentLevel === \"number\" &&\n playerStats.currentLevel >= 0\n ? playerStats.currentLevel\n : \"Auto\"}\n / ${Array.isArray(playerStats.levels) ? playerStats.levels.length : 0}</span\n >\n </div>\n ${typeof playerStats.latency === \"number\"\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Latency</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value\": true,\n \"fw-dev-stat-value--warn\": playerStats.latency > 5000,\n })}\n >${Math.round(playerStats.latency)} ms</span\n >\n </div>\n `\n : nothing}\n `\n : nothing}\n ${playerStats.type === \"webrtc\"\n ? html`\n ${playerStats.video\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Video Bitrate</span>\n <span class=\"fw-dev-stat-value--accent\"\n >${typeof playerStats.video.bitrate === \"number\" &&\n playerStats.video.bitrate > 0\n ? `${Math.round(playerStats.video.bitrate / 1000)} kbps`\n : \"N/A\"}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">FPS</span>\n <span class=\"fw-dev-stat-value\"\n >${Math.round(\n (playerStats.video.framesPerSecond as number) || 0\n )}</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Frames</span>\n <span class=\"fw-dev-stat-value\"\n >${playerStats.video.framesDecoded as number} decoded,\n <span\n class=${classMap({\n \"fw-dev-stat-value--bad\":\n ((playerStats.video.frameDropRate as number) || 0) > 1,\n \"fw-dev-stat-value--good\":\n ((playerStats.video.frameDropRate as number) || 0) <= 1,\n })}\n >${playerStats.video.framesDropped as number} dropped</span\n ></span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Packet Loss</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value--bad\":\n ((playerStats.video.packetLossRate as number) || 0) > 1,\n \"fw-dev-stat-value--good\":\n ((playerStats.video.packetLossRate as number) || 0) <= 1,\n })}\n >${(\n ((playerStats.video.packetLossRate as number) || 0) as number\n ).toFixed(2)}%</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Jitter</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value\": true,\n \"fw-dev-stat-value--warn\":\n ((playerStats.video.jitter as number) || 0) > 30,\n })}\n >${(((playerStats.video.jitter as number) || 0) as number).toFixed(1)}\n ms</span\n >\n </div>\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">Jitter Buffer</span>\n <span class=\"fw-dev-stat-value\"\n >${(\n ((playerStats.video.jitterBufferDelay as number) || 0) as number\n ).toFixed(1)}\n ms</span\n >\n </div>\n `\n : nothing}\n ${playerStats.network\n ? html`\n <div class=\"fw-dev-stat\">\n <span class=\"fw-dev-stat-label\">RTT</span>\n <span\n class=${classMap({\n \"fw-dev-stat-value\": true,\n \"fw-dev-stat-value--warn\":\n ((playerStats.network.rtt as number) || 0) > 200,\n })}\n >${Math.round(((playerStats.network.rtt as number) || 0) as number)}\n ms</span\n >\n </div>\n `\n : nothing}\n `\n : nothing}\n `\n : nothing}\n ${trackEntries.length > 0\n ? html`\n <div class=\"fw-dev-list-header fw-dev-section-header\">\n <span class=\"fw-dev-list-title\">Tracks (${trackEntries.length})</span>\n </div>\n ${trackEntries.map(([id, track]) => {\n const typedTrack = track as {\n type: string;\n codec: string;\n width?: number;\n height?: number;\n bps?: number;\n fpks?: number;\n channels?: number;\n rate?: number;\n lang?: string;\n };\n\n return html`\n <div class=\"fw-dev-track\">\n <div class=\"fw-dev-track-header\">\n <span\n class=${classMap({\n \"fw-dev-track-badge\": true,\n \"fw-dev-track-badge--video\": typedTrack.type === \"video\",\n \"fw-dev-track-badge--audio\": typedTrack.type === \"audio\",\n \"fw-dev-track-badge--other\":\n typedTrack.type !== \"video\" && typedTrack.type !== \"audio\",\n })}\n >${typedTrack.type}</span\n >\n <span class=\"fw-dev-track-codec\">${typedTrack.codec}</span>\n <span class=\"fw-dev-track-id\">#${id}</span>\n </div>\n <div class=\"fw-dev-track-meta\">\n ${typedTrack.type === \"video\" && typedTrack.width && typedTrack.height\n ? html`<span>${typedTrack.width}x${typedTrack.height}</span>`\n : nothing}\n ${typedTrack.bps\n ? html`<span>${Math.round(typedTrack.bps / 1000)} kbps</span>`\n : nothing}\n ${typedTrack.fpks\n ? html`<span>${Math.round(typedTrack.fpks / 1000)} fps</span>`\n : nothing}\n ${typedTrack.type === \"audio\" && typedTrack.channels\n ? html`<span>${typedTrack.channels}ch</span>`\n : nothing}\n ${typedTrack.type === \"audio\" && typedTrack.rate\n ? html`<span>${typedTrack.rate} Hz</span>`\n : nothing}\n ${typedTrack.lang ? html`<span>${typedTrack.lang}</span>` : nothing}\n </div>\n </div>\n `;\n })}\n `\n : nothing}\n ${mistStreamInfo && trackEntries.length === 0\n ? html`\n <div class=\"fw-dev-no-tracks\">\n <span class=\"fw-dev-no-tracks-text\"\n >No track data available\n ${mistStreamInfo.type\n ? html`<span class=\"fw-dev-no-tracks-type\">(${mistStreamInfo.type})</span>`\n : nothing}</span\n >\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n private _renderConfigTab(): unknown {\n const allCombinations = this._getAllCombinations();\n const compatibleCombinations = allCombinations.filter((combo) => combo.compatible);\n const activeComboIndex = this._getActiveComboIndex(allCombinations);\n\n const currentPlayer = this.pc.s.currentPlayerInfo;\n const currentSource = this.pc.s.currentSourceInfo;\n\n return html`\n <div class=\"fw-dev-body\">\n <div class=\"fw-dev-section\">\n <div class=\"fw-dev-label\">Active</div>\n <div class=\"fw-dev-value\">\n ${currentPlayer?.name || \"None\"}\n <span class=\"fw-dev-value-arrow\">${\"\\u2192\"}</span>\n ${SOURCE_TYPE_LABELS[currentSource?.type || \"\"] || currentSource?.type || \"-\"}\n </div>\n ${(this.pc.s.endpoints?.primary as { nodeId?: string } | undefined)?.nodeId\n ? html`\n <div class=\"fw-dev-value-muted\">\n Node: ${(this.pc.s.endpoints?.primary as { nodeId?: string }).nodeId}\n </div>\n `\n : nothing}\n </div>\n\n <div class=\"fw-dev-section\">\n <div class=\"fw-dev-label\">Playback Mode</div>\n <div class=\"fw-dev-mode-group\">\n ${([\"auto\", \"low-latency\", \"quality\"] as const).map(\n (mode) => html`\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-mode-btn\": true,\n \"fw-dev-mode-btn--active\": this.playbackMode === mode,\n })}\n @click=${() => this._handleModeChange(mode)}\n >\n ${mode === \"low-latency\"\n ? \"Low Lat\"\n : `${mode.charAt(0).toUpperCase()}${mode.slice(1)}`}\n </button>\n `\n )}\n </div>\n <div class=\"fw-dev-mode-desc\">\n ${this.playbackMode === \"auto\"\n ? \"Balanced: MP4/WS \\u2192 WHEP \\u2192 HLS\"\n : this.playbackMode === \"low-latency\"\n ? \"WHEP/WebRTC first (<1s delay)\"\n : \"MP4/WS first, HLS fallback\"}\n </div>\n </div>\n\n <div class=\"fw-dev-actions\">\n <button type=\"button\" class=\"fw-dev-action-btn\" @click=${this._handleReload}>\n Reload\n </button>\n <button type=\"button\" class=\"fw-dev-action-btn\" @click=${this._handleNextCombo}>\n Next Option\n </button>\n </div>\n\n <div class=\"fw-dev-section\" style=\"padding:0;border-bottom:0;\">\n <div class=\"fw-dev-list-header\">\n <span class=\"fw-dev-list-title\">Player Options (${compatibleCombinations.length})</span>\n ${allCombinations.length > compatibleCombinations.length\n ? html`\n <button\n type=\"button\"\n class=\"fw-dev-list-toggle\"\n @click=${() => {\n this._showDisabledPlayers = !this._showDisabledPlayers;\n }}\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n class=${classMap({\n \"fw-dev-chevron\": true,\n \"fw-dev-chevron--open\": this._showDisabledPlayers,\n })}\n >\n <path d=\"M6 9l6 6 6-6\"></path>\n </svg>\n ${this._showDisabledPlayers ? \"Hide\" : \"Show\"} disabled\n (${allCombinations.length - compatibleCombinations.length})\n </button>\n `\n : nothing}\n </div>\n\n ${allCombinations.length === 0\n ? html`<div class=\"fw-dev-list-empty\">No stream info available</div>`\n : html`\n ${allCombinations.map((combo, index) => {\n const isCodecIncompatible = combo.codecIncompatible === true;\n const isPartial = ((combo as any).missingTracks?.length ?? 0) > 0;\n const isWarn = isCodecIncompatible || isPartial;\n if (!combo.compatible && !isWarn && !this._showDisabledPlayers) {\n return nothing;\n }\n\n const isActive = activeComboIndex === index;\n const typeLabel =\n SOURCE_TYPE_LABELS[combo.sourceType] || combo.sourceType.split(\"/\").pop();\n\n const scoreClass =\n !combo.compatible && !isWarn\n ? \"fw-dev-combo-score--disabled\"\n : isWarn\n ? \"fw-dev-combo-score--low\"\n : combo.score >= 2\n ? \"fw-dev-combo-score--high\"\n : combo.score >= 1.5\n ? \"fw-dev-combo-score--mid\"\n : \"fw-dev-combo-score--low\";\n\n const rankClass = isActive\n ? \"fw-dev-combo-rank--active\"\n : !combo.compatible && !isWarn\n ? \"fw-dev-combo-rank--disabled\"\n : isWarn\n ? \"fw-dev-combo-rank--warn\"\n : \"\";\n\n const typeClass =\n !combo.compatible && !isWarn\n ? \"fw-dev-combo-type--disabled\"\n : isWarn\n ? \"fw-dev-combo-type--warn\"\n : \"\";\n\n return html`\n <div\n class=\"fw-dev-combo\"\n @mouseenter=${(event: MouseEvent) =>\n this._handleComboMouseEnter(index, event)}\n @mouseleave=${() => {\n this._hoveredComboIndex = null;\n this._tooltipPos = null;\n }}\n >\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-combo-btn\": true,\n \"fw-dev-combo-btn--active\": isActive,\n \"fw-dev-combo-btn--disabled\": !combo.compatible && !isWarn,\n \"fw-dev-combo-btn--codec-warn\": isWarn,\n })}\n @click=${() => this._handleSelectCombo(index)}\n >\n <span\n class=${classMap({\n \"fw-dev-combo-rank\": true,\n [rankClass]: rankClass.length > 0,\n })}\n >${combo.compatible && !isPartial\n ? index + 1\n : isWarn\n ? \"\\u26A0\"\n : \"\\u2014\"}</span\n >\n\n <span class=\"fw-dev-combo-name\"\n >${combo.playerName} <span class=\"fw-dev-combo-arrow\">${\"\\u2192\"}</span>\n <span\n class=${classMap({\n \"fw-dev-combo-type\": true,\n [typeClass]: typeClass.length > 0,\n })}\n >${typeLabel}</span\n ></span\n >\n\n <span class=${classMap({ \"fw-dev-combo-score\": true, [scoreClass]: true })}\n >${combo.score.toFixed(2)}</span\n >\n </button>\n\n ${this._hoveredComboIndex === index && this._tooltipPos\n ? html`\n <div\n class=\"fw-dev-tooltip\"\n style=\"top: ${this._tooltipPos.top}px; left: ${this._tooltipPos\n .left}px;\"\n >\n <div class=\"fw-dev-tooltip-header\">\n <div class=\"fw-dev-tooltip-title\">${combo.playerName}</div>\n <div class=\"fw-dev-tooltip-subtitle\">${combo.sourceType}</div>\n ${combo.scoreBreakdown?.trackTypes &&\n combo.scoreBreakdown.trackTypes.length > 0\n ? html`\n <div class=\"fw-dev-tooltip-tracks\">\n Tracks:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.trackTypes.join(\", \")}</span\n >\n </div>\n `\n : nothing}\n </div>\n\n ${combo.note\n ? html`<div class=\"fw-dev-tooltip-note\">${combo.note}</div>`\n : nothing}\n ${isPartial\n ? html`<div class=\"fw-dev-tooltip-note\">\n No compatible ${(combo as any).missingTracks.join(\", \")} codec\n </div>`\n : nothing}\n ${combo.compatible && combo.scoreBreakdown\n ? html`\n <div class=\"fw-dev-tooltip-score\">\n Score: ${combo.score.toFixed(2)}\n </div>\n <div class=\"fw-dev-tooltip-row\">\n Tracks [${combo.scoreBreakdown.trackTypes.join(\", \")}]:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.trackScore.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.tracks}</span\n >\n </div>\n <div class=\"fw-dev-tooltip-row\">\n Priority:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.priorityScore.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.priority}</span\n >\n </div>\n <div class=\"fw-dev-tooltip-row\">\n Source:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.sourceScore.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.source}</span\n >\n </div>\n\n ${typeof combo.scoreBreakdown.reliabilityScore === \"number\"\n ? html`\n <div class=\"fw-dev-tooltip-row\">\n Reliability:\n <span class=\"fw-dev-tooltip-value\"\n >${combo.scoreBreakdown.reliabilityScore.toFixed(\n 2\n )}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.reliability ??\n 0}</span\n >\n </div>\n `\n : nothing}\n ${typeof combo.scoreBreakdown.modeBonus === \"number\" &&\n combo.scoreBreakdown.modeBonus !== 0\n ? html`\n <div class=\"fw-dev-tooltip-row\">\n Mode (${this.playbackMode}):\n <span class=\"fw-dev-tooltip-bonus\"\n >+${combo.scoreBreakdown.modeBonus.toFixed(2)}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.mode ?? 0}</span\n >\n </div>\n `\n : nothing}\n ${typeof combo.scoreBreakdown.routingBonus === \"number\" &&\n combo.scoreBreakdown.routingBonus !== 0\n ? html`\n <div class=\"fw-dev-tooltip-row\">\n Routing:\n <span\n class=${classMap({\n \"fw-dev-tooltip-bonus\":\n combo.scoreBreakdown.routingBonus > 0,\n \"fw-dev-tooltip-penalty\":\n combo.scoreBreakdown.routingBonus < 0,\n })}\n >${combo.scoreBreakdown.routingBonus > 0\n ? \"+\"\n : \"\"}${combo.scoreBreakdown.routingBonus.toFixed(\n 2\n )}</span\n >\n <span class=\"fw-dev-tooltip-weight\"\n >x${combo.scoreBreakdown.weights.routing ?? 0}</span\n >\n </div>\n `\n : nothing}\n `\n : html`\n <div class=\"fw-dev-tooltip-error\">\n ${combo.incompatibleReason || \"Incompatible\"}\n </div>\n `}\n </div>\n `\n : nothing}\n </div>\n `;\n })}\n `}\n </div>\n </div>\n `;\n }\n\n protected render() {\n return html`\n <div class=\"fw-dev-panel\">\n <div class=\"fw-dev-header\">\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-tab\": true,\n \"fw-dev-tab--active\": this._activeTab === \"config\",\n })}\n @click=${() => {\n this._activeTab = \"config\";\n }}\n >\n Config\n </button>\n <button\n type=\"button\"\n class=${classMap({\n \"fw-dev-tab\": true,\n \"fw-dev-tab--active\": this._activeTab === \"stats\",\n })}\n @click=${() => {\n this._activeTab = \"stats\";\n }}\n >\n Stats\n </button>\n <div class=\"fw-dev-spacer\"></div>\n <button\n type=\"button\"\n class=\"fw-dev-close\"\n aria-label=\"Close dev mode panel\"\n @click=${() =>\n this.dispatchEvent(new CustomEvent(\"fw-close\", { bubbles: true, composed: true }))}\n >\n ${closeIcon()}\n </button>\n </div>\n\n ${this._activeTab === \"config\" ? this._renderConfigTab() : this._renderStatsTab()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fw-dev-mode-panel\": FwDevModePanel;\n }\n}\n"],"names":[],"mappings":"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"}