@sweet-player/core 0.3.0 → 0.4.0
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/README.md +5 -1
- package/dist/index.cjs +267 -105
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +267 -105
- package/dist/sweet-player.global.js +159 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -457,69 +457,14 @@ var icons = {
|
|
|
457
457
|
),
|
|
458
458
|
audio: createSvgIcon(
|
|
459
459
|
"M12 3a9 9 0 0 0-9 9v7c0 1.1.9 2 2 2h4v-8H5v-1c0-3.87 3.13-7 7-7s7 3.13 7 7v1h-4v8h4c1.1 0 2-.9 2-2v-7a9 9 0 0 0-9-9z"
|
|
460
|
-
)
|
|
460
|
+
),
|
|
461
|
+
settings: createSvgIcon(
|
|
462
|
+
"M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65a.5.5 0 0 0 .12-.64l-2-3.46a.5.5 0 0 0-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.49.49 0 0 0 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.49.49 0 0 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65a.5.5 0 0 0-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46a.5.5 0 0 0-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"
|
|
463
|
+
),
|
|
464
|
+
chevronRight: createSvgIcon("M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"),
|
|
465
|
+
chevronLeft: createSvgIcon("M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z")
|
|
461
466
|
};
|
|
462
467
|
|
|
463
|
-
// src/ui/components/menu.ts
|
|
464
|
-
function createPopupMenu(opts) {
|
|
465
|
-
const root = createEl("div", { className: "sp-menu" });
|
|
466
|
-
const btn = createEl("button", {
|
|
467
|
-
className: "sp-btn sp-menu-btn",
|
|
468
|
-
html: opts.buttonHtml,
|
|
469
|
-
attrs: { type: "button", title: opts.title, "aria-label": opts.title },
|
|
470
|
-
parent: root
|
|
471
|
-
});
|
|
472
|
-
const panel = createEl("div", { className: "sp-menu-panel", parent: root });
|
|
473
|
-
let items = [];
|
|
474
|
-
let activeValue;
|
|
475
|
-
function render() {
|
|
476
|
-
panel.innerHTML = "";
|
|
477
|
-
if (items.length === 0) {
|
|
478
|
-
createEl("div", { className: "sp-menu-empty", text: opts.emptyText ?? "-", parent: panel });
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
for (const item of items) {
|
|
482
|
-
const itemBtn = createEl("button", {
|
|
483
|
-
className: "sp-menu-item" + (item.value === activeValue ? " sp-active" : ""),
|
|
484
|
-
text: item.label,
|
|
485
|
-
attrs: { type: "button" },
|
|
486
|
-
parent: panel
|
|
487
|
-
});
|
|
488
|
-
itemBtn.addEventListener("click", (e) => {
|
|
489
|
-
e.stopPropagation();
|
|
490
|
-
close();
|
|
491
|
-
opts.onSelect(item);
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
function close() {
|
|
496
|
-
root.classList.remove("sp-open");
|
|
497
|
-
}
|
|
498
|
-
btn.addEventListener("click", (e) => {
|
|
499
|
-
e.stopPropagation();
|
|
500
|
-
const willOpen = !root.classList.contains("sp-open");
|
|
501
|
-
root.closest(".sp-controls")?.querySelectorAll(".sp-menu.sp-open").forEach((m) => m.classList.remove("sp-open"));
|
|
502
|
-
root.classList.toggle("sp-open", willOpen);
|
|
503
|
-
});
|
|
504
|
-
document.addEventListener("click", close);
|
|
505
|
-
render();
|
|
506
|
-
return {
|
|
507
|
-
el: root,
|
|
508
|
-
setItems(next) {
|
|
509
|
-
items = next;
|
|
510
|
-
render();
|
|
511
|
-
},
|
|
512
|
-
setActive(value) {
|
|
513
|
-
activeValue = value;
|
|
514
|
-
render();
|
|
515
|
-
},
|
|
516
|
-
setButtonContent(html) {
|
|
517
|
-
btn.innerHTML = html;
|
|
518
|
-
},
|
|
519
|
-
close
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
|
|
523
468
|
// src/ui/components/progressBar.ts
|
|
524
469
|
function createProgressBar(video, onSeek) {
|
|
525
470
|
const root = createEl("div", { className: "sp-progress" });
|
|
@@ -627,6 +572,157 @@ function createVolumeControl(opts) {
|
|
|
627
572
|
};
|
|
628
573
|
}
|
|
629
574
|
|
|
575
|
+
// src/ui/components/settingsPanel.ts
|
|
576
|
+
function createSettingsPanel(opts) {
|
|
577
|
+
const root = createEl("div", { className: "sp-menu sp-settings" });
|
|
578
|
+
const btn = createEl("button", {
|
|
579
|
+
className: "sp-btn",
|
|
580
|
+
html: icons.settings,
|
|
581
|
+
attrs: { type: "button", title: opts.buttonTitle, "aria-label": opts.buttonTitle },
|
|
582
|
+
parent: root
|
|
583
|
+
});
|
|
584
|
+
const panel = createEl("div", { className: "sp-settings-panel", parent: root });
|
|
585
|
+
const mainView = createEl("div", { className: "sp-settings-main", parent: panel });
|
|
586
|
+
const subView = createEl("div", { className: "sp-settings-sub", parent: panel });
|
|
587
|
+
let sections = opts.sections;
|
|
588
|
+
let activeSub = null;
|
|
589
|
+
function renderMain() {
|
|
590
|
+
mainView.innerHTML = "";
|
|
591
|
+
for (const sec of sections) {
|
|
592
|
+
if (sec.toggle) {
|
|
593
|
+
const row2 = createEl("div", {
|
|
594
|
+
className: "sp-settings-row sp-settings-toggle-row",
|
|
595
|
+
attrs: { "data-key": sec.key },
|
|
596
|
+
parent: mainView
|
|
597
|
+
});
|
|
598
|
+
createEl("span", { className: "sp-settings-label", text: sec.label, parent: row2 });
|
|
599
|
+
const track = createEl("div", {
|
|
600
|
+
className: "sp-toggle" + (sec.toggle.checked ? " sp-on" : ""),
|
|
601
|
+
attrs: { role: "switch", "aria-checked": String(sec.toggle.checked), tabindex: "0" },
|
|
602
|
+
parent: row2
|
|
603
|
+
});
|
|
604
|
+
createEl("span", { className: "sp-toggle-thumb", parent: track });
|
|
605
|
+
const handler = (e) => {
|
|
606
|
+
e.stopPropagation();
|
|
607
|
+
sec.toggle.onToggle();
|
|
608
|
+
};
|
|
609
|
+
row2.addEventListener("click", handler);
|
|
610
|
+
track.addEventListener("keydown", (e) => {
|
|
611
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
612
|
+
e.preventDefault();
|
|
613
|
+
handler(e);
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (sec.items.length === 0) continue;
|
|
619
|
+
const row = createEl("button", {
|
|
620
|
+
className: "sp-settings-row",
|
|
621
|
+
attrs: { type: "button", "data-key": sec.key },
|
|
622
|
+
parent: mainView
|
|
623
|
+
});
|
|
624
|
+
createEl("span", { className: "sp-settings-label", text: sec.label, parent: row });
|
|
625
|
+
createEl("span", { className: "sp-settings-value", text: sec.currentValue, parent: row });
|
|
626
|
+
const arrow = createEl("span", { className: "sp-settings-arrow", parent: row });
|
|
627
|
+
arrow.innerHTML = icons.chevronRight;
|
|
628
|
+
row.addEventListener("click", (e) => {
|
|
629
|
+
e.stopPropagation();
|
|
630
|
+
showSub(sec.key);
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function renderSub(key) {
|
|
635
|
+
subView.innerHTML = "";
|
|
636
|
+
const sec = sections.find((s) => s.key === key);
|
|
637
|
+
if (!sec) return;
|
|
638
|
+
const back = createEl("button", {
|
|
639
|
+
className: "sp-settings-back",
|
|
640
|
+
attrs: { type: "button" },
|
|
641
|
+
parent: subView
|
|
642
|
+
});
|
|
643
|
+
const backArrow = createEl("span", { className: "sp-settings-back-arrow", parent: back });
|
|
644
|
+
backArrow.innerHTML = icons.chevronLeft;
|
|
645
|
+
createEl("span", { text: sec.label, parent: back });
|
|
646
|
+
back.addEventListener("click", (e) => {
|
|
647
|
+
e.stopPropagation();
|
|
648
|
+
showMain();
|
|
649
|
+
});
|
|
650
|
+
for (const item of sec.items) {
|
|
651
|
+
const itemBtn = createEl("button", {
|
|
652
|
+
className: "sp-menu-item" + (item.value === sec.activeValue ? " sp-active" : ""),
|
|
653
|
+
text: item.label,
|
|
654
|
+
attrs: { type: "button" },
|
|
655
|
+
parent: subView
|
|
656
|
+
});
|
|
657
|
+
itemBtn.addEventListener("click", (e) => {
|
|
658
|
+
e.stopPropagation();
|
|
659
|
+
close();
|
|
660
|
+
sec.onSelect(item);
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
function showSub(key) {
|
|
665
|
+
activeSub = key;
|
|
666
|
+
renderSub(key);
|
|
667
|
+
mainView.style.display = "none";
|
|
668
|
+
subView.style.display = "";
|
|
669
|
+
}
|
|
670
|
+
function showMain() {
|
|
671
|
+
activeSub = null;
|
|
672
|
+
mainView.style.display = "";
|
|
673
|
+
subView.style.display = "none";
|
|
674
|
+
}
|
|
675
|
+
function close() {
|
|
676
|
+
root.classList.remove("sp-open");
|
|
677
|
+
showMain();
|
|
678
|
+
}
|
|
679
|
+
btn.addEventListener("click", (e) => {
|
|
680
|
+
e.stopPropagation();
|
|
681
|
+
const willOpen = !root.classList.contains("sp-open");
|
|
682
|
+
root.closest(".sp-controls")?.querySelectorAll(".sp-menu.sp-open").forEach((m) => m.classList.remove("sp-open"));
|
|
683
|
+
if (willOpen) {
|
|
684
|
+
renderMain();
|
|
685
|
+
showMain();
|
|
686
|
+
}
|
|
687
|
+
root.classList.toggle("sp-open", willOpen);
|
|
688
|
+
});
|
|
689
|
+
const onDocClick = () => close();
|
|
690
|
+
document.addEventListener("click", onDocClick);
|
|
691
|
+
panel.addEventListener("click", (e) => e.stopPropagation());
|
|
692
|
+
renderMain();
|
|
693
|
+
showMain();
|
|
694
|
+
return {
|
|
695
|
+
el: root,
|
|
696
|
+
updateSection(key, patch) {
|
|
697
|
+
const sec = sections.find((s) => s.key === key);
|
|
698
|
+
if (!sec) return;
|
|
699
|
+
if (patch.items !== void 0) sec.items = patch.items;
|
|
700
|
+
if (patch.currentValue !== void 0) sec.currentValue = patch.currentValue;
|
|
701
|
+
if (patch.activeValue !== void 0) sec.activeValue = patch.activeValue;
|
|
702
|
+
if (patch.toggle) {
|
|
703
|
+
if (sec.toggle) {
|
|
704
|
+
sec.toggle.checked = patch.toggle.checked;
|
|
705
|
+
if (patch.toggle.onToggle) sec.toggle.onToggle = patch.toggle.onToggle;
|
|
706
|
+
} else {
|
|
707
|
+
sec.toggle = { checked: patch.toggle.checked, onToggle: patch.toggle.onToggle ?? (() => {
|
|
708
|
+
}) };
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
if (sec.toggle) {
|
|
712
|
+
if (!activeSub) renderMain();
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
if (activeSub === key) renderSub(key);
|
|
716
|
+
if (!activeSub) renderMain();
|
|
717
|
+
},
|
|
718
|
+
close,
|
|
719
|
+
destroy() {
|
|
720
|
+
document.removeEventListener("click", onDocClick);
|
|
721
|
+
root.remove();
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
630
726
|
// src/ui/controls.ts
|
|
631
727
|
function createControls(ctx) {
|
|
632
728
|
const { video, actions, i18n, hidden } = ctx;
|
|
@@ -661,57 +757,114 @@ function createControls(ctx) {
|
|
|
661
757
|
parent: show("time") ? row : void 0
|
|
662
758
|
});
|
|
663
759
|
createEl("div", { className: "sp-controls-spacer", parent: row });
|
|
664
|
-
const rateMenu = createPopupMenu({
|
|
665
|
-
buttonHtml: "1x",
|
|
666
|
-
title: i18n.t("speed"),
|
|
667
|
-
emptyText: i18n.t("empty"),
|
|
668
|
-
onSelect: (item) => actions.setRate(item.value)
|
|
669
|
-
});
|
|
670
|
-
rateMenu.setItems(ctx.playbackRates.map((r) => ({ label: `${r}x`, value: r })));
|
|
671
|
-
rateMenu.setActive(video.playbackRate);
|
|
672
|
-
if (show("rate")) row.appendChild(rateMenu.el);
|
|
673
|
-
const qualityMenu = createPopupMenu({
|
|
674
|
-
buttonHtml: i18n.t("quality"),
|
|
675
|
-
title: i18n.t("quality"),
|
|
676
|
-
emptyText: i18n.t("empty"),
|
|
677
|
-
onSelect: (item) => actions.selectQuality(item.value)
|
|
678
|
-
});
|
|
679
|
-
if (show("quality")) row.appendChild(qualityMenu.el);
|
|
680
|
-
const ratioMenu = createPopupMenu({
|
|
681
|
-
buttonHtml: i18n.t("aspectRatio"),
|
|
682
|
-
title: i18n.t("aspectRatio"),
|
|
683
|
-
emptyText: i18n.t("empty"),
|
|
684
|
-
onSelect: (item) => actions.setAspectRatio(item.value)
|
|
685
|
-
});
|
|
686
|
-
ratioMenu.setItems(
|
|
687
|
-
ctx.aspectRatios.map((r) => ({ label: r === "original" ? i18n.t("ratioOriginal") : r, value: r }))
|
|
688
|
-
);
|
|
689
|
-
ratioMenu.setActive("original");
|
|
690
|
-
if (show("ratio")) row.appendChild(ratioMenu.el);
|
|
691
|
-
const audioMenu = createPopupMenu({
|
|
692
|
-
buttonHtml: icons.audio,
|
|
693
|
-
title: i18n.t("audioTrack"),
|
|
694
|
-
emptyText: i18n.t("empty"),
|
|
695
|
-
onSelect: (item) => actions.selectAudioTrack(item.value)
|
|
696
|
-
});
|
|
697
|
-
if (show("audioTrack")) row.appendChild(audioMenu.el);
|
|
698
760
|
const volume = createVolumeControl({
|
|
699
761
|
muteTitle: i18n.t("mute"),
|
|
700
762
|
onVolumeChange: actions.setVolume,
|
|
701
763
|
onToggleMute: actions.toggleMute
|
|
702
764
|
});
|
|
703
765
|
if (show("volume")) row.appendChild(volume.el);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
766
|
+
let currentRate = video.playbackRate;
|
|
767
|
+
let qualityItems = [];
|
|
768
|
+
let activeQuality;
|
|
769
|
+
let audioItems = [];
|
|
770
|
+
let activeAudio;
|
|
771
|
+
const settingsPanel = createSettingsPanel({
|
|
772
|
+
buttonTitle: i18n.t("settings"),
|
|
773
|
+
sections: [
|
|
774
|
+
...show("rate") ? [{
|
|
775
|
+
key: "rate",
|
|
776
|
+
label: i18n.t("speed"),
|
|
777
|
+
currentValue: `${currentRate}x`,
|
|
778
|
+
items: ctx.playbackRates.map((r) => ({ label: `${r}x`, value: r })),
|
|
779
|
+
activeValue: currentRate,
|
|
780
|
+
onSelect: (item) => actions.setRate(item.value)
|
|
781
|
+
}] : [],
|
|
782
|
+
...show("quality") ? [{
|
|
783
|
+
key: "quality",
|
|
784
|
+
label: i18n.t("quality"),
|
|
785
|
+
currentValue: i18n.t("qualityAuto"),
|
|
786
|
+
items: qualityItems,
|
|
787
|
+
activeValue: activeQuality,
|
|
788
|
+
onSelect: (item) => actions.selectQuality(item.value)
|
|
789
|
+
}] : [],
|
|
790
|
+
...show("ratio") ? [{
|
|
791
|
+
key: "ratio",
|
|
792
|
+
label: i18n.t("aspectRatio"),
|
|
793
|
+
currentValue: i18n.t("ratioOriginal"),
|
|
794
|
+
items: ctx.aspectRatios.map((r) => ({
|
|
795
|
+
label: r === "original" ? i18n.t("ratioOriginal") : r,
|
|
796
|
+
value: r
|
|
797
|
+
})),
|
|
798
|
+
activeValue: "original",
|
|
799
|
+
onSelect: (item) => actions.setAspectRatio(item.value)
|
|
800
|
+
}] : [],
|
|
801
|
+
...show("audioTrack") ? [{
|
|
802
|
+
key: "audioTrack",
|
|
803
|
+
label: i18n.t("audioTrack"),
|
|
804
|
+
currentValue: "-",
|
|
805
|
+
items: audioItems,
|
|
806
|
+
activeValue: activeAudio,
|
|
807
|
+
onSelect: (item) => actions.selectAudioTrack(item.value)
|
|
808
|
+
}] : [],
|
|
809
|
+
...show("pip") && document.pictureInPictureEnabled ? [{
|
|
810
|
+
key: "pip",
|
|
811
|
+
label: i18n.t("pip"),
|
|
812
|
+
currentValue: "",
|
|
813
|
+
items: [],
|
|
814
|
+
activeValue: void 0,
|
|
815
|
+
onSelect: () => {
|
|
816
|
+
},
|
|
817
|
+
toggle: {
|
|
818
|
+
checked: false,
|
|
819
|
+
onToggle: () => actions.togglePip()
|
|
820
|
+
}
|
|
821
|
+
}] : []
|
|
822
|
+
]
|
|
823
|
+
});
|
|
824
|
+
if (show("settings")) row.appendChild(settingsPanel.el);
|
|
707
825
|
const fsBtn = button(icons.fullscreen, i18n.t("fullscreen"), actions.toggleFullscreen, false, show("fullscreen"));
|
|
826
|
+
const qualityMenuAdapter = {
|
|
827
|
+
el: document.createElement("div"),
|
|
828
|
+
setItems(items) {
|
|
829
|
+
qualityItems = items;
|
|
830
|
+
const cur = activeQuality ? items.find((i) => i.value === activeQuality)?.label : i18n.t("qualityAuto");
|
|
831
|
+
settingsPanel.updateSection("quality", { items, currentValue: cur ?? i18n.t("qualityAuto") });
|
|
832
|
+
},
|
|
833
|
+
setActive(value) {
|
|
834
|
+
activeQuality = value;
|
|
835
|
+
const label = qualityItems.find((i) => i.value === value)?.label ?? i18n.t("qualityAuto");
|
|
836
|
+
settingsPanel.updateSection("quality", { activeValue: value, currentValue: label });
|
|
837
|
+
},
|
|
838
|
+
setButtonContent() {
|
|
839
|
+
},
|
|
840
|
+
close() {
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
const audioMenuAdapter = {
|
|
844
|
+
el: document.createElement("div"),
|
|
845
|
+
setItems(items) {
|
|
846
|
+
audioItems = items;
|
|
847
|
+
const cur = activeAudio ? items.find((i) => i.value === activeAudio)?.label : "-";
|
|
848
|
+
settingsPanel.updateSection("audioTrack", { items, currentValue: cur ?? "-" });
|
|
849
|
+
},
|
|
850
|
+
setActive(value) {
|
|
851
|
+
activeAudio = value;
|
|
852
|
+
const label = audioItems.find((i) => i.value === value)?.label ?? "-";
|
|
853
|
+
settingsPanel.updateSection("audioTrack", { activeValue: value, currentValue: label });
|
|
854
|
+
},
|
|
855
|
+
setButtonContent() {
|
|
856
|
+
},
|
|
857
|
+
close() {
|
|
858
|
+
}
|
|
859
|
+
};
|
|
708
860
|
return {
|
|
709
861
|
topEl,
|
|
710
862
|
bottomEl,
|
|
711
863
|
progress,
|
|
712
864
|
volume,
|
|
713
|
-
qualityMenu,
|
|
714
|
-
audioMenu,
|
|
865
|
+
qualityMenu: qualityMenuAdapter,
|
|
866
|
+
audioMenu: audioMenuAdapter,
|
|
867
|
+
settingsPanel,
|
|
715
868
|
updatePlayState(playing) {
|
|
716
869
|
playBtn.innerHTML = playing ? icons.pause : icons.play;
|
|
717
870
|
},
|
|
@@ -720,16 +873,21 @@ function createControls(ctx) {
|
|
|
720
873
|
progress.update();
|
|
721
874
|
},
|
|
722
875
|
updateRate(rate) {
|
|
723
|
-
|
|
724
|
-
|
|
876
|
+
currentRate = rate;
|
|
877
|
+
settingsPanel.updateSection("rate", { activeValue: rate, currentValue: `${rate}x` });
|
|
725
878
|
},
|
|
726
879
|
updateFullscreen(fs) {
|
|
727
880
|
fsBtn.innerHTML = fs ? icons.fullscreenExit : icons.fullscreen;
|
|
728
881
|
},
|
|
882
|
+
updatePip(pip) {
|
|
883
|
+
settingsPanel.updateSection("pip", { toggle: { checked: pip } });
|
|
884
|
+
},
|
|
729
885
|
updateRatio(ratio) {
|
|
730
|
-
|
|
886
|
+
const label = ratio === "original" ? i18n.t("ratioOriginal") : ratio;
|
|
887
|
+
settingsPanel.updateSection("ratio", { activeValue: ratio, currentValue: label });
|
|
731
888
|
},
|
|
732
889
|
destroy() {
|
|
890
|
+
settingsPanel.destroy();
|
|
733
891
|
topEl.remove();
|
|
734
892
|
bottomEl.remove();
|
|
735
893
|
}
|
|
@@ -1090,6 +1248,7 @@ var zhCN = {
|
|
|
1090
1248
|
scVolume: "\u97F3\u91CF \xB15",
|
|
1091
1249
|
scFullscreen: "\u5168\u5C4F\u5207\u6362",
|
|
1092
1250
|
scMute: "\u9759\u97F3\u5207\u6362",
|
|
1251
|
+
settings: "\u8BBE\u7F6E",
|
|
1093
1252
|
copyLog: "\u590D\u5236\u65E5\u5FD7",
|
|
1094
1253
|
logCopied: "\u5DF2\u590D\u5236"
|
|
1095
1254
|
};
|
|
@@ -1133,6 +1292,7 @@ var en = {
|
|
|
1133
1292
|
scVolume: "Volume \xB15",
|
|
1134
1293
|
scFullscreen: "Toggle fullscreen",
|
|
1135
1294
|
scMute: "Toggle mute",
|
|
1295
|
+
settings: "Settings",
|
|
1136
1296
|
copyLog: "Copy log",
|
|
1137
1297
|
logCopied: "Copied"
|
|
1138
1298
|
};
|
|
@@ -1208,10 +1368,10 @@ function clearProgress(id) {
|
|
|
1208
1368
|
}
|
|
1209
1369
|
|
|
1210
1370
|
// src/version.ts
|
|
1211
|
-
var VERSION = true ? "0.
|
|
1371
|
+
var VERSION = true ? "0.4.0" : "dev";
|
|
1212
1372
|
|
|
1213
1373
|
// src/styles/player.css
|
|
1214
|
-
var player_default = ".sweet-player {\n --sp-accent: #ff4d6d;\n --sp-bg: #000;\n --sp-text: #fff;\n --sp-bar-height: 4px;\n --sp-bar-hover-height: 6px;\n --sp-control-size: 36px;\n --sp-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--sp-bg);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 13px;\n overflow: hidden;\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sweet-player *,\n.sweet-player *::before,\n.sweet-player *::after {\n box-sizing: border-box;\n}\n\n.sp-video {\n width: 100%;\n height: 100%;\n object-fit: contain;\n display: block;\n}\n\n/* \u5F3A\u5236\u753B\u9762\u6BD4\u4F8B\uFF1Avideo \u5C45\u4E2D\u3001\u6309\u6BD4\u4F8B\u9650\u5236\u5C3A\u5BF8\u5E76\u62C9\u4F38\u586B\u5145 */\n.sweet-player[data-ratio]:not([data-ratio='original']) .sp-video {\n width: auto;\n height: auto;\n max-width: 100%;\n max-height: 100%;\n aspect-ratio: var(--sp-forced-ratio);\n object-fit: fill;\n}\n\n/* ---------- \u9876\u90E8\u6807\u9898\u533A ---------- */\n.sp-top {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n padding: 12px 16px 28px;\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.6), transparent);\n transition: opacity 0.25s ease;\n pointer-events: none;\n}\n\n.sp-title {\n display: inline-block;\n max-width: 70%;\n font-size: 15px;\n font-weight: 500;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: auto;\n cursor: default;\n}\n\n/* ---------- \u7EDF\u8BA1\u4FE1\u606F\u8499\u5C42 ---------- */\n.sp-stats {\n position: absolute;\n top: 12px;\n left: 12px;\n z-index: 30;\n min-width: 300px;\n max-width: calc(100% - 24px);\n padding: 10px 14px;\n background: rgba(0, 0, 0, 0.75);\n border-radius: 6px;\n font-size: 12px;\n line-height: 1.7;\n font-family: 'SFMono-Regular', Consolas, monospace;\n pointer-events: auto;\n}\n\n.sp-stats-header {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 4px;\n margin: -4px -6px 4px 0;\n}\n\n.sp-stats-copy {\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n opacity: 0.7;\n font-size: 12px;\n line-height: 22px;\n padding: 0 6px;\n border-radius: 3px;\n white-space: nowrap;\n}\n\n.sp-stats-copy:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n}\n\n.sp-stats-close {\n width: 22px;\n height: 22px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n opacity: 0.7;\n font-size: 16px;\n line-height: 1;\n flex-shrink: 0;\n}\n\n.sp-stats-close:hover {\n opacity: 1;\n}\n\n.sp-stats-row {\n display: flex;\n gap: 12px;\n}\n\n.sp-stats-row dt {\n flex: 0 0 110px;\n opacity: 0.65;\n margin: 0;\n}\n\n.sp-stats-row dd {\n margin: 0;\n word-break: break-all;\n}\n\n/* ---------- \u5FEB\u6377\u952E\u9762\u677F ---------- */\n.sp-shortcuts {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 30;\n min-width: 280px;\n max-width: calc(100% - 24px);\n max-height: calc(100% - 24px);\n overflow-y: auto;\n padding: 14px 20px 14px;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 8px;\n font-size: 13px;\n line-height: 2.1;\n pointer-events: auto;\n}\n\n.sp-shortcuts-title {\n font-size: 14px;\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.sp-shortcuts-body {\n margin: 0;\n}\n\n.sp-shortcuts-row {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.sp-shortcuts-row dt {\n flex: 0 0 100px;\n margin: 0;\n}\n\n.sp-shortcuts-row dd {\n margin: 0;\n opacity: 0.85;\n}\n\n.sp-kbd {\n display: inline-block;\n padding: 0 7px;\n background: rgba(255, 255, 255, 0.15);\n border-radius: 4px;\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 12px;\n line-height: 20px;\n white-space: nowrap;\n}\n\n.sp-shortcuts-close {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 22px;\n height: 22px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n opacity: 0.7;\n font-size: 16px;\n line-height: 1;\n}\n\n.sp-shortcuts-close:hover {\n opacity: 1;\n}\n\n/* ---------- \u53F3\u952E\u83DC\u5355 ---------- */\n.sp-context-menu {\n position: absolute;\n z-index: 40;\n min-width: 150px;\n padding: 4px 0;\n background: rgba(28, 28, 28, 0.95);\n border-radius: 6px;\n display: none;\n}\n\n.sp-context-menu.sp-visible {\n display: block;\n}\n\n.sp-context-item {\n display: block;\n width: 100%;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n text-align: left;\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n}\n\n.sp-context-item:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n/* ---------- \u4E2D\u592E OSD \u53CD\u9988 ---------- */\n.sp-osd {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 20;\n padding: 10px 18px;\n background: rgba(0, 0, 0, 0.65);\n border-radius: 6px;\n font-size: 16px;\n font-weight: 500;\n opacity: 0;\n transition: opacity 0.15s ease;\n pointer-events: none;\n white-space: nowrap;\n}\n\n.sp-osd.sp-visible {\n opacity: 1;\n}\n\n/* ---------- \u5E95\u90E8\u63A7\u5236\u533A ---------- */\n.sp-bottom {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n padding: 24px 12px 6px;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);\n transition: opacity 0.25s ease;\n z-index: 10;\n}\n\n.sweet-player.sp-controls-hidden .sp-bottom,\n.sweet-player.sp-controls-hidden .sp-top {\n opacity: 0;\n pointer-events: none;\n}\n\n.sweet-player.sp-controls-hidden {\n cursor: none;\n}\n\n/* ---------- \u8FDB\u5EA6\u6761 ---------- */\n.sp-progress {\n position: relative;\n height: 14px;\n display: flex;\n align-items: center;\n cursor: pointer;\n margin-bottom: 4px;\n}\n\n.sp-progress-track {\n position: relative;\n width: 100%;\n height: var(--sp-bar-height);\n background: rgba(255, 255, 255, 0.25);\n border-radius: 2px;\n overflow: visible;\n transition: height 0.1s ease;\n}\n\n.sp-progress:hover .sp-progress-track {\n height: var(--sp-bar-hover-height);\n}\n\n.sp-progress-buffered,\n.sp-progress-played {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n}\n\n.sp-progress-buffered {\n background: rgba(255, 255, 255, 0.35);\n}\n\n.sp-progress-played {\n background: var(--sp-accent);\n}\n\n.sp-progress-thumb {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--sp-accent);\n transform: translate(-50%, -50%) scale(0);\n transition: transform 0.1s ease;\n pointer-events: none;\n}\n\n.sp-progress:hover .sp-progress-thumb,\n.sp-progress.sp-dragging .sp-progress-thumb {\n transform: translate(-50%, -50%) scale(1);\n}\n\n.sp-progress-tooltip {\n position: absolute;\n bottom: 18px;\n transform: translateX(-50%);\n padding: 2px 6px;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 3px;\n font-size: 12px;\n display: none;\n pointer-events: none;\n white-space: nowrap;\n}\n\n.sp-progress:hover .sp-progress-tooltip {\n display: block;\n}\n\n/* ---------- \u63A7\u5236\u6309\u94AE\u884C ---------- */\n.sp-controls {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.sp-controls-spacer {\n flex: 1;\n}\n\n.sp-btn {\n width: var(--sp-control-size);\n height: var(--sp-control-size);\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n padding: 0;\n opacity: 0.9;\n transition: opacity 0.1s ease, background 0.1s ease;\n}\n\n.sp-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.15);\n}\n\n.sp-btn svg {\n width: 22px;\n height: 22px;\n}\n\n.sp-btn:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.sp-time {\n padding: 0 8px;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n opacity: 0.95;\n}\n\n/* ---------- \u5F39\u51FA\u83DC\u5355 ---------- */\n.sp-menu {\n position: relative;\n}\n\n.sp-menu-btn {\n min-width: var(--sp-control-size);\n width: auto;\n padding: 0 8px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.sp-menu-panel {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n min-width: 80px;\n max-height: 220px;\n overflow-y: auto;\n background: rgba(28, 28, 28, 0.95);\n border-radius: 6px;\n padding: 4px 0;\n display: none;\n z-index: 25;\n}\n\n.sp-menu.sp-open .sp-menu-panel {\n display: block;\n}\n\n.sp-menu-item {\n display: block;\n width: 100%;\n padding: 7px 16px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n text-align: center;\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n}\n\n.sp-menu-item:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n.sp-menu-item.sp-active {\n color: var(--sp-accent);\n font-weight: 600;\n}\n\n.sp-menu-empty {\n padding: 7px 16px;\n opacity: 0.5;\n white-space: nowrap;\n}\n\n/* ---------- \u72B6\u6001\u8499\u5C42\uFF1Aloading / \u9519\u8BEF / \u7ED3\u675F ---------- */\n.sp-state {\n position: absolute;\n inset: 0;\n z-index: 15;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n}\n\n.sp-spinner {\n opacity: 0;\n transition: opacity 0.2s ease 0.3s; /* \u5EF6\u8FDF\u51FA\u73B0\uFF0C\u907F\u514D\u77ED\u6682 seek \u95EA\u70C1 */\n}\n\n.sp-state.sp-loading .sp-spinner {\n opacity: 1;\n}\n\n.sp-spinner-ring {\n width: 44px;\n height: 44px;\n border: 4px solid rgba(255, 255, 255, 0.25);\n border-top-color: var(--sp-accent);\n border-radius: 50%;\n animation: sp-spin 0.8s linear infinite;\n}\n\n@keyframes sp-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.sp-state-panel {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 14px;\n background: rgba(0, 0, 0, 0.55);\n pointer-events: auto;\n}\n\n.sp-state-message {\n font-size: 15px;\n opacity: 0.95;\n}\n\n.sp-state-actions {\n display: flex;\n gap: 12px;\n}\n\n.sp-state-btn {\n padding: 8px 22px;\n border: 1px solid rgba(255, 255, 255, 0.5);\n border-radius: 18px;\n background: transparent;\n color: var(--sp-text);\n font-size: 14px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.sp-state-btn:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.sp-state-btn-primary {\n background: var(--sp-accent);\n border-color: var(--sp-accent);\n}\n\n.sp-state-btn-primary:hover {\n background: var(--sp-accent);\n filter: brightness(1.1);\n}\n\n.sp-state-countdown {\n font-size: 13px;\n opacity: 0.85;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sp-state-cancel {\n border: none;\n background: transparent;\n color: var(--sp-accent);\n cursor: pointer;\n font-size: 13px;\n padding: 2px 6px;\n}\n\n/* ---------- \u97F3\u91CF ---------- */\n.sp-volume {\n display: flex;\n align-items: center;\n}\n\n.sp-volume-slider {\n width: 0;\n overflow: hidden;\n transition: width 0.15s ease;\n display: flex;\n align-items: center;\n}\n\n.sp-volume:hover .sp-volume-slider,\n.sp-volume.sp-dragging .sp-volume-slider {\n width: 64px;\n}\n\n.sp-volume-track {\n position: relative;\n width: 56px;\n height: var(--sp-bar-height);\n margin: 0 4px;\n background: rgba(255, 255, 255, 0.25);\n border-radius: 2px;\n cursor: pointer;\n}\n\n.sp-volume-fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--sp-text);\n border-radius: 2px;\n}\n\n.sp-volume-thumb {\n position: absolute;\n top: 50%;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--sp-text);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n";
|
|
1374
|
+
var player_default = ".sweet-player {\n --sp-accent: #ff4d6d;\n --sp-bg: #000;\n --sp-text: #fff;\n --sp-bar-height: 4px;\n --sp-bar-hover-height: 6px;\n --sp-control-size: 36px;\n --sp-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--sp-bg);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 13px;\n overflow: hidden;\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sweet-player *,\n.sweet-player *::before,\n.sweet-player *::after {\n box-sizing: border-box;\n}\n\n.sp-video {\n width: 100%;\n height: 100%;\n object-fit: contain;\n display: block;\n}\n\n/* \u5F3A\u5236\u753B\u9762\u6BD4\u4F8B\uFF1Avideo \u5C45\u4E2D\u3001\u6309\u6BD4\u4F8B\u9650\u5236\u5C3A\u5BF8\u5E76\u62C9\u4F38\u586B\u5145 */\n.sweet-player[data-ratio]:not([data-ratio='original']) .sp-video {\n width: auto;\n height: auto;\n max-width: 100%;\n max-height: 100%;\n aspect-ratio: var(--sp-forced-ratio);\n object-fit: fill;\n}\n\n/* ---------- \u9876\u90E8\u6807\u9898\u533A ---------- */\n.sp-top {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n padding: 12px 16px 28px;\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.6), transparent);\n transition: opacity 0.25s ease;\n pointer-events: none;\n}\n\n.sp-title {\n display: inline-block;\n max-width: 70%;\n font-size: 15px;\n font-weight: 500;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: auto;\n cursor: default;\n}\n\n/* ---------- \u7EDF\u8BA1\u4FE1\u606F\u8499\u5C42 ---------- */\n.sp-stats {\n position: absolute;\n top: 12px;\n left: 12px;\n z-index: 30;\n min-width: 300px;\n max-width: calc(100% - 24px);\n padding: 10px 14px;\n background: rgba(0, 0, 0, 0.75);\n border-radius: 6px;\n font-size: 12px;\n line-height: 1.7;\n font-family: 'SFMono-Regular', Consolas, monospace;\n pointer-events: auto;\n}\n\n.sp-stats-header {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 4px;\n margin: -4px -6px 4px 0;\n}\n\n.sp-stats-copy {\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n opacity: 0.7;\n font-size: 12px;\n line-height: 22px;\n padding: 0 6px;\n border-radius: 3px;\n white-space: nowrap;\n}\n\n.sp-stats-copy:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n}\n\n.sp-stats-close {\n width: 22px;\n height: 22px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n opacity: 0.7;\n font-size: 16px;\n line-height: 1;\n flex-shrink: 0;\n}\n\n.sp-stats-close:hover {\n opacity: 1;\n}\n\n.sp-stats-row {\n display: flex;\n gap: 12px;\n}\n\n.sp-stats-row dt {\n flex: 0 0 110px;\n opacity: 0.65;\n margin: 0;\n}\n\n.sp-stats-row dd {\n margin: 0;\n word-break: break-all;\n}\n\n/* ---------- \u5FEB\u6377\u952E\u9762\u677F ---------- */\n.sp-shortcuts {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 30;\n min-width: 280px;\n max-width: calc(100% - 24px);\n max-height: calc(100% - 24px);\n overflow-y: auto;\n padding: 14px 20px 14px;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 8px;\n font-size: 13px;\n line-height: 2.1;\n pointer-events: auto;\n}\n\n.sp-shortcuts-title {\n font-size: 14px;\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.sp-shortcuts-body {\n margin: 0;\n}\n\n.sp-shortcuts-row {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.sp-shortcuts-row dt {\n flex: 0 0 100px;\n margin: 0;\n}\n\n.sp-shortcuts-row dd {\n margin: 0;\n opacity: 0.85;\n}\n\n.sp-kbd {\n display: inline-block;\n padding: 0 7px;\n background: rgba(255, 255, 255, 0.15);\n border-radius: 4px;\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 12px;\n line-height: 20px;\n white-space: nowrap;\n}\n\n.sp-shortcuts-close {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 22px;\n height: 22px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n opacity: 0.7;\n font-size: 16px;\n line-height: 1;\n}\n\n.sp-shortcuts-close:hover {\n opacity: 1;\n}\n\n/* ---------- \u53F3\u952E\u83DC\u5355 ---------- */\n.sp-context-menu {\n position: absolute;\n z-index: 40;\n min-width: 150px;\n padding: 4px 0;\n background: rgba(28, 28, 28, 0.95);\n border-radius: 6px;\n display: none;\n}\n\n.sp-context-menu.sp-visible {\n display: block;\n}\n\n.sp-context-item {\n display: block;\n width: 100%;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n text-align: left;\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n}\n\n.sp-context-item:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n/* ---------- \u4E2D\u592E OSD \u53CD\u9988 ---------- */\n.sp-osd {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 20;\n padding: 10px 18px;\n background: rgba(0, 0, 0, 0.65);\n border-radius: 6px;\n font-size: 16px;\n font-weight: 500;\n opacity: 0;\n transition: opacity 0.15s ease;\n pointer-events: none;\n white-space: nowrap;\n}\n\n.sp-osd.sp-visible {\n opacity: 1;\n}\n\n/* ---------- \u5E95\u90E8\u63A7\u5236\u533A ---------- */\n.sp-bottom {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n padding: 24px 12px 6px;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);\n transition: opacity 0.25s ease;\n z-index: 10;\n}\n\n.sweet-player.sp-controls-hidden .sp-bottom,\n.sweet-player.sp-controls-hidden .sp-top {\n opacity: 0;\n pointer-events: none;\n}\n\n.sweet-player.sp-controls-hidden {\n cursor: none;\n}\n\n/* ---------- \u8FDB\u5EA6\u6761 ---------- */\n.sp-progress {\n position: relative;\n height: 14px;\n display: flex;\n align-items: center;\n cursor: pointer;\n margin-bottom: 4px;\n}\n\n.sp-progress-track {\n position: relative;\n width: 100%;\n height: var(--sp-bar-height);\n background: rgba(255, 255, 255, 0.25);\n border-radius: 2px;\n overflow: visible;\n transition: height 0.1s ease;\n}\n\n.sp-progress:hover .sp-progress-track {\n height: var(--sp-bar-hover-height);\n}\n\n.sp-progress-buffered,\n.sp-progress-played {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n}\n\n.sp-progress-buffered {\n background: rgba(255, 255, 255, 0.35);\n}\n\n.sp-progress-played {\n background: var(--sp-accent);\n}\n\n.sp-progress-thumb {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--sp-accent);\n transform: translate(-50%, -50%) scale(0);\n transition: transform 0.1s ease;\n pointer-events: none;\n}\n\n.sp-progress:hover .sp-progress-thumb,\n.sp-progress.sp-dragging .sp-progress-thumb {\n transform: translate(-50%, -50%) scale(1);\n}\n\n.sp-progress-tooltip {\n position: absolute;\n bottom: 18px;\n transform: translateX(-50%);\n padding: 2px 6px;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 3px;\n font-size: 12px;\n display: none;\n pointer-events: none;\n white-space: nowrap;\n}\n\n.sp-progress:hover .sp-progress-tooltip {\n display: block;\n}\n\n/* ---------- \u63A7\u5236\u6309\u94AE\u884C ---------- */\n.sp-controls {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.sp-controls-spacer {\n flex: 1;\n}\n\n.sp-btn {\n width: var(--sp-control-size);\n height: var(--sp-control-size);\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n padding: 0;\n opacity: 0.9;\n transition: opacity 0.1s ease, background 0.1s ease;\n}\n\n.sp-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.15);\n}\n\n.sp-btn svg {\n width: 22px;\n height: 22px;\n}\n\n.sp-btn:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.sp-time {\n padding: 0 8px;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n opacity: 0.95;\n}\n\n/* ---------- \u5F39\u51FA\u83DC\u5355 ---------- */\n.sp-menu {\n position: relative;\n}\n\n.sp-menu-btn {\n min-width: var(--sp-control-size);\n width: auto;\n padding: 0 8px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.sp-menu-panel {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n min-width: 80px;\n max-height: 220px;\n overflow-y: auto;\n background: rgba(28, 28, 28, 0.95);\n border-radius: 6px;\n padding: 4px 0;\n display: none;\n z-index: 25;\n}\n\n.sp-menu.sp-open .sp-menu-panel {\n display: block;\n}\n\n.sp-menu-item {\n display: block;\n width: 100%;\n padding: 7px 16px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n text-align: center;\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n}\n\n.sp-menu-item:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n.sp-menu-item.sp-active {\n color: var(--sp-accent);\n font-weight: 600;\n}\n\n.sp-menu-empty {\n padding: 7px 16px;\n opacity: 0.5;\n white-space: nowrap;\n}\n\n/* ---------- \u72B6\u6001\u8499\u5C42\uFF1Aloading / \u9519\u8BEF / \u7ED3\u675F ---------- */\n.sp-state {\n position: absolute;\n inset: 0;\n z-index: 15;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n}\n\n.sp-spinner {\n opacity: 0;\n transition: opacity 0.2s ease 0.3s; /* \u5EF6\u8FDF\u51FA\u73B0\uFF0C\u907F\u514D\u77ED\u6682 seek \u95EA\u70C1 */\n}\n\n.sp-state.sp-loading .sp-spinner {\n opacity: 1;\n}\n\n.sp-spinner-ring {\n width: 44px;\n height: 44px;\n border: 4px solid rgba(255, 255, 255, 0.25);\n border-top-color: var(--sp-accent);\n border-radius: 50%;\n animation: sp-spin 0.8s linear infinite;\n}\n\n@keyframes sp-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.sp-state-panel {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 14px;\n background: rgba(0, 0, 0, 0.55);\n pointer-events: auto;\n}\n\n.sp-state-message {\n font-size: 15px;\n opacity: 0.95;\n}\n\n.sp-state-actions {\n display: flex;\n gap: 12px;\n}\n\n.sp-state-btn {\n padding: 8px 22px;\n border: 1px solid rgba(255, 255, 255, 0.5);\n border-radius: 18px;\n background: transparent;\n color: var(--sp-text);\n font-size: 14px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.sp-state-btn:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.sp-state-btn-primary {\n background: var(--sp-accent);\n border-color: var(--sp-accent);\n}\n\n.sp-state-btn-primary:hover {\n background: var(--sp-accent);\n filter: brightness(1.1);\n}\n\n.sp-state-countdown {\n font-size: 13px;\n opacity: 0.85;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sp-state-cancel {\n border: none;\n background: transparent;\n color: var(--sp-accent);\n cursor: pointer;\n font-size: 13px;\n padding: 2px 6px;\n}\n\n/* ---------- \u8BBE\u7F6E\u9762\u677F ---------- */\n.sp-settings-panel {\n position: absolute;\n bottom: calc(100% + 8px);\n right: 0;\n width: 180px;\n background: rgba(28, 28, 28, 0.95);\n border-radius: 6px;\n padding: 4px 0;\n display: none;\n z-index: 25;\n}\n\n.sp-settings.sp-open .sp-settings-panel {\n display: block;\n}\n\n.sp-settings-row {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 7px 12px;\n border: none;\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n gap: 4px;\n}\n\n.sp-settings-row:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n.sp-settings-label {\n flex: 1;\n text-align: left;\n}\n\n.sp-settings-value {\n opacity: 0.6;\n font-size: 12px;\n}\n\n.sp-settings-arrow {\n display: inline-flex;\n align-items: center;\n opacity: 0.5;\n}\n\n.sp-settings-arrow svg {\n width: 16px;\n height: 16px;\n}\n\n.sp-settings-back {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 7px 12px;\n border: none;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n background: transparent;\n color: var(--sp-text);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n gap: 2px;\n margin-bottom: 2px;\n}\n\n.sp-settings-back:hover {\n background: rgba(255, 255, 255, 0.08);\n}\n\n.sp-settings-back-arrow {\n display: inline-flex;\n align-items: center;\n opacity: 0.7;\n}\n\n.sp-settings-back-arrow svg {\n width: 18px;\n height: 18px;\n}\n\n.sp-settings-sub .sp-menu-item {\n text-align: left;\n padding: 7px 16px;\n}\n\n/* ---------- \u884C\u5185\u5F00\u5173 ---------- */\n.sp-settings-toggle-row {\n cursor: pointer;\n}\n\n.sp-toggle {\n position: relative;\n width: 30px;\n height: 17px;\n background: rgba(255, 255, 255, 0.25);\n border-radius: 9px;\n flex-shrink: 0;\n transition: background 0.15s ease;\n outline: none;\n}\n\n.sp-toggle:focus-visible {\n box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.4);\n}\n\n.sp-toggle.sp-on {\n background: var(--sp-accent);\n}\n\n.sp-toggle-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 13px;\n height: 13px;\n background: #fff;\n border-radius: 50%;\n transition: transform 0.15s ease;\n}\n\n.sp-toggle.sp-on .sp-toggle-thumb {\n transform: translateX(13px);\n}\n\n/* ---------- \u97F3\u91CF ---------- */\n.sp-volume {\n display: flex;\n align-items: center;\n}\n\n.sp-volume-slider {\n width: 0;\n overflow: hidden;\n transition: width 0.15s ease;\n display: flex;\n align-items: center;\n}\n\n.sp-volume:hover .sp-volume-slider,\n.sp-volume.sp-dragging .sp-volume-slider {\n width: 64px;\n}\n\n.sp-volume-track {\n position: relative;\n width: 56px;\n height: var(--sp-bar-height);\n margin: 0 4px;\n background: rgba(255, 255, 255, 0.25);\n border-radius: 2px;\n cursor: pointer;\n}\n\n.sp-volume-fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--sp-text);\n border-radius: 2px;\n}\n\n.sp-volume-thumb {\n position: absolute;\n top: 50%;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--sp-text);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n";
|
|
1215
1375
|
|
|
1216
1376
|
// src/player.ts
|
|
1217
1377
|
var DEFAULT_RATES = [0.5, 1, 1.5, 2];
|
|
@@ -1650,10 +1810,12 @@ var SweetPlayer = class {
|
|
|
1650
1810
|
);
|
|
1651
1811
|
listen("enterpictureinpicture", () => {
|
|
1652
1812
|
log("\u64AD\u653E\u5668", "\u8FDB\u5165\u753B\u4E2D\u753B");
|
|
1813
|
+
this.controls.updatePip(true);
|
|
1653
1814
|
this.emitter.emit("pipchange", true);
|
|
1654
1815
|
});
|
|
1655
1816
|
listen("leavepictureinpicture", () => {
|
|
1656
1817
|
log("\u64AD\u653E\u5668", "\u9000\u51FA\u753B\u4E2D\u753B");
|
|
1818
|
+
this.controls.updatePip(false);
|
|
1657
1819
|
this.emitter.emit("pipchange", false);
|
|
1658
1820
|
});
|
|
1659
1821
|
const onVideoClick = (e) => {
|