@livepeer-frameworks/player-svelte 0.1.2 → 0.2.1
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 +6 -2
- package/dist/DevModePanel.svelte +53 -16
- package/dist/IdleScreen.svelte +36 -28
- package/dist/LoadingScreen.svelte +107 -67
- package/dist/LoadingScreen.svelte.bak +702 -0
- package/dist/Player.svelte +200 -53
- package/dist/Player.svelte.d.ts +6 -1
- package/dist/PlayerControls.svelte +114 -32
- package/dist/PlayerControls.svelte.d.ts +3 -0
- package/dist/StreamStateOverlay.svelte +33 -21
- package/dist/SubtitleRenderer.svelte +2 -2
- package/dist/controls/FullscreenButton.svelte +26 -0
- package/dist/controls/FullscreenButton.svelte.d.ts +3 -0
- package/dist/controls/LiveBadge.svelte +23 -0
- package/dist/controls/LiveBadge.svelte.d.ts +3 -0
- package/dist/controls/PlayButton.svelte +26 -0
- package/dist/controls/PlayButton.svelte.d.ts +3 -0
- package/dist/controls/SettingsMenu.svelte +208 -0
- package/dist/controls/SettingsMenu.svelte.d.ts +28 -0
- package/dist/controls/SkipButton.svelte +33 -0
- package/dist/controls/SkipButton.svelte.d.ts +7 -0
- package/dist/controls/TimeDisplay.svelte +18 -0
- package/dist/controls/TimeDisplay.svelte.d.ts +3 -0
- package/dist/controls/VolumeControl.svelte +26 -0
- package/dist/controls/VolumeControl.svelte.d.ts +3 -0
- package/dist/controls/index.d.ts +7 -0
- package/dist/controls/index.js +7 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -1
- package/dist/stores/i18n.d.ts +3 -0
- package/dist/stores/i18n.js +4 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.js +2 -0
- package/dist/stores/playerController.d.ts +2 -0
- package/dist/stores/playerController.js +4 -0
- package/package.json +19 -19
- package/src/DevModePanel.svelte +53 -16
- package/src/IdleScreen.svelte +12 -4
- package/src/LoadingScreen.svelte +90 -50
- package/src/LoadingScreen.svelte.bak +702 -0
- package/src/Player.svelte +200 -53
- package/src/PlayerControls.svelte +114 -32
- package/src/StreamStateOverlay.svelte +17 -5
- package/src/controls/FullscreenButton.svelte +26 -0
- package/src/controls/LiveBadge.svelte +23 -0
- package/src/controls/PlayButton.svelte +26 -0
- package/src/controls/SettingsMenu.svelte +208 -0
- package/src/controls/SkipButton.svelte +33 -0
- package/src/controls/TimeDisplay.svelte +18 -0
- package/src/controls/VolumeControl.svelte +26 -0
- package/src/controls/index.ts +7 -0
- package/src/index.ts +10 -0
- package/src/stores/i18n.ts +7 -0
- package/src/stores/index.ts +3 -0
- package/src/stores/playerController.ts +7 -0
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
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Svelte wrapper for the FrameWorks player. Resolves endpoints via Gateway or Mist and renders the best available player (WebCodecs, HLS, etc).
|
|
4
4
|
|
|
5
|
-
**Docs:** `
|
|
5
|
+
**Docs:** `logbook.frameworks.network`
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -35,7 +35,11 @@ Notes:
|
|
|
35
35
|
### Direct MistServer Node (mistUrl)
|
|
36
36
|
|
|
37
37
|
```svelte
|
|
38
|
-
<Player
|
|
38
|
+
<Player
|
|
39
|
+
contentType="live"
|
|
40
|
+
contentId="pk_..."
|
|
41
|
+
options={{ mistUrl: "https://edge-egress.example.com" }}
|
|
42
|
+
/>
|
|
39
43
|
```
|
|
40
44
|
|
|
41
45
|
### Styles
|
package/dist/DevModePanel.svelte
CHANGED
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
let internalIsOpen = $state(false);
|
|
68
68
|
let activeTab = $state<"config" | "stats">("config");
|
|
69
69
|
let hoveredComboIndex = $state<number | null>(null);
|
|
70
|
-
let
|
|
70
|
+
let tooltipPos = $state<{ top: number; left: number } | null>(null);
|
|
71
71
|
let showDisabledPlayers = $state(false);
|
|
72
72
|
let comboListRef: HTMLDivElement | undefined = $state();
|
|
73
73
|
|
|
@@ -163,14 +163,12 @@
|
|
|
163
163
|
|
|
164
164
|
function handleComboHover(index: number, e: MouseEvent) {
|
|
165
165
|
hoveredComboIndex = index;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
tooltipAbove = relativePosition > 0.6;
|
|
173
|
-
}
|
|
166
|
+
const row = e.currentTarget as HTMLElement;
|
|
167
|
+
const rowRect = row.getBoundingClientRect();
|
|
168
|
+
tooltipPos = {
|
|
169
|
+
top: Math.max(8, Math.min(rowRect.top, window.innerHeight - 200)),
|
|
170
|
+
left: Math.max(8, rowRect.left - 228),
|
|
171
|
+
};
|
|
174
172
|
}
|
|
175
173
|
|
|
176
174
|
// Quality monitoring
|
|
@@ -387,7 +385,10 @@
|
|
|
387
385
|
class="fw-dev-combo"
|
|
388
386
|
role="listitem"
|
|
389
387
|
onmouseenter={(e) => handleComboHover(index, e)}
|
|
390
|
-
onmouseleave={() =>
|
|
388
|
+
onmouseleave={() => {
|
|
389
|
+
hoveredComboIndex = null;
|
|
390
|
+
tooltipPos = null;
|
|
391
|
+
}}
|
|
391
392
|
>
|
|
392
393
|
<button
|
|
393
394
|
type="button"
|
|
@@ -446,12 +447,10 @@
|
|
|
446
447
|
</button>
|
|
447
448
|
|
|
448
449
|
<!-- Tooltip -->
|
|
449
|
-
{#if hoveredComboIndex === index}
|
|
450
|
+
{#if hoveredComboIndex === index && tooltipPos}
|
|
450
451
|
<div
|
|
451
|
-
class=
|
|
452
|
-
|
|
453
|
-
tooltipAbove ? "fw-dev-tooltip--above" : "fw-dev-tooltip--below"
|
|
454
|
-
)}
|
|
452
|
+
class="fw-dev-tooltip"
|
|
453
|
+
style="top: {tooltipPos.top}px; left: {tooltipPos.left}px;"
|
|
455
454
|
>
|
|
456
455
|
<div class="fw-dev-tooltip-header">
|
|
457
456
|
<div class="fw-dev-tooltip-title">{combo.playerName}</div>
|
|
@@ -467,7 +466,8 @@
|
|
|
467
466
|
{#if combo.compatible && combo.scoreBreakdown}
|
|
468
467
|
<div class="fw-dev-tooltip-score">Score: {combo.score.toFixed(2)}</div>
|
|
469
468
|
<div class="fw-dev-tooltip-row">
|
|
470
|
-
Tracks
|
|
469
|
+
Tracks [{combo.scoreBreakdown.trackTypes.join(", ")}]:
|
|
470
|
+
<span class="fw-dev-tooltip-value"
|
|
471
471
|
>{combo.scoreBreakdown.trackScore.toFixed(2)}</span
|
|
472
472
|
>
|
|
473
473
|
<span class="fw-dev-tooltip-weight"
|
|
@@ -490,6 +490,43 @@
|
|
|
490
490
|
>x{combo.scoreBreakdown.weights.source}</span
|
|
491
491
|
>
|
|
492
492
|
</div>
|
|
493
|
+
{#if combo.scoreBreakdown.reliabilityScore !== undefined}
|
|
494
|
+
<div class="fw-dev-tooltip-row">
|
|
495
|
+
Reliability: <span class="fw-dev-tooltip-value"
|
|
496
|
+
>{combo.scoreBreakdown.reliabilityScore.toFixed(2)}</span
|
|
497
|
+
>
|
|
498
|
+
<span class="fw-dev-tooltip-weight"
|
|
499
|
+
>x{combo.scoreBreakdown.weights.reliability ?? 0}</span
|
|
500
|
+
>
|
|
501
|
+
</div>
|
|
502
|
+
{/if}
|
|
503
|
+
{#if combo.scoreBreakdown.modeBonus !== undefined && combo.scoreBreakdown.modeBonus !== 0}
|
|
504
|
+
<div class="fw-dev-tooltip-row">
|
|
505
|
+
Mode ({playbackMode}):
|
|
506
|
+
<span class="fw-dev-tooltip-bonus"
|
|
507
|
+
>+{combo.scoreBreakdown.modeBonus.toFixed(2)}</span
|
|
508
|
+
>
|
|
509
|
+
<span class="fw-dev-tooltip-weight"
|
|
510
|
+
>x{combo.scoreBreakdown.weights.mode ?? 0}</span
|
|
511
|
+
>
|
|
512
|
+
</div>
|
|
513
|
+
{/if}
|
|
514
|
+
{#if combo.scoreBreakdown.routingBonus !== undefined && combo.scoreBreakdown.routingBonus !== 0}
|
|
515
|
+
<div class="fw-dev-tooltip-row">
|
|
516
|
+
Routing: <span
|
|
517
|
+
class={combo.scoreBreakdown.routingBonus > 0
|
|
518
|
+
? "fw-dev-tooltip-bonus"
|
|
519
|
+
: "fw-dev-tooltip-penalty"}
|
|
520
|
+
>
|
|
521
|
+
{combo.scoreBreakdown.routingBonus > 0
|
|
522
|
+
? "+"
|
|
523
|
+
: ""}{combo.scoreBreakdown.routingBonus.toFixed(2)}
|
|
524
|
+
</span>
|
|
525
|
+
<span class="fw-dev-tooltip-weight"
|
|
526
|
+
>x{combo.scoreBreakdown.weights.routing ?? 0}</span
|
|
527
|
+
>
|
|
528
|
+
</div>
|
|
529
|
+
{/if}
|
|
493
530
|
{:else}
|
|
494
531
|
<div class="fw-dev-tooltip-error">
|
|
495
532
|
{combo.incompatibleReason || "Incompatible"}
|
package/dist/IdleScreen.svelte
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
- Status overlay at bottom
|
|
14
14
|
-->
|
|
15
15
|
<script lang="ts">
|
|
16
|
-
import { onMount, onDestroy } from "svelte";
|
|
16
|
+
import { onMount, onDestroy, getContext } from "svelte";
|
|
17
|
+
import type { Readable } from "svelte/store";
|
|
18
|
+
import { createTranslator, type TranslateFn } from "@livepeer-frameworks/player-core";
|
|
17
19
|
import type { StreamStatus } from "@livepeer-frameworks/player-core";
|
|
18
20
|
import DvdLogo from "./DvdLogo.svelte";
|
|
19
21
|
import logomarkAsset from "./assets/logomark.svg";
|
|
@@ -26,14 +28,20 @@
|
|
|
26
28
|
onRetry?: () => void;
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
const translatorCtx = getContext<Readable<TranslateFn> | undefined>("fw-translator");
|
|
32
|
+
const fallbackT = createTranslator({ locale: "en" });
|
|
33
|
+
let t: TranslateFn = $derived(translatorCtx ? $translatorCtx : fallbackT);
|
|
34
|
+
|
|
29
35
|
let {
|
|
30
36
|
status = "OFFLINE",
|
|
31
|
-
message =
|
|
37
|
+
message = undefined,
|
|
32
38
|
percentage = undefined,
|
|
33
39
|
error = undefined,
|
|
34
40
|
onRetry = undefined,
|
|
35
41
|
}: Props = $props();
|
|
36
42
|
|
|
43
|
+
let effectiveMessage = $derived(message ?? t("waitingForStream"));
|
|
44
|
+
|
|
37
45
|
// Container ref for mouse tracking
|
|
38
46
|
let containerRef: HTMLDivElement | undefined = $state();
|
|
39
47
|
|
|
@@ -316,7 +324,7 @@
|
|
|
316
324
|
let _statusLabel = $derived(getStatusLabel(status));
|
|
317
325
|
let showRetry = $derived((status === "ERROR" || status === "INVALID") && onRetry);
|
|
318
326
|
let showProgress = $derived(status === "INITIALIZING" && percentage !== undefined);
|
|
319
|
-
let displayMessage = $derived(error ||
|
|
327
|
+
let displayMessage = $derived(error || effectiveMessage);
|
|
320
328
|
let isLoading = $derived(
|
|
321
329
|
status === "INITIALIZING" || status === "BOOTING" || status === "WAITING_FOR_DATA" || !status
|
|
322
330
|
);
|
|
@@ -522,7 +530,7 @@
|
|
|
522
530
|
|
|
523
531
|
<!-- Retry button -->
|
|
524
532
|
{#if showRetry}
|
|
525
|
-
<button type="button" class="retry-button" onclick={onRetry}>
|
|
533
|
+
<button type="button" class="retry-button" onclick={onRetry}> {t("retry")} </button>
|
|
526
534
|
{/if}
|
|
527
535
|
</div>
|
|
528
536
|
|
|
@@ -619,7 +627,7 @@
|
|
|
619
627
|
}
|
|
620
628
|
}
|
|
621
629
|
|
|
622
|
-
.
|
|
630
|
+
.idle-container {
|
|
623
631
|
position: absolute;
|
|
624
632
|
inset: 0;
|
|
625
633
|
z-index: 5;
|
|
@@ -644,7 +652,7 @@
|
|
|
644
652
|
-webkit-user-select: none;
|
|
645
653
|
}
|
|
646
654
|
|
|
647
|
-
.
|
|
655
|
+
.bubble {
|
|
648
656
|
position: absolute;
|
|
649
657
|
border-radius: 50%;
|
|
650
658
|
transition: opacity 1s ease-in-out;
|
|
@@ -654,7 +662,7 @@
|
|
|
654
662
|
user-select: none;
|
|
655
663
|
}
|
|
656
664
|
|
|
657
|
-
.
|
|
665
|
+
.particle {
|
|
658
666
|
position: absolute;
|
|
659
667
|
border-radius: 50%;
|
|
660
668
|
opacity: 0;
|
|
@@ -665,7 +673,7 @@
|
|
|
665
673
|
user-select: none;
|
|
666
674
|
}
|
|
667
675
|
|
|
668
|
-
.
|
|
676
|
+
.center-logo {
|
|
669
677
|
position: absolute;
|
|
670
678
|
top: 50%;
|
|
671
679
|
left: 50%;
|
|
@@ -679,7 +687,7 @@
|
|
|
679
687
|
user-select: none;
|
|
680
688
|
}
|
|
681
689
|
|
|
682
|
-
.
|
|
690
|
+
.logo-pulse {
|
|
683
691
|
position: absolute;
|
|
684
692
|
border-radius: 50%;
|
|
685
693
|
background: rgba(122, 162, 247, 0.15);
|
|
@@ -691,18 +699,18 @@
|
|
|
691
699
|
transition: transform 0.3s ease-out;
|
|
692
700
|
}
|
|
693
701
|
|
|
694
|
-
.
|
|
702
|
+
.logo-pulse.hovered {
|
|
695
703
|
animation: logoPulse 1s ease-in-out infinite;
|
|
696
704
|
transform: scale(1.2);
|
|
697
705
|
}
|
|
698
706
|
|
|
699
|
-
.
|
|
707
|
+
.logo-button {
|
|
700
708
|
all: unset;
|
|
701
709
|
cursor: pointer;
|
|
702
710
|
display: block;
|
|
703
711
|
}
|
|
704
712
|
|
|
705
|
-
.
|
|
713
|
+
.logo-image {
|
|
706
714
|
position: relative;
|
|
707
715
|
z-index: 1;
|
|
708
716
|
filter: drop-shadow(0 4px 8px rgba(36, 40, 59, 0.3));
|
|
@@ -714,13 +722,13 @@
|
|
|
714
722
|
-webkit-touch-callout: none;
|
|
715
723
|
}
|
|
716
724
|
|
|
717
|
-
.
|
|
725
|
+
.logo-image.hovered {
|
|
718
726
|
filter: drop-shadow(0 6px 12px rgba(36, 40, 59, 0.4)) brightness(1.1);
|
|
719
727
|
transform: scale(1.1);
|
|
720
728
|
cursor: pointer;
|
|
721
729
|
}
|
|
722
730
|
|
|
723
|
-
.
|
|
731
|
+
.overlay-texture {
|
|
724
732
|
position: absolute;
|
|
725
733
|
top: 0;
|
|
726
734
|
left: 0;
|
|
@@ -736,7 +744,7 @@
|
|
|
736
744
|
user-select: none;
|
|
737
745
|
}
|
|
738
746
|
|
|
739
|
-
.
|
|
747
|
+
.hitmarker {
|
|
740
748
|
position: absolute;
|
|
741
749
|
transform: translate(-50%, -50%);
|
|
742
750
|
pointer-events: none;
|
|
@@ -745,7 +753,7 @@
|
|
|
745
753
|
height: 40px;
|
|
746
754
|
}
|
|
747
755
|
|
|
748
|
-
.
|
|
756
|
+
.hitmarker-line {
|
|
749
757
|
position: absolute;
|
|
750
758
|
width: 12px;
|
|
751
759
|
height: 3px;
|
|
@@ -754,31 +762,31 @@
|
|
|
754
762
|
border-radius: 1px;
|
|
755
763
|
}
|
|
756
764
|
|
|
757
|
-
.
|
|
765
|
+
.hitmarker-line.tl {
|
|
758
766
|
top: 25%;
|
|
759
767
|
left: 25%;
|
|
760
768
|
animation: hitmarkerFade45 0.6s ease-out forwards;
|
|
761
769
|
}
|
|
762
770
|
|
|
763
|
-
.
|
|
771
|
+
.hitmarker-line.tr {
|
|
764
772
|
top: 25%;
|
|
765
773
|
left: 75%;
|
|
766
774
|
animation: hitmarkerFadeNeg45 0.6s ease-out forwards;
|
|
767
775
|
}
|
|
768
776
|
|
|
769
|
-
.
|
|
777
|
+
.hitmarker-line.bl {
|
|
770
778
|
top: 75%;
|
|
771
779
|
left: 25%;
|
|
772
780
|
animation: hitmarkerFadeNeg45 0.6s ease-out forwards;
|
|
773
781
|
}
|
|
774
782
|
|
|
775
|
-
.
|
|
783
|
+
.hitmarker-line.br {
|
|
776
784
|
top: 75%;
|
|
777
785
|
left: 75%;
|
|
778
786
|
animation: hitmarkerFade45 0.6s ease-out forwards;
|
|
779
787
|
}
|
|
780
788
|
|
|
781
|
-
.
|
|
789
|
+
.status-overlay {
|
|
782
790
|
position: absolute;
|
|
783
791
|
bottom: 16px;
|
|
784
792
|
left: 50%;
|
|
@@ -792,7 +800,7 @@
|
|
|
792
800
|
text-align: center;
|
|
793
801
|
}
|
|
794
802
|
|
|
795
|
-
.
|
|
803
|
+
.status-indicator {
|
|
796
804
|
display: flex;
|
|
797
805
|
align-items: center;
|
|
798
806
|
gap: 8px;
|
|
@@ -801,16 +809,16 @@
|
|
|
801
809
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
802
810
|
}
|
|
803
811
|
|
|
804
|
-
.
|
|
812
|
+
.status-icon {
|
|
805
813
|
width: 20px;
|
|
806
814
|
height: 20px;
|
|
807
815
|
}
|
|
808
816
|
|
|
809
|
-
.
|
|
817
|
+
.status-icon.spinning {
|
|
810
818
|
animation: spin 1s linear infinite;
|
|
811
819
|
}
|
|
812
820
|
|
|
813
|
-
.
|
|
821
|
+
.progress-bar {
|
|
814
822
|
width: 160px;
|
|
815
823
|
height: 4px;
|
|
816
824
|
background: rgba(65, 72, 104, 0.4);
|
|
@@ -818,13 +826,13 @@
|
|
|
818
826
|
overflow: hidden;
|
|
819
827
|
}
|
|
820
828
|
|
|
821
|
-
.
|
|
829
|
+
.progress-fill {
|
|
822
830
|
height: 100%;
|
|
823
831
|
background: hsl(var(--tn-cyan, 193 100% 75%));
|
|
824
832
|
transition: width 0.3s ease-out;
|
|
825
833
|
}
|
|
826
834
|
|
|
827
|
-
.
|
|
835
|
+
.retry-button {
|
|
828
836
|
padding: 6px 16px;
|
|
829
837
|
background: transparent;
|
|
830
838
|
border: 1px solid rgba(122, 162, 247, 0.4);
|
|
@@ -837,7 +845,7 @@
|
|
|
837
845
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
838
846
|
}
|
|
839
847
|
|
|
840
|
-
.
|
|
848
|
+
.retry-button:hover {
|
|
841
849
|
background: rgba(122, 162, 247, 0.1);
|
|
842
850
|
}
|
|
843
851
|
</style>
|