@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 +24 -0
- package/README.md +164 -0
- package/dist/esm/components/controls/fw-skip-button.js +1 -1
- package/dist/esm/components/controls/fw-skip-button.js.map +1 -1
- package/dist/esm/components/fw-dev-mode-panel.js +21 -11
- package/dist/esm/components/fw-dev-mode-panel.js.map +1 -1
- package/dist/esm/components/fw-player-controls.js +6 -5
- package/dist/esm/components/fw-player-controls.js.map +1 -1
- package/dist/esm/components/fw-player.js +17 -13
- package/dist/esm/components/fw-player.js.map +1 -1
- package/dist/esm/components/fw-seek-bar.js +18 -10
- package/dist/esm/components/fw-seek-bar.js.map +1 -1
- package/dist/esm/components/fw-subtitle-renderer.js +2 -2
- package/dist/esm/components/fw-subtitle-renderer.js.map +1 -1
- package/dist/esm/controllers/player-controller-host.js +6 -2
- package/dist/esm/controllers/player-controller-host.js.map +1 -1
- package/dist/esm/styles/shared-styles.js +40 -4
- package/dist/esm/styles/shared-styles.js.map +1 -1
- package/dist/fw-player.iife.js +250 -203
- package/package.json +15 -15
- package/src/components/controls/fw-skip-button.ts +1 -1
- package/src/components/fw-dev-mode-panel.ts +21 -11
- package/src/components/fw-player-controls.ts +10 -7
- package/src/components/fw-player.ts +17 -13
- package/src/components/fw-seek-bar.ts +18 -10
- package/src/components/fw-subtitle-renderer.ts +2 -2
- package/src/controllers/player-controller-host.ts +6 -2
- package/src/styles/shared-styles.ts +40 -4
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;
|
|
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
|
-
|
|
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 && !
|
|
620
|
+
const scoreClass = !combo.compatible && !isWarn
|
|
619
621
|
? "fw-dev-combo-score--disabled"
|
|
620
|
-
:
|
|
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 && !
|
|
631
|
+
: !combo.compatible && !isWarn
|
|
630
632
|
? "fw-dev-combo-rank--disabled"
|
|
631
|
-
:
|
|
633
|
+
: isWarn
|
|
632
634
|
? "fw-dev-combo-rank--warn"
|
|
633
635
|
: "";
|
|
634
|
-
const typeClass = !combo.compatible && !
|
|
636
|
+
const typeClass = !combo.compatible && !isWarn
|
|
635
637
|
? "fw-dev-combo-type--disabled"
|
|
636
|
-
:
|
|
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 && !
|
|
654
|
-
"fw-dev-combo-btn--codec-warn":
|
|
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
|
-
:
|
|
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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"}
|