@livepeer-frameworks/streamcrafter-wc 0.1.1 → 0.1.3
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/dist/cjs/components/fw-sc-advanced.js +555 -71
- package/dist/cjs/components/fw-sc-advanced.js.map +1 -1
- package/dist/cjs/components/fw-streamcrafter.js +179 -1
- package/dist/cjs/components/fw-streamcrafter.js.map +1 -1
- package/dist/cjs/controllers/ingest-controller-host.js +34 -1
- package/dist/cjs/controllers/ingest-controller-host.js.map +1 -1
- package/dist/esm/components/fw-sc-advanced.js +556 -72
- package/dist/esm/components/fw-sc-advanced.js.map +1 -1
- package/dist/esm/components/fw-streamcrafter.js +180 -2
- package/dist/esm/components/fw-streamcrafter.js.map +1 -1
- package/dist/esm/controllers/ingest-controller-host.js +34 -1
- package/dist/esm/controllers/ingest-controller-host.js.map +1 -1
- package/dist/fw-streamcrafter.iife.js +646 -204
- package/dist/fw-streamcrafter.iife.js.map +1 -1
- package/dist/types/components/fw-sc-advanced.d.ts +12 -2
- package/dist/types/components/fw-streamcrafter.d.ts +12 -0
- package/dist/types/controllers/ingest-controller-host.d.ts +5 -0
- package/package.json +1 -1
- package/src/components/fw-sc-advanced.ts +569 -93
- package/src/components/fw-streamcrafter.ts +181 -1
- package/src/controllers/ingest-controller-host.ts +36 -1
|
@@ -8,98 +8,479 @@ var sharedStyles = require('../styles/shared-styles.js');
|
|
|
8
8
|
var utilityStyles = require('../styles/utility-styles.js');
|
|
9
9
|
var index = require('../icons/index.js');
|
|
10
10
|
|
|
11
|
+
function formatBitrate(bps) {
|
|
12
|
+
if (bps >= 1_000_000)
|
|
13
|
+
return `${(bps / 1_000_000).toFixed(1)} Mbps`;
|
|
14
|
+
return `${(bps / 1000).toFixed(0)} kbps`;
|
|
15
|
+
}
|
|
11
16
|
exports.FwScAdvanced = class FwScAdvanced extends lit.LitElement {
|
|
12
17
|
constructor() {
|
|
13
18
|
super(...arguments);
|
|
14
|
-
this.
|
|
19
|
+
this.compositorEnabled = false;
|
|
20
|
+
this.compositorRendererType = null;
|
|
21
|
+
this.compositorStats = null;
|
|
22
|
+
this.sceneCount = 0;
|
|
23
|
+
this.layerCount = 0;
|
|
24
|
+
this._activeTab = "audio";
|
|
15
25
|
}
|
|
16
26
|
render() {
|
|
17
27
|
return lit.html `
|
|
18
28
|
<div class="panel">
|
|
19
29
|
<div class="header">
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
<button
|
|
31
|
+
class=${classMap_js.classMap({ tab: true, "tab--active": this._activeTab === "audio" })}
|
|
32
|
+
@click=${() => {
|
|
33
|
+
this._activeTab = "audio";
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
Audio
|
|
37
|
+
</button>
|
|
38
|
+
<button
|
|
39
|
+
class=${classMap_js.classMap({ tab: true, "tab--active": this._activeTab === "stats" })}
|
|
40
|
+
@click=${() => {
|
|
24
41
|
this._activeTab = "stats";
|
|
25
42
|
}}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
>
|
|
44
|
+
Stats
|
|
45
|
+
</button>
|
|
46
|
+
<button
|
|
47
|
+
class=${classMap_js.classMap({ tab: true, "tab--active": this._activeTab === "info" })}
|
|
48
|
+
@click=${() => {
|
|
32
49
|
this._activeTab = "info";
|
|
33
50
|
}}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
>
|
|
52
|
+
Info
|
|
53
|
+
</button>
|
|
54
|
+
${this.compositorEnabled
|
|
55
|
+
? lit.html `
|
|
56
|
+
<button
|
|
57
|
+
class=${classMap_js.classMap({
|
|
58
|
+
tab: true,
|
|
59
|
+
"tab--active": this._activeTab === "compositor",
|
|
60
|
+
})}
|
|
61
|
+
@click=${() => {
|
|
62
|
+
this._activeTab = "compositor";
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
Comp
|
|
66
|
+
</button>
|
|
67
|
+
`
|
|
68
|
+
: lit.nothing}
|
|
69
|
+
<div style="flex:1"></div>
|
|
38
70
|
<button
|
|
39
71
|
class="close"
|
|
40
72
|
@click=${() => this.dispatchEvent(new CustomEvent("fw-close", { bubbles: true, composed: true }))}
|
|
41
|
-
aria-label="Close panel"
|
|
73
|
+
aria-label="Close advanced panel"
|
|
42
74
|
>
|
|
43
|
-
${index.xIcon(
|
|
75
|
+
${index.xIcon(12)}
|
|
44
76
|
</button>
|
|
45
77
|
</div>
|
|
46
78
|
<div class="body">
|
|
47
|
-
${this._activeTab === "
|
|
79
|
+
${this._activeTab === "audio"
|
|
80
|
+
? this._renderAudio()
|
|
81
|
+
: this._activeTab === "stats"
|
|
82
|
+
? this._renderStats()
|
|
83
|
+
: this._activeTab === "info"
|
|
84
|
+
? this._renderInfo()
|
|
85
|
+
: this._renderCompositor()}
|
|
48
86
|
</div>
|
|
49
87
|
</div>
|
|
50
88
|
`;
|
|
51
89
|
}
|
|
90
|
+
// ---- Audio Tab ----
|
|
91
|
+
_renderAudio() {
|
|
92
|
+
const s = this.ic.s;
|
|
93
|
+
const masterVolume = this.ic.getMasterVolume();
|
|
94
|
+
const audioLevel = s.audioLevel;
|
|
95
|
+
const levelColor = audioLevel > 0.9 ? "#f7768e" : audioLevel > 0.7 ? "#e0af68" : "#9ece6a";
|
|
96
|
+
const volColor = masterVolume > 1 ? "#e0af68" : masterVolume === 1 ? "#9ece6a" : "#c0caf5";
|
|
97
|
+
return lit.html `
|
|
98
|
+
<!-- Master Volume -->
|
|
99
|
+
<div class="section">
|
|
100
|
+
<div class="section-header">Master Volume</div>
|
|
101
|
+
<div style="display:flex;align-items:center;gap:12px">
|
|
102
|
+
<fw-sc-volume
|
|
103
|
+
.value=${masterVolume}
|
|
104
|
+
.min=${0}
|
|
105
|
+
.max=${2}
|
|
106
|
+
@fw-sc-volume-change=${(e) => this.ic.setMasterVolume(e.detail.value)}
|
|
107
|
+
></fw-sc-volume>
|
|
108
|
+
<span
|
|
109
|
+
style="font-size:14px;min-width:48px;text-align:right;color:${volColor}"
|
|
110
|
+
>
|
|
111
|
+
${Math.round(masterVolume * 100)}%
|
|
112
|
+
</span>
|
|
113
|
+
</div>
|
|
114
|
+
${masterVolume > 1
|
|
115
|
+
? lit.html `<div style="font-size:10px;color:#e0af68;margin-top:4px">
|
|
116
|
+
+${((masterVolume - 1) * 100).toFixed(0)}% boost
|
|
117
|
+
</div>`
|
|
118
|
+
: lit.nothing}
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<!-- Audio Level -->
|
|
122
|
+
<div class="section">
|
|
123
|
+
<div class="section-header">Output Level</div>
|
|
124
|
+
<div class="level-bar">
|
|
125
|
+
<div
|
|
126
|
+
class="level-fill"
|
|
127
|
+
style="width:${audioLevel * 100}%;background:${levelColor}"
|
|
128
|
+
></div>
|
|
129
|
+
</div>
|
|
130
|
+
<div class="level-labels">
|
|
131
|
+
<span>-60dB</span><span>0dB</span>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<!-- Audio Mixing Status -->
|
|
136
|
+
<div class="section">
|
|
137
|
+
<div style="display:flex;justify-content:space-between;align-items:center">
|
|
138
|
+
<span class="section-header" style="margin-bottom:0">Audio Mixing</span>
|
|
139
|
+
<span
|
|
140
|
+
class="badge"
|
|
141
|
+
style="background:rgba(158,206,106,0.2);color:#9ece6a"
|
|
142
|
+
>
|
|
143
|
+
ON
|
|
144
|
+
</span>
|
|
145
|
+
</div>
|
|
146
|
+
<div style="font-size:10px;color:#565f89;margin-top:4px">
|
|
147
|
+
Compressor + Limiter active
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<!-- Audio Processing -->
|
|
152
|
+
<div style="border-bottom:1px solid rgba(65,72,104,0.3)">
|
|
153
|
+
<div class="section-dark">
|
|
154
|
+
<span class="section-header" style="margin-bottom:0">Processing</span>
|
|
155
|
+
<span style="font-size:9px;color:#565f89">
|
|
156
|
+
profile: ${s.qualityProfile}
|
|
157
|
+
</span>
|
|
158
|
+
</div>
|
|
159
|
+
${this._renderToggle("Echo Cancellation", true)}
|
|
160
|
+
${this._renderToggle("Noise Suppression", true)}
|
|
161
|
+
${this._renderToggle("Auto Gain Control", true)}
|
|
162
|
+
</div>
|
|
163
|
+
`;
|
|
164
|
+
}
|
|
165
|
+
_renderToggle(label, checked) {
|
|
166
|
+
return lit.html `
|
|
167
|
+
<div class="processing-row">
|
|
168
|
+
<span class="processing-label">${label}</span>
|
|
169
|
+
<button
|
|
170
|
+
type="button"
|
|
171
|
+
role="switch"
|
|
172
|
+
aria-checked=${checked}
|
|
173
|
+
class="toggle ${checked ? "toggle--on" : "toggle--off"}"
|
|
174
|
+
>
|
|
175
|
+
<div class="toggle-knob"></div>
|
|
176
|
+
</button>
|
|
177
|
+
</div>
|
|
178
|
+
`;
|
|
179
|
+
}
|
|
180
|
+
// ---- Stats Tab ----
|
|
52
181
|
_renderStats() {
|
|
53
182
|
const s = this.ic.s;
|
|
54
183
|
const stats = s.stats;
|
|
184
|
+
const stateColor = s.state === "streaming"
|
|
185
|
+
? "#9ece6a"
|
|
186
|
+
: s.state === "connecting"
|
|
187
|
+
? "#7aa2f7"
|
|
188
|
+
: s.state === "error"
|
|
189
|
+
? "#f7768e"
|
|
190
|
+
: "#c0caf5";
|
|
55
191
|
return lit.html `
|
|
56
192
|
<div class="section">
|
|
57
|
-
<div class="
|
|
58
|
-
|
|
59
|
-
|
|
193
|
+
<div class="section-header" style="margin-bottom:4px">Connection</div>
|
|
194
|
+
<div style="font-size:14px;font-weight:600;color:${stateColor}">
|
|
195
|
+
${s.state.charAt(0).toUpperCase() + s.state.slice(1)}
|
|
196
|
+
</div>
|
|
60
197
|
</div>
|
|
61
198
|
${stats
|
|
62
199
|
? lit.html `
|
|
63
|
-
<div class="
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
200
|
+
<div class="row">
|
|
201
|
+
<span class="row-label">Bitrate</span>
|
|
202
|
+
<span class="row-value">
|
|
203
|
+
${formatBitrate(stats.video.bitrate + stats.audio.bitrate)}
|
|
204
|
+
</span>
|
|
205
|
+
</div>
|
|
206
|
+
<div class="row">
|
|
207
|
+
<span class="row-label">Video</span>
|
|
208
|
+
<span class="row-value" style="color:#7aa2f7">
|
|
209
|
+
${formatBitrate(stats.video.bitrate)}
|
|
210
|
+
</span>
|
|
211
|
+
</div>
|
|
212
|
+
<div class="row">
|
|
213
|
+
<span class="row-label">Audio</span>
|
|
214
|
+
<span class="row-value" style="color:#7aa2f7">
|
|
215
|
+
${formatBitrate(stats.audio.bitrate)}
|
|
216
|
+
</span>
|
|
217
|
+
</div>
|
|
218
|
+
<div class="row">
|
|
219
|
+
<span class="row-label">Frame Rate</span>
|
|
220
|
+
<span class="row-value">
|
|
221
|
+
${stats.video.framesPerSecond.toFixed(0)} fps
|
|
222
|
+
</span>
|
|
223
|
+
</div>
|
|
224
|
+
<div class="row">
|
|
225
|
+
<span class="row-label">Frames Encoded</span>
|
|
226
|
+
<span class="row-value">${stats.video.framesEncoded}</span>
|
|
227
|
+
</div>
|
|
228
|
+
${stats.video.packetsLost > 0 || stats.audio.packetsLost > 0
|
|
229
|
+
? lit.html `
|
|
230
|
+
<div class="row">
|
|
231
|
+
<span class="row-label">Packets Lost</span>
|
|
232
|
+
<span class="row-value" style="color:#f7768e">
|
|
233
|
+
${stats.video.packetsLost + stats.audio.packetsLost}
|
|
234
|
+
</span>
|
|
235
|
+
</div>
|
|
236
|
+
`
|
|
237
|
+
: lit.nothing}
|
|
238
|
+
<div class="row">
|
|
239
|
+
<span class="row-label">RTT</span>
|
|
240
|
+
<span
|
|
241
|
+
class="row-value"
|
|
242
|
+
style="color:${stats.connection.rtt > 200 ? "#e0af68" : "#c0caf5"}"
|
|
243
|
+
>
|
|
244
|
+
${stats.connection.rtt.toFixed(0)} ms
|
|
245
|
+
</span>
|
|
246
|
+
</div>
|
|
247
|
+
<div class="row">
|
|
248
|
+
<span class="row-label">ICE State</span>
|
|
249
|
+
<span class="row-value" style="text-transform:capitalize">
|
|
250
|
+
${stats.connection.iceState}
|
|
251
|
+
</span>
|
|
252
|
+
</div>
|
|
253
|
+
`
|
|
254
|
+
: lit.html `
|
|
255
|
+
<div style="color:#565f89;text-align:center;padding:24px">
|
|
256
|
+
${s.state === "streaming"
|
|
257
|
+
? "Waiting for stats..."
|
|
258
|
+
: "Start streaming to see stats"}
|
|
259
|
+
</div>
|
|
260
|
+
`}
|
|
261
|
+
${s.error
|
|
262
|
+
? lit.html `
|
|
263
|
+
<div
|
|
264
|
+
style="padding:12px;border-top:1px solid rgba(247,118,142,0.3);background:rgba(247,118,142,0.1)"
|
|
265
|
+
>
|
|
266
|
+
<div class="section-header" style="color:#f7768e;margin-bottom:4px">
|
|
267
|
+
Error
|
|
268
|
+
</div>
|
|
269
|
+
<div style="font-size:12px;color:#f7768e">${s.error}</div>
|
|
71
270
|
</div>
|
|
72
271
|
`
|
|
73
272
|
: lit.nothing}
|
|
74
273
|
${s.encoderStats
|
|
75
274
|
? lit.html `
|
|
76
|
-
<div
|
|
77
|
-
<div class="
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
275
|
+
<div style="border-top:1px solid rgba(65,72,104,0.3)">
|
|
276
|
+
<div class="section-dark">
|
|
277
|
+
<span class="section-header" style="margin-bottom:0">Encoder</span>
|
|
278
|
+
</div>
|
|
279
|
+
<div class="row">
|
|
280
|
+
<span class="row-label">Video frames</span>
|
|
281
|
+
<span class="row-value">${s.encoderStats.video.framesEncoded}</span>
|
|
282
|
+
</div>
|
|
283
|
+
<div class="row">
|
|
284
|
+
<span class="row-label">Video pending</span>
|
|
285
|
+
<span
|
|
286
|
+
class="row-value"
|
|
287
|
+
style="color:${s.encoderStats.video.framesPending > 5
|
|
288
|
+
? "#e0af68"
|
|
289
|
+
: "#c0caf5"}"
|
|
290
|
+
>
|
|
291
|
+
${s.encoderStats.video.framesPending}
|
|
292
|
+
</span>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="row">
|
|
295
|
+
<span class="row-label">Audio samples</span>
|
|
296
|
+
<span class="row-value">${s.encoderStats.audio.samplesEncoded}</span>
|
|
297
|
+
</div>
|
|
81
298
|
</div>
|
|
82
299
|
`
|
|
83
300
|
: lit.nothing}
|
|
84
301
|
`;
|
|
85
302
|
}
|
|
303
|
+
// ---- Info Tab ----
|
|
86
304
|
_renderInfo() {
|
|
87
305
|
const s = this.ic.s;
|
|
88
306
|
return lit.html `
|
|
89
307
|
<div class="section">
|
|
90
|
-
<div class="
|
|
91
|
-
|
|
92
|
-
|
|
308
|
+
<div class="section-header" style="margin-bottom:4px">Quality Profile</div>
|
|
309
|
+
<div style="font-size:14px;color:#c0caf5;text-transform:capitalize">
|
|
310
|
+
${s.qualityProfile}
|
|
311
|
+
</div>
|
|
93
312
|
</div>
|
|
313
|
+
|
|
94
314
|
<div class="section">
|
|
95
|
-
<div class="
|
|
96
|
-
${
|
|
97
|
-
|
|
98
|
-
|
|
315
|
+
<div class="section-header" style="margin-bottom:4px">Configuration</div>
|
|
316
|
+
${this._simpleRow("WebCodecs", s.isWebCodecsAvailable ? "Available" : "Unavailable")}
|
|
317
|
+
${this._simpleRow("WebCodecs Active", s.isWebCodecsActive ? "Yes" : s.useWebCodecs ? "Pending" : "No")}
|
|
318
|
+
${this._simpleRow("Sources", String(s.sources.length))}
|
|
319
|
+
</div>
|
|
320
|
+
|
|
321
|
+
${s.sources.length > 0
|
|
322
|
+
? lit.html `
|
|
323
|
+
<div style="border-bottom:1px solid rgba(65,72,104,0.3)">
|
|
324
|
+
<div class="section-dark">
|
|
325
|
+
<span class="section-header" style="margin-bottom:0">
|
|
326
|
+
Sources (${s.sources.length})
|
|
327
|
+
</span>
|
|
328
|
+
</div>
|
|
329
|
+
${s.sources.map((source, idx) => lit.html `
|
|
330
|
+
<div
|
|
331
|
+
style="padding:8px 12px;${idx > 0
|
|
332
|
+
? "border-top:1px solid rgba(65,72,104,0.2)"
|
|
333
|
+
: ""}"
|
|
334
|
+
>
|
|
335
|
+
<div style="display:flex;align-items:center;gap:8px">
|
|
336
|
+
<span
|
|
337
|
+
class="source-type"
|
|
338
|
+
style="background:${source.type === "camera"
|
|
339
|
+
? "rgba(122,162,247,0.2)"
|
|
340
|
+
: source.type === "screen"
|
|
341
|
+
? "rgba(158,206,106,0.2)"
|
|
342
|
+
: "rgba(224,175,104,0.2)"};color:${source.type === "camera"
|
|
343
|
+
? "#7aa2f7"
|
|
344
|
+
: source.type === "screen"
|
|
345
|
+
? "#9ece6a"
|
|
346
|
+
: "#e0af68"}"
|
|
347
|
+
>
|
|
348
|
+
${source.type}
|
|
349
|
+
</span>
|
|
350
|
+
<span
|
|
351
|
+
style="color:#c0caf5;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
|
|
352
|
+
>
|
|
353
|
+
${source.label}
|
|
354
|
+
</span>
|
|
355
|
+
</div>
|
|
356
|
+
<div
|
|
357
|
+
style="display:flex;gap:12px;margin-top:4px;font-size:10px;color:#565f89"
|
|
358
|
+
>
|
|
359
|
+
<span>Vol: ${Math.round(source.volume * 100)}%</span>
|
|
360
|
+
${source.muted
|
|
361
|
+
? lit.html `<span style="color:#f7768e">Muted</span>`
|
|
362
|
+
: lit.nothing}
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
`)}
|
|
366
|
+
</div>
|
|
367
|
+
`
|
|
368
|
+
: lit.nothing}
|
|
369
|
+
`;
|
|
370
|
+
}
|
|
371
|
+
// ---- Compositor Tab ----
|
|
372
|
+
_renderCompositor() {
|
|
373
|
+
const s = this.ic.s;
|
|
374
|
+
const rt = this.compositorRendererType;
|
|
375
|
+
const stats = this.compositorStats;
|
|
376
|
+
const rendererColor = rt === "webgpu" ? "#bb9af7" : rt === "webgl" ? "#7aa2f7" : "#9ece6a";
|
|
377
|
+
const rendererLabel = rt === "webgpu"
|
|
378
|
+
? "WebGPU"
|
|
379
|
+
: rt === "webgl"
|
|
380
|
+
? "WebGL"
|
|
381
|
+
: rt === "canvas2d"
|
|
382
|
+
? "Canvas2D"
|
|
383
|
+
: "Not initialized";
|
|
384
|
+
return lit.html `
|
|
385
|
+
<div class="section">
|
|
386
|
+
<div class="section-header">Renderer</div>
|
|
387
|
+
<div style="font-size:14px;font-weight:600;color:${rendererColor}">
|
|
388
|
+
${rendererLabel}
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
|
|
392
|
+
${stats
|
|
393
|
+
? lit.html `
|
|
394
|
+
<div style="border-bottom:1px solid rgba(65,72,104,0.3)">
|
|
395
|
+
<div class="section-dark">
|
|
396
|
+
<span class="section-header" style="margin-bottom:0">Performance</span>
|
|
397
|
+
</div>
|
|
398
|
+
<div class="row">
|
|
399
|
+
<span class="row-label">Frame Rate</span>
|
|
400
|
+
<span class="row-value">${stats.fps} fps</span>
|
|
401
|
+
</div>
|
|
402
|
+
<div class="row">
|
|
403
|
+
<span class="row-label">Frame Time</span>
|
|
404
|
+
<span
|
|
405
|
+
class="row-value"
|
|
406
|
+
style="color:${stats.frameTimeMs > 16 ? "#e0af68" : "#c0caf5"}"
|
|
407
|
+
>
|
|
408
|
+
${stats.frameTimeMs.toFixed(2)} ms
|
|
409
|
+
</span>
|
|
410
|
+
</div>
|
|
411
|
+
${stats.gpuMemoryMB !== undefined
|
|
412
|
+
? lit.html `
|
|
413
|
+
<div class="row">
|
|
414
|
+
<span class="row-label">GPU Memory</span>
|
|
415
|
+
<span class="row-value">
|
|
416
|
+
${stats.gpuMemoryMB.toFixed(1)} MB
|
|
417
|
+
</span>
|
|
418
|
+
</div>
|
|
419
|
+
`
|
|
420
|
+
: lit.nothing}
|
|
421
|
+
</div>
|
|
422
|
+
`
|
|
423
|
+
: lit.nothing}
|
|
424
|
+
|
|
425
|
+
<div style="border-bottom:1px solid rgba(65,72,104,0.3)">
|
|
426
|
+
<div class="section-dark">
|
|
427
|
+
<span class="section-header" style="margin-bottom:0">Composition</span>
|
|
428
|
+
</div>
|
|
429
|
+
<div class="row">
|
|
430
|
+
<span class="row-label">Scenes</span>
|
|
431
|
+
<span class="row-value">${this.sceneCount}</span>
|
|
432
|
+
</div>
|
|
433
|
+
<div class="row">
|
|
434
|
+
<span class="row-label">Layers</span>
|
|
435
|
+
<span class="row-value">${this.layerCount}</span>
|
|
436
|
+
</div>
|
|
437
|
+
</div>
|
|
438
|
+
|
|
439
|
+
<!-- Encoder -->
|
|
440
|
+
<div style="border-bottom:1px solid rgba(65,72,104,0.3)">
|
|
441
|
+
<div class="section-dark">
|
|
442
|
+
<span class="section-header" style="margin-bottom:0">Encoder</span>
|
|
443
|
+
</div>
|
|
444
|
+
<div class="row">
|
|
445
|
+
<span class="row-label">Type</span>
|
|
446
|
+
<span
|
|
447
|
+
class="badge"
|
|
448
|
+
style="background:${s.useWebCodecs && s.isWebCodecsAvailable
|
|
449
|
+
? "rgba(187,154,247,0.2)"
|
|
450
|
+
: "rgba(122,162,247,0.2)"};color:${s.useWebCodecs && s.isWebCodecsAvailable
|
|
451
|
+
? "#bb9af7"
|
|
452
|
+
: "#7aa2f7"}"
|
|
453
|
+
>
|
|
454
|
+
${s.useWebCodecs && s.isWebCodecsAvailable ? "WebCodecs" : "Browser"}
|
|
455
|
+
${s.state === "streaming"
|
|
456
|
+
? lit.html `<span style="opacity:0.7;margin-left:4px">
|
|
457
|
+
${s.isWebCodecsActive ? "(active)" : "(pending)"}
|
|
458
|
+
</span>`
|
|
459
|
+
: lit.nothing}
|
|
460
|
+
</span>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="processing-row">
|
|
463
|
+
<span class="processing-label">Use WebCodecs</span>
|
|
464
|
+
<button
|
|
465
|
+
type="button"
|
|
466
|
+
role="switch"
|
|
467
|
+
aria-checked=${s.useWebCodecs}
|
|
468
|
+
class="toggle ${s.useWebCodecs ? "toggle--on" : "toggle--off"}"
|
|
469
|
+
?disabled=${s.state === "streaming" || !s.isWebCodecsAvailable}
|
|
470
|
+
@click=${() => this.ic.setUseWebCodecs(!s.useWebCodecs)}
|
|
471
|
+
>
|
|
472
|
+
<div class="toggle-knob"></div>
|
|
473
|
+
</button>
|
|
474
|
+
</div>
|
|
475
|
+
${!s.isWebCodecsAvailable
|
|
476
|
+
? lit.html `<div style="padding:8px 12px;font-size:10px;color:#f7768e">
|
|
477
|
+
Not available - RTCRtpScriptTransform unsupported
|
|
478
|
+
</div>`
|
|
479
|
+
: lit.nothing}
|
|
99
480
|
</div>
|
|
100
481
|
`;
|
|
101
482
|
}
|
|
102
|
-
|
|
483
|
+
_simpleRow(label, value) {
|
|
103
484
|
return lit.html `<div class="row">
|
|
104
485
|
<span class="row-label">${label}</span><span class="row-value">${value}</span>
|
|
105
486
|
</div>`;
|
|
@@ -113,68 +494,80 @@ exports.FwScAdvanced.styles = [
|
|
|
113
494
|
display: block;
|
|
114
495
|
}
|
|
115
496
|
.panel {
|
|
116
|
-
width:
|
|
497
|
+
width: 280px;
|
|
117
498
|
height: 100%;
|
|
118
|
-
border-left: 1px solid rgba(
|
|
499
|
+
border-left: 1px solid rgba(65, 72, 104, 0.5);
|
|
119
500
|
background: #1a1b26;
|
|
120
|
-
|
|
121
|
-
|
|
501
|
+
display: flex;
|
|
502
|
+
flex-direction: column;
|
|
503
|
+
font-size: 12px;
|
|
504
|
+
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, monospace;
|
|
122
505
|
color: #a9b1d6;
|
|
506
|
+
flex-shrink: 0;
|
|
507
|
+
z-index: 40;
|
|
123
508
|
}
|
|
124
509
|
.header {
|
|
125
510
|
display: flex;
|
|
126
511
|
align-items: center;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
border-bottom: 1px solid rgba(90, 96, 127, 0.3);
|
|
130
|
-
}
|
|
131
|
-
.tabs {
|
|
132
|
-
display: flex;
|
|
133
|
-
gap: 0.5rem;
|
|
512
|
+
border-bottom: 1px solid rgba(65, 72, 104, 0.3);
|
|
513
|
+
background: #16161e;
|
|
134
514
|
}
|
|
135
515
|
.tab {
|
|
136
|
-
padding:
|
|
516
|
+
padding: 8px 12px;
|
|
517
|
+
font-size: 10px;
|
|
518
|
+
text-transform: uppercase;
|
|
519
|
+
letter-spacing: 0.05em;
|
|
520
|
+
font-weight: 600;
|
|
137
521
|
border: none;
|
|
138
|
-
background:
|
|
522
|
+
background: transparent;
|
|
139
523
|
color: #565f89;
|
|
140
|
-
font-size: 0.6875rem;
|
|
141
|
-
font-weight: 600;
|
|
142
524
|
cursor: pointer;
|
|
143
|
-
|
|
525
|
+
transition: all 0.15s;
|
|
144
526
|
}
|
|
145
527
|
.tab--active {
|
|
528
|
+
background: #1a1b26;
|
|
146
529
|
color: #c0caf5;
|
|
147
|
-
background: rgba(90, 96, 127, 0.2);
|
|
148
530
|
}
|
|
149
531
|
.close {
|
|
150
532
|
display: flex;
|
|
151
|
-
background:
|
|
533
|
+
background: transparent;
|
|
152
534
|
border: none;
|
|
153
535
|
color: #565f89;
|
|
154
536
|
cursor: pointer;
|
|
155
|
-
padding:
|
|
537
|
+
padding: 8px;
|
|
538
|
+
transition: color 0.15s;
|
|
156
539
|
}
|
|
157
540
|
.close:hover {
|
|
158
541
|
color: #c0caf5;
|
|
159
542
|
}
|
|
160
543
|
.body {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
.section {
|
|
164
|
-
margin-bottom: 0.75rem;
|
|
544
|
+
flex: 1;
|
|
545
|
+
overflow-y: auto;
|
|
165
546
|
}
|
|
166
|
-
.
|
|
167
|
-
font-size:
|
|
168
|
-
|
|
547
|
+
.section-header {
|
|
548
|
+
font-size: 10px;
|
|
549
|
+
color: #565f89;
|
|
169
550
|
text-transform: uppercase;
|
|
170
551
|
letter-spacing: 0.05em;
|
|
171
|
-
|
|
172
|
-
margin-bottom:
|
|
552
|
+
font-weight: 600;
|
|
553
|
+
margin-bottom: 8px;
|
|
554
|
+
}
|
|
555
|
+
.section {
|
|
556
|
+
padding: 12px;
|
|
557
|
+
border-bottom: 1px solid rgba(65, 72, 104, 0.3);
|
|
558
|
+
}
|
|
559
|
+
.section-dark {
|
|
560
|
+
padding: 8px 12px;
|
|
561
|
+
background: #16161e;
|
|
562
|
+
display: flex;
|
|
563
|
+
justify-content: space-between;
|
|
564
|
+
align-items: center;
|
|
173
565
|
}
|
|
174
566
|
.row {
|
|
175
567
|
display: flex;
|
|
176
568
|
justify-content: space-between;
|
|
177
|
-
padding:
|
|
569
|
+
padding: 8px 12px;
|
|
570
|
+
border-top: 1px solid rgba(65, 72, 104, 0.2);
|
|
178
571
|
}
|
|
179
572
|
.row-label {
|
|
180
573
|
color: #565f89;
|
|
@@ -184,11 +577,102 @@ exports.FwScAdvanced.styles = [
|
|
|
184
577
|
font-family: ui-monospace, monospace;
|
|
185
578
|
font-variant-numeric: tabular-nums;
|
|
186
579
|
}
|
|
580
|
+
.level-bar {
|
|
581
|
+
height: 8px;
|
|
582
|
+
background: rgba(65, 72, 104, 0.3);
|
|
583
|
+
border-radius: 4px;
|
|
584
|
+
overflow: hidden;
|
|
585
|
+
}
|
|
586
|
+
.level-fill {
|
|
587
|
+
height: 100%;
|
|
588
|
+
transition: all 75ms;
|
|
589
|
+
}
|
|
590
|
+
.level-labels {
|
|
591
|
+
display: flex;
|
|
592
|
+
justify-content: space-between;
|
|
593
|
+
font-size: 10px;
|
|
594
|
+
color: #565f89;
|
|
595
|
+
margin-top: 4px;
|
|
596
|
+
}
|
|
597
|
+
.badge {
|
|
598
|
+
font-size: 12px;
|
|
599
|
+
font-family: monospace;
|
|
600
|
+
padding: 2px 6px;
|
|
601
|
+
}
|
|
602
|
+
.toggle {
|
|
603
|
+
position: relative;
|
|
604
|
+
display: inline-flex;
|
|
605
|
+
height: 20px;
|
|
606
|
+
width: 36px;
|
|
607
|
+
flex-shrink: 0;
|
|
608
|
+
cursor: pointer;
|
|
609
|
+
border-radius: 10px;
|
|
610
|
+
border: 2px solid transparent;
|
|
611
|
+
transition: background 0.2s;
|
|
612
|
+
padding: 0;
|
|
613
|
+
}
|
|
614
|
+
.toggle:disabled {
|
|
615
|
+
opacity: 0.5;
|
|
616
|
+
cursor: not-allowed;
|
|
617
|
+
}
|
|
618
|
+
.toggle-knob {
|
|
619
|
+
position: absolute;
|
|
620
|
+
top: 2px;
|
|
621
|
+
width: 12px;
|
|
622
|
+
height: 12px;
|
|
623
|
+
border-radius: 50%;
|
|
624
|
+
background: white;
|
|
625
|
+
transition: left 0.2s;
|
|
626
|
+
}
|
|
627
|
+
.toggle--on {
|
|
628
|
+
background: #7aa2f7;
|
|
629
|
+
}
|
|
630
|
+
.toggle--off {
|
|
631
|
+
background: rgba(65, 72, 104, 0.5);
|
|
632
|
+
}
|
|
633
|
+
.toggle--on .toggle-knob {
|
|
634
|
+
left: 18px;
|
|
635
|
+
}
|
|
636
|
+
.toggle--off .toggle-knob {
|
|
637
|
+
left: 4px;
|
|
638
|
+
}
|
|
639
|
+
.processing-row {
|
|
640
|
+
display: flex;
|
|
641
|
+
justify-content: space-between;
|
|
642
|
+
align-items: center;
|
|
643
|
+
padding: 8px 12px;
|
|
644
|
+
border-top: 1px solid rgba(65, 72, 104, 0.2);
|
|
645
|
+
}
|
|
646
|
+
.processing-label {
|
|
647
|
+
font-size: 12px;
|
|
648
|
+
color: #a9b1d6;
|
|
649
|
+
}
|
|
650
|
+
.source-type {
|
|
651
|
+
font-size: 10px;
|
|
652
|
+
font-family: monospace;
|
|
653
|
+
padding: 2px 6px;
|
|
654
|
+
text-transform: uppercase;
|
|
655
|
+
}
|
|
187
656
|
`,
|
|
188
657
|
];
|
|
189
658
|
tslib_es6.__decorate([
|
|
190
659
|
decorators_js.property({ attribute: false })
|
|
191
660
|
], exports.FwScAdvanced.prototype, "ic", void 0);
|
|
661
|
+
tslib_es6.__decorate([
|
|
662
|
+
decorators_js.property({ type: Boolean, attribute: "compositor-enabled" })
|
|
663
|
+
], exports.FwScAdvanced.prototype, "compositorEnabled", void 0);
|
|
664
|
+
tslib_es6.__decorate([
|
|
665
|
+
decorators_js.property({ type: String, attribute: "compositor-renderer" })
|
|
666
|
+
], exports.FwScAdvanced.prototype, "compositorRendererType", void 0);
|
|
667
|
+
tslib_es6.__decorate([
|
|
668
|
+
decorators_js.property({ attribute: false })
|
|
669
|
+
], exports.FwScAdvanced.prototype, "compositorStats", void 0);
|
|
670
|
+
tslib_es6.__decorate([
|
|
671
|
+
decorators_js.property({ type: Number, attribute: "scene-count" })
|
|
672
|
+
], exports.FwScAdvanced.prototype, "sceneCount", void 0);
|
|
673
|
+
tslib_es6.__decorate([
|
|
674
|
+
decorators_js.property({ type: Number, attribute: "layer-count" })
|
|
675
|
+
], exports.FwScAdvanced.prototype, "layerCount", void 0);
|
|
192
676
|
tslib_es6.__decorate([
|
|
193
677
|
decorators_js.state()
|
|
194
678
|
], exports.FwScAdvanced.prototype, "_activeTab", void 0);
|