@vplayer/core 0.2.2 → 0.3.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/dist/index.js CHANGED
@@ -188,12 +188,96 @@ function f(e) {
188
188
  return Number.isFinite(e) && e > 0;
189
189
  }
190
190
  //#endregion
191
+ //#region src/media-session.ts
192
+ var p = 10, m = 1, h = [
193
+ "play",
194
+ "pause",
195
+ "seekbackward",
196
+ "seekforward",
197
+ "seekto"
198
+ ];
199
+ function g() {
200
+ return typeof navigator > "u" || !("mediaSession" in navigator) ? null : navigator.mediaSession;
201
+ }
202
+ function _(e, t, n) {
203
+ if (typeof e.setActionHandler == "function") try {
204
+ e.setActionHandler(t, n);
205
+ } catch {}
206
+ }
207
+ function v() {
208
+ let e = null, t, n, r = !1, i = NaN, a = NaN, o = NaN;
209
+ function s() {
210
+ let r = g();
211
+ r && e && r.metadata === e && (r.metadata = null), e = null, t = void 0, n = void 0;
212
+ }
213
+ function c(e) {
214
+ let t = g();
215
+ !t || r || (_(t, "play", () => e.play()), _(t, "pause", () => e.pause()), _(t, "seekbackward", (t) => {
216
+ e.skip(-(t.seekOffset ?? p));
217
+ }), _(t, "seekforward", (t) => {
218
+ e.skip(t.seekOffset ?? p);
219
+ }), _(t, "seekto", (t) => {
220
+ typeof t.seekTime == "number" && e.seek(t.seekTime);
221
+ }), r = !0);
222
+ }
223
+ function l(r, i) {
224
+ let a = g();
225
+ if (!a || typeof MediaMetadata > "u") return;
226
+ let o = r?.trim() || void 0;
227
+ if (!o) {
228
+ s();
229
+ return;
230
+ }
231
+ if (e && a.metadata === e && t === o && n === i) return;
232
+ let c = new MediaMetadata({
233
+ title: o,
234
+ artwork: i ? [{ src: i }] : []
235
+ });
236
+ a.metadata = c, e = c, t = o, n = i;
237
+ }
238
+ function u(e) {
239
+ let t = g();
240
+ t && (t.playbackState = e);
241
+ }
242
+ function d(e, t, n, r = !1) {
243
+ let s = g();
244
+ if (!(!s || typeof s.setPositionState != "function") && !(!f(e) || !Number.isFinite(t) || t < 0) && !(!r && Number.isFinite(i) && Math.abs(t - i) < m && e === a && n === o)) try {
245
+ s.setPositionState({
246
+ duration: e,
247
+ playbackRate: n,
248
+ position: Math.min(t, e)
249
+ }), i = t, a = e, o = n;
250
+ } catch {}
251
+ }
252
+ function v() {
253
+ let e = g();
254
+ if (e) {
255
+ if (r) {
256
+ for (let t of h) _(e, t, null);
257
+ r = !1;
258
+ }
259
+ e.playbackState = "none";
260
+ }
261
+ s(), i = NaN, a = NaN, o = NaN;
262
+ }
263
+ return {
264
+ setup: c,
265
+ syncMetadata: l,
266
+ setPlaybackState: u,
267
+ syncPosition: d,
268
+ get hasMetadata() {
269
+ return e !== null;
270
+ },
271
+ teardown: v
272
+ };
273
+ }
274
+ //#endregion
191
275
  //#region src/storage.ts
192
- var ee = "vplayer", p = class {
276
+ var y = "vplayer", b = class {
193
277
  fallback = /* @__PURE__ */ new Map();
194
278
  prefix;
195
279
  constructor(e = {}) {
196
- this.prefix = e.prefix ?? ee;
280
+ this.prefix = e.prefix ?? y;
197
281
  }
198
282
  fullKey(e) {
199
283
  return `${this.prefix}:${e}`;
@@ -234,7 +318,7 @@ var ee = "vplayer", p = class {
234
318
  } catch {}
235
319
  this.fallback.clear();
236
320
  }
237
- }, m = {
321
+ }, x = {
238
322
  VOLUME: "volume",
239
323
  MUTED: "muted",
240
324
  PLAYBACK_RATE: "playbackRate",
@@ -244,21 +328,30 @@ var ee = "vplayer", p = class {
244
328
  LOOP: "loop",
245
329
  FLIP: "flip",
246
330
  ASPECT_RATIO: "aspectRatio"
247
- }, te = class {
331
+ }, ee = class {
248
332
  storage;
249
- constructor(e = new p({ prefix: "vplayer:progress" })) {
250
- this.storage = e;
333
+ maxEntries;
334
+ constructor(e = new b(), t = 100) {
335
+ this.storage = e, this.maxEntries = t;
251
336
  }
252
337
  async load(e) {
253
- return this.storage.get(encodeURIComponent(e)) ?? null;
338
+ return this.storage.get("progress")?.[e] ?? null;
254
339
  }
255
340
  async save(e, t) {
256
- this.storage.set(encodeURIComponent(e), t);
341
+ let n = this.storage.get("progress") ?? {};
342
+ delete n[e], n[e] = t;
343
+ let r = Object.keys(n);
344
+ for (; r.length > this.maxEntries;) {
345
+ let e = r.shift();
346
+ e !== void 0 && delete n[e];
347
+ }
348
+ this.storage.set("progress", n);
257
349
  }
258
350
  async clear(e) {
259
- this.storage.remove(encodeURIComponent(e));
351
+ let t = this.storage.get("progress") ?? {};
352
+ delete t[e], Object.keys(t).length === 0 ? this.storage.remove("progress") : this.storage.set("progress", t);
260
353
  }
261
- }, h = class {
354
+ }, S = class {
262
355
  element;
263
356
  destroyed = !1;
264
357
  listeners = /* @__PURE__ */ new Map();
@@ -406,9 +499,9 @@ var ee = "vplayer", p = class {
406
499
  this.domListeners = [];
407
500
  }
408
501
  destroy() {
409
- this.destroyed || (this.destroyed = !0, this.detachDOMListeners(), this.listeners.clear());
502
+ this.destroyed || (this.destroyed = !0, this.element.pause(), this.detachDOMListeners(), this.listeners.clear());
410
503
  }
411
- }, g = class extends h {}, _ = class extends h {
504
+ }, C = class extends S {}, w = class extends S {
412
505
  hls = null;
413
506
  hlsSrc;
414
507
  hlsConfig;
@@ -446,7 +539,7 @@ var ee = "vplayer", p = class {
446
539
  destroy() {
447
540
  this.destroyed || (super.destroy(), this.hls &&= (this.hls.destroy(), null));
448
541
  }
449
- }, v = class extends h {
542
+ }, T = class extends S {
450
543
  dashPlayer = null;
451
544
  dashSrc;
452
545
  dashConfig;
@@ -474,37 +567,37 @@ var ee = "vplayer", p = class {
474
567
  };
475
568
  //#endregion
476
569
  //#region src/source-resolver.ts
477
- function y(e) {
570
+ function E(e) {
478
571
  try {
479
572
  return new URL(e, typeof window < "u" ? window.location.href : "http://localhost").pathname.toLowerCase();
480
573
  } catch {
481
574
  return e.toLowerCase().split("?")[0].split("#")[0];
482
575
  }
483
576
  }
484
- function b(e) {
485
- let t = e.type?.toLowerCase() ?? "", n = y(e.src);
577
+ function D(e) {
578
+ let t = e.type?.toLowerCase() ?? "", n = E(e.src);
486
579
  return t.includes("mpegurl") || t.includes("hls") || n.endsWith(".m3u8") ? "hls" : t.includes("dash") || n.endsWith(".mpd") ? "dash" : /\.(mp4|m4v|webm|ogv|ogg|mov)$/i.test(n) || t.startsWith("video/") ? "native" : "unknown";
487
580
  }
488
- function x(e) {
581
+ function O(e) {
489
582
  return {
490
583
  src: e.src,
491
584
  type: e.type
492
585
  };
493
586
  }
494
- function ne(e, t) {
587
+ function te(e, t) {
495
588
  if (t.engine) return typeof t.engine == "function" ? t.engine(e) : t.engine;
496
- let n = x(t), r = b(n);
497
- return r === "hls" && !s(e) ? new _(e, {
589
+ let n = O(t), r = D(n);
590
+ return r === "hls" && !s(e) ? new w(e, {
498
591
  src: n.src,
499
592
  hlsConfig: t.hlsConfig
500
- }) : r === "dash" ? new v(e, {
593
+ }) : r === "dash" ? new T(e, {
501
594
  src: n.src,
502
595
  dashConfig: t.dashConfig
503
- }) : (e.src = n.src, new g(e));
596
+ }) : (e.src = n.src, new C(e));
504
597
  }
505
598
  //#endregion
506
599
  //#region src/subtitle-parser.ts
507
- var S = {
600
+ var k = {
508
601
  fontSize: "medium",
509
602
  fontScale: 100,
510
603
  fontFamily: "sans",
@@ -517,16 +610,16 @@ var S = {
517
610
  position: 0,
518
611
  lineHeight: 1.35,
519
612
  delay: 0
520
- }, C = "(?:\\d{2}:)?\\d{2}:\\d{2}[.,]\\d{3}", w = RegExp(`^(${C})\\s*-->\\s*(${C})(?:\\s+(.*))?$`);
521
- function T(e) {
613
+ }, A = "(?:\\d{2}:)?\\d{2}:\\d{2}[.,]\\d{3}", j = RegExp(`^(${A})\\s*-->\\s*(${A})(?:\\s+(.*))?$`);
614
+ function M(e) {
522
615
  return e.replace(/^\uFEFF/, "").replace(/\r\n?/g, "\n");
523
616
  }
524
- function E(e) {
617
+ function N(e) {
525
618
  let t = e.replace(",", ".").split(":").map(Number);
526
619
  return t.some((e) => !Number.isFinite(e)) ? NaN : t.length === 3 ? t[0] * 3600 + t[1] * 60 + t[2] : t.length === 2 ? t[0] * 60 + t[1] : t[0];
527
620
  }
528
- function D(e, t) {
529
- let n = T(e).trim();
621
+ function P(e, t) {
622
+ let n = M(e).trim();
530
623
  if (t === "vtt") {
531
624
  let e = n.indexOf("\n");
532
625
  n = (e === -1 ? "" : n.slice(e + 1)).trim();
@@ -535,11 +628,11 @@ function D(e, t) {
535
628
  for (let e of n.split(/\n{2,}/)) {
536
629
  let t = e.split("\n").map((e) => e.trimEnd()), n = t[0]?.trim();
537
630
  if (!n || n.startsWith("NOTE") || n === "STYLE" || n === "REGION") continue;
538
- let i = t.findIndex((e) => w.test(e.trim()));
631
+ let i = t.findIndex((e) => j.test(e.trim()));
539
632
  if (i === -1) continue;
540
- let a = w.exec(t[i].trim());
633
+ let a = j.exec(t[i].trim());
541
634
  if (!a) continue;
542
- let o = E(a[1]), s = E(a[2]), c = t.slice(i + 1).filter((e) => e.trim().length > 0).join("\n");
635
+ let o = N(a[1]), s = N(a[2]), c = t.slice(i + 1).filter((e) => e.trim().length > 0).join("\n");
543
636
  if (!Number.isFinite(o) || !Number.isFinite(s) || s <= o || !c) continue;
544
637
  let l = i > 0 ? t[i - 1]?.trim() : void 0;
545
638
  r.push({
@@ -553,14 +646,14 @@ function D(e, t) {
553
646
  }
554
647
  return r;
555
648
  }
556
- function O(e) {
557
- return D(e, "srt");
649
+ function F(e) {
650
+ return P(e, "srt");
558
651
  }
559
- function k(e) {
560
- return D(e, "vtt");
652
+ function I(e) {
653
+ return P(e, "vtt");
561
654
  }
562
- function A(e, t = {}) {
563
- let n = T(e).trimStart(), r = t.fileName?.toLowerCase().match(/\\.(vtt|srt)$/)?.[1], i = t.mimeType === "text/vtt" ? "vtt" : t.mimeType === "application/x-subrip" ? "srt" : void 0, a = n.startsWith("WEBVTT") ? "vtt" : w.test(n.split("\n")[0] ?? "") ? "srt" : void 0, o = t.format ?? i ?? r ?? a;
655
+ function L(e, t = {}) {
656
+ let n = M(e).trimStart(), r = t.fileName?.toLowerCase().match(/\\.(vtt|srt)$/)?.[1], i = t.mimeType === "text/vtt" ? "vtt" : t.mimeType === "application/x-subrip" ? "srt" : void 0, a = n.startsWith("WEBVTT") ? "vtt" : j.test(n.split("\n")[0] ?? "") ? "srt" : void 0, o = t.format ?? i ?? r ?? a;
564
657
  if (!o) return {
565
658
  ok: !1,
566
659
  error: {
@@ -568,7 +661,7 @@ function A(e, t = {}) {
568
661
  message: "Expected a WebVTT or SRT subtitle file."
569
662
  }
570
663
  };
571
- let s = o === "vtt" ? k(n) : O(n);
664
+ let s = o === "vtt" ? I(n) : F(n);
572
665
  return s.length === 0 ? {
573
666
  ok: !1,
574
667
  error: {
@@ -581,9 +674,9 @@ function A(e, t = {}) {
581
674
  cues: s
582
675
  };
583
676
  }
584
- async function j(e, t) {
677
+ async function R(e, t) {
585
678
  if (e.content !== void 0) {
586
- let t = A(e.content, {
679
+ let t = L(e.content, {
587
680
  format: e.format,
588
681
  fileName: e.label
589
682
  });
@@ -593,7 +686,7 @@ async function j(e, t) {
593
686
  if (!e.src) throw Error("Subtitle track has no source.");
594
687
  let n = await fetch(e.src, { signal: t });
595
688
  if (!n.ok) throw Error(`Failed to fetch subtitles: ${n.status}`);
596
- let r = A(await n.text(), {
689
+ let r = L(await n.text(), {
597
690
  format: e.format,
598
691
  fileName: e.src,
599
692
  mimeType: n.headers.get("content-type")?.split(";")[0]
@@ -601,7 +694,7 @@ async function j(e, t) {
601
694
  if (!r.ok) throw Error(r.error.message);
602
695
  return r.cues;
603
696
  }
604
- function M(e, t) {
697
+ function z(e, t) {
605
698
  let n = 0, r = e.length - 1;
606
699
  for (; n <= r;) {
607
700
  let i = n + r >> 1, a = e[i];
@@ -611,7 +704,7 @@ function M(e, t) {
611
704
  }
612
705
  return null;
613
706
  }
614
- function N(e) {
707
+ function ne(e) {
615
708
  let t = e.match(/#xywh=(\d+),(\d+),(\d+),(\d+)/);
616
709
  return t ? {
617
710
  src: e.replace(/#xywh=.*$/, ""),
@@ -621,7 +714,7 @@ function N(e) {
621
714
  h: Number(t[4])
622
715
  } : null;
623
716
  }
624
- function P(e) {
717
+ function B(e) {
625
718
  let t = e.replace(/\r\n/g, "\n"), n = t.indexOf("\n\n");
626
719
  return n > 0 && (t = t.slice(n + 2)), t.trim().split(/\n\n+/).map((e) => {
627
720
  let t = e.split("\n"), n = t.findIndex((e) => e.includes("-->"));
@@ -630,7 +723,7 @@ function P(e) {
630
723
  if (!r) return null;
631
724
  let i = t.slice(n + 1).find((e) => e.trim().length > 0);
632
725
  if (!i) return null;
633
- let a = i.trim(), o = N(a), s = E(r[1]), c = E(r[2]);
726
+ let a = i.trim(), o = ne(a), s = N(r[1]), c = N(r[2]);
634
727
  return o ? {
635
728
  start: s,
636
729
  end: c,
@@ -650,7 +743,7 @@ function P(e) {
650
743
  };
651
744
  }).filter((e) => e !== null);
652
745
  }
653
- function F(e, t) {
746
+ function V(e, t) {
654
747
  try {
655
748
  return new URL(e, t).toString();
656
749
  } catch {
@@ -661,9 +754,9 @@ async function re(e, t, n) {
661
754
  let r = await fetch(e, { signal: t });
662
755
  if (!r.ok) throw Error(`Failed to fetch thumbnail VTT: ${r.status}`);
663
756
  let i = r.url || e, a = await r.text();
664
- return P(n ? await n(a, i) : a).map((e) => (e.src = F(e.src, i), e));
757
+ return B(n ? await n(a, i) : a).map((e) => (e.src = V(e.src, i), e));
665
758
  }
666
- function I(e, t) {
759
+ function ie(e, t) {
667
760
  if (e.length === 0) return null;
668
761
  let n = 0, r = e.length - 1;
669
762
  for (; n <= r;) {
@@ -676,10 +769,10 @@ function I(e, t) {
676
769
  }
677
770
  //#endregion
678
771
  //#region src/state/slices.ts
679
- function ie() {
680
- return new e(L());
772
+ function ae() {
773
+ return new e(H());
681
774
  }
682
- function L() {
775
+ function H() {
683
776
  return {
684
777
  status: "idle",
685
778
  source: null,
@@ -706,7 +799,7 @@ function L() {
706
799
  subtitleSearchResults: [],
707
800
  subtitleSearchStatus: "idle",
708
801
  subtitleSearchError: null,
709
- captionSettings: { ...S },
802
+ captionSettings: { ...k },
710
803
  activeQuality: "Auto",
711
804
  qualities: [],
712
805
  controlsVisible: !0,
@@ -730,7 +823,7 @@ function L() {
730
823
  resumeState: { status: "idle" }
731
824
  };
732
825
  }
733
- var R = (e) => ({
826
+ var U = (e) => ({
734
827
  status: e.status,
735
828
  source: e.source,
736
829
  isPlaying: e.isPlaying,
@@ -743,10 +836,10 @@ var R = (e) => ({
743
836
  playbackRate: e.playbackRate,
744
837
  isLive: e.isLive,
745
838
  resumeState: e.resumeState
746
- }), ae = (e) => ({
839
+ }), W = (e) => ({
747
840
  volume: e.volume,
748
841
  isMuted: e.isMuted
749
- }), z = (e) => ({
842
+ }), G = (e) => ({
750
843
  isLooping: e.isLooping,
751
844
  flip: e.flip,
752
845
  aspectRatio: e.aspectRatio,
@@ -762,7 +855,7 @@ var R = (e) => ({
762
855
  captionSettings: e.captionSettings,
763
856
  activeQuality: e.activeQuality,
764
857
  qualities: e.qualities
765
- }), B = (e) => ({
858
+ }), K = (e) => ({
766
859
  controlsVisible: e.controlsVisible,
767
860
  capabilities: e.capabilities,
768
861
  isFullscreen: e.isFullscreen,
@@ -774,18 +867,27 @@ var R = (e) => ({
774
867
  layers: e.layers,
775
868
  contextMenuItems: e.contextMenuItems,
776
869
  contextMenuEnabled: e.contextMenuEnabled
777
- }), V = (e) => ({ thumbnailCues: e.thumbnailCues }), H = (e) => e.error, U = [
870
+ }), se = (e) => ({ thumbnailCues: e.thumbnailCues }), q = (e) => e.error, J = [
778
871
  "default",
779
872
  "16:9",
780
873
  "4:3",
781
874
  "21:9",
782
875
  "cover",
783
876
  "fill"
784
- ], se = 5e3, ce = 2, le = {
877
+ ], ce = 5e3, le = 2;
878
+ function ue(e) {
879
+ try {
880
+ let t = new URL(e, typeof document > "u" ? void 0 : document.baseURI);
881
+ return t.search = "", t.hash = "", t.href;
882
+ } catch {
883
+ return e.split(/[?#]/, 1)[0] ?? e;
884
+ }
885
+ }
886
+ var de = {
785
887
  "16:9": "16 / 9",
786
888
  "4:3": "4 / 3",
787
889
  "21:9": "21 / 9"
788
- }, ue = {
890
+ }, fe = {
789
891
  default: "default",
790
892
  "16:9": "16-9",
791
893
  "4:3": "4-3",
@@ -793,111 +895,108 @@ var R = (e) => ({
793
895
  cover: "cover",
794
896
  fill: "fill"
795
897
  };
796
- function de(e) {
898
+ function pe(e) {
797
899
  e.classList.remove("vplayer--media-default", "vplayer--media-16-9", "vplayer--media-4-3", "vplayer--media-21-9", "vplayer--media-cover", "vplayer--media-fill");
798
900
  }
799
- function fe(e) {
800
- return typeof e == "string" && e in ue ? e : "default";
901
+ function me(e) {
902
+ return typeof e == "string" && e in fe ? e : "default";
801
903
  }
802
- function pe(e) {
904
+ function he(e) {
803
905
  return e === "cover" ? "cover" : e === "fill" ? "fill" : "contain";
804
906
  }
805
- function W(e) {
907
+ function Y(e) {
806
908
  return {
807
909
  ...e,
808
910
  id: e.id ?? `${e.local ? "local" : "track"}:${e.src ?? e.label}:${e.lang}`
809
911
  };
810
912
  }
811
- function G(e) {
812
- let r = ie(), i = { ...e }, o = new t(), s = new p(), c = new a(i.lang);
913
+ function ge(e) {
914
+ let r = ae(), i = { ...e }, o = new t(), s = new b(), c = new a(i.lang);
813
915
  i.translations && c.addTranslations(i.lang ?? "en", i.translations);
814
- let l = new n(), u = i.reconnectMax ?? 3, ee = i.reconnectSleep ?? 1500, h = null, g = null, _ = null, v = 0, y = NaN, b = null, C = 0, w = null, T = null, E = null, D = null, O = new te(), k = 0, A = !1, M = !1, N = null, P = [], F = !1;
916
+ let l = new n(), u = i.reconnectMax ?? 3, p = i.reconnectSleep ?? 1500, m = null, h = null, g = null, _ = 0, y = NaN, S = null, C = 0, w = null, T = null, E = null, D = v(), A = new ee(), j = 0, M = !1, N = null, P = [], F = !1;
815
917
  function I(e) {
918
+ let t = e.playbackProgress?.id ?? (e.playbackProgress?.normalizeUrl === !1 ? e.src : ue(e.src));
816
919
  return {
817
- generation: k,
818
- id: e.playbackProgress?.id ?? e.src,
819
- store: e.playbackProgress?.store ?? O
920
+ generation: j,
921
+ id: t,
922
+ store: e.playbackProgress?.store ?? A
820
923
  };
821
924
  }
822
925
  let L = I(i);
823
- function R() {
926
+ function z() {
824
927
  if (F) return;
825
928
  let e = P.shift();
826
929
  e && (F = !0, (e.kind === "save" ? e.target.store.save(e.target.id, e.progress) : e.target.store.clear(e.target.id)).catch((t) => {
827
930
  console.warn(e.kind === "save" ? "[vplayer] playback progress save failed:" : "[vplayer] playback progress clear failed:", t);
828
931
  }).finally(() => {
829
- F = !1, R();
932
+ F = !1, z();
830
933
  }));
831
934
  }
832
- function ae(e, t) {
935
+ function ne(e, t) {
833
936
  let n = P.at(-1);
834
937
  n?.kind === "save" && n.target.generation === e.generation ? n.progress = t : P.push({
835
938
  kind: "save",
836
939
  target: e,
837
940
  progress: t
838
- }), R();
941
+ }), z();
839
942
  }
840
- function z(e) {
943
+ function B(e) {
841
944
  P.push({
842
945
  kind: "clear",
843
946
  target: e
844
- }), R();
947
+ }), z();
845
948
  }
846
- function B(e = L, t = g) {
847
- !t || t.ended || !Number.isFinite(t.currentTime) || t.currentTime < 0 || !f(t.duration) || (v = Date.now(), y = t.currentTime, ae(e, {
949
+ function V(e = L, t = h) {
950
+ !t || t.ended || r.state.resumeState.status === "prompt" || !Number.isFinite(t.currentTime) || t.currentTime <= 3 || !f(t.duration) || (_ = Date.now(), y = t.currentTime, ne(e, {
848
951
  time: t.currentTime,
849
952
  duration: t.duration
850
953
  }));
851
954
  }
852
- function oe(e) {
853
- !r.state.isPlaying || Date.now() - v < se || Number.isFinite(y) && Math.abs(e.currentTime - y) < ce || B(L, e);
955
+ function ie(e) {
956
+ !r.state.isPlaying || Date.now() - _ < ce || Number.isFinite(y) && Math.abs(e.currentTime - y) < le || V(L, e);
854
957
  }
855
- function V() {
856
- k++, L = I(i), A = !1, M = !1, v = 0, y = NaN, r.setState((e) => ({
958
+ function H() {
959
+ j++, L = I(i), M = !1, _ = 0, y = NaN, r.setState((e) => ({
857
960
  ...e,
858
961
  resumeState: { status: "idle" }
859
962
  }));
860
963
  }
861
- function H(e) {
862
- if (A || !f(e.duration)) return;
863
- A = !0;
964
+ function U(e) {
965
+ if (M || !f(e.duration)) return;
966
+ M = !0;
864
967
  let t = L, n = e.duration;
865
968
  r.setState((e) => ({
866
969
  ...e,
867
970
  resumeState: { status: "loading" }
868
- })), t.store.load(t.id).then((a) => {
869
- let o = i.autoPlay === !0;
870
- if (t.generation === k && e === g) {
871
- if (!a || !o && (M || e.currentTime !== 0) || !Number.isFinite(a.time) || !Number.isFinite(a.duration) || a.time <= 3 || a.time >= n - 3 || Math.abs(a.duration - n) > Math.max(1, n * .01)) {
971
+ })), t.store.load(t.id).then((i) => {
972
+ if (t.generation === j && e === h) {
973
+ if (!i || !Number.isFinite(i.time) || !Number.isFinite(i.duration) || i.time <= 3 || i.time >= n - 3 || Math.abs(i.duration - n) > Math.max(1, n * .01)) {
872
974
  r.setState((e) => ({
873
975
  ...e,
874
976
  resumeState: { status: "idle" }
875
977
  }));
876
978
  return;
877
979
  }
878
- o ? (e.seek(a.time), r.setState((e) => ({
879
- ...e,
880
- resumeState: { status: "idle" }
881
- }))) : r.setState((e) => ({
980
+ r.setState((e) => ({
882
981
  ...e,
883
982
  resumeState: {
884
983
  status: "prompt",
885
- progress: a
984
+ progress: i
886
985
  }
887
986
  }));
888
987
  }
889
988
  }).catch((n) => {
890
- t.generation === k && e === g && r.setState((e) => ({
989
+ t.generation === j && e === h && r.setState((e) => ({
891
990
  ...e,
892
991
  resumeState: { status: "idle" }
893
992
  })), console.warn("[vplayer] playback progress load failed:", n);
894
993
  });
895
994
  }
896
- function G(e) {
995
+ function W(e) {
897
996
  r.setState((t) => {
898
997
  let n = new Map(t.subtitleTracks.map((e) => [e.id, e]));
899
998
  for (let t of e) {
900
- let e = W(t);
999
+ let e = Y(t);
901
1000
  n.set(e.id, e);
902
1001
  }
903
1002
  return {
@@ -906,7 +1005,7 @@ function G(e) {
906
1005
  };
907
1006
  });
908
1007
  }
909
- function K(e) {
1008
+ function G(e) {
910
1009
  T?.abort();
911
1010
  let t = new AbortController();
912
1011
  T = t, r.setState((t) => ({
@@ -915,7 +1014,7 @@ function G(e) {
915
1014
  subtitleCues: [],
916
1015
  subtitleStatus: "loading",
917
1016
  subtitleError: null
918
- })), j(e, t.signal).then((e) => {
1017
+ })), R(e, t.signal).then((e) => {
919
1018
  t.signal.aborted || r.setState((t) => ({
920
1019
  ...t,
921
1020
  subtitleCues: e,
@@ -931,7 +1030,7 @@ function G(e) {
931
1030
  }));
932
1031
  });
933
1032
  }
934
- function q() {
1033
+ function K() {
935
1034
  let e = (i.subtitleProviders ?? []).map(({ id: e, label: t }) => ({
936
1035
  id: e,
937
1036
  label: t
@@ -944,7 +1043,7 @@ function G(e) {
944
1043
  subtitleSearchError: null
945
1044
  }));
946
1045
  }
947
- function me(e = {}) {
1046
+ function oe(e = {}) {
948
1047
  E?.abort();
949
1048
  let t = i.subtitleProviders ?? [], n = e.providerId ? t.filter((t) => t.id === e.providerId) : t;
950
1049
  if (n.length === 0) {
@@ -984,7 +1083,7 @@ function G(e) {
984
1083
  }));
985
1084
  });
986
1085
  }
987
- function he(e) {
1086
+ function se(e) {
988
1087
  T?.abort();
989
1088
  let t = (i.subtitleProviders ?? []).find((t) => t.id === e.providerId);
990
1089
  if (!t) {
@@ -1004,15 +1103,15 @@ function G(e) {
1004
1103
  subtitleError: null
1005
1104
  })), (async () => {
1006
1105
  try {
1007
- let i = await t.fetch(e, n.signal), a = W({
1106
+ let i = await t.fetch(e, n.signal), a = Y({
1008
1107
  id: `provider:${t.id}:${e.id}`,
1009
1108
  lang: e.language,
1010
1109
  label: e.label,
1011
1110
  format: i.format ?? e.format,
1012
1111
  ...i.content === void 0 ? { src: i.src } : { content: i.content }
1013
- }), o = await j(a, n.signal);
1112
+ }), o = await R(a, n.signal);
1014
1113
  if (n.signal.aborted) return;
1015
- G([a]), r.setState((e) => ({
1114
+ W([a]), r.setState((e) => ({
1016
1115
  ...e,
1017
1116
  activeSubtitle: a,
1018
1117
  subtitleCues: o,
@@ -1030,77 +1129,64 @@ function G(e) {
1030
1129
  }
1031
1130
  })();
1032
1131
  }
1033
- i.subtitles?.length && G(i.subtitles), q();
1034
- function ge() {
1035
- D && typeof navigator < "u" && "mediaSession" in navigator && navigator.mediaSession.metadata === D && (navigator.mediaSession.metadata = null), D = null;
1036
- }
1037
- function _e() {
1038
- if (typeof navigator > "u" || !("mediaSession" in navigator) || typeof MediaMetadata > "u") return;
1039
- let e = i.title?.trim();
1040
- if (!e) {
1041
- ge();
1042
- return;
1043
- }
1044
- let t = new MediaMetadata({
1045
- title: e,
1046
- artwork: i.poster ? [{ src: i.poster }] : []
1047
- });
1048
- navigator.mediaSession.metadata = t, D = t;
1132
+ i.subtitles?.length && W(i.subtitles), K();
1133
+ function q() {
1134
+ return i.mediaSessionArtwork ?? i.poster;
1049
1135
  }
1050
- function ve() {
1136
+ function ge() {
1051
1137
  l.register({
1052
1138
  key: "Space",
1053
1139
  description: "Toggle play/pause",
1054
1140
  handler: (e) => {
1055
- e.preventDefault(), J.togglePlay();
1141
+ e.preventDefault(), Z.togglePlay();
1056
1142
  }
1057
1143
  }), l.register({
1058
1144
  key: "KeyK",
1059
1145
  description: "Toggle play/pause",
1060
1146
  handler: (e) => {
1061
- e.preventDefault(), J.togglePlay();
1147
+ e.preventDefault(), Z.togglePlay();
1062
1148
  }
1063
1149
  }), l.register({
1064
1150
  key: "KeyL",
1065
1151
  description: "Toggle loop",
1066
1152
  handler: (e) => {
1067
- e.preventDefault(), J.toggleLoop();
1153
+ e.preventDefault(), Z.toggleLoop();
1068
1154
  }
1069
1155
  }), l.register({
1070
1156
  key: "KeyI",
1071
1157
  description: "Toggle info panel",
1072
1158
  handler: (e) => {
1073
- e.preventDefault(), J.toggleInfoPanel();
1159
+ e.preventDefault(), Z.toggleInfoPanel();
1074
1160
  }
1075
1161
  }), l.register({
1076
1162
  key: "KeyF",
1077
1163
  description: "Toggle fullscreen",
1078
1164
  handler: (e) => {
1079
- e.preventDefault(), J.toggleFullscreen();
1165
+ e.preventDefault(), Z.toggleFullscreen();
1080
1166
  }
1081
1167
  }), l.register({
1082
1168
  key: "KeyA",
1083
1169
  description: "Cycle aspect ratio",
1084
1170
  handler: (e) => {
1085
- e.preventDefault(), J.cycleAspectRatio();
1171
+ e.preventDefault(), Z.cycleAspectRatio();
1086
1172
  }
1087
1173
  }), l.register({
1088
1174
  key: "KeyM",
1089
1175
  description: "Toggle mute",
1090
1176
  handler: (e) => {
1091
- e.preventDefault(), J.toggleMute();
1177
+ e.preventDefault(), Z.toggleMute();
1092
1178
  }
1093
1179
  }), l.register({
1094
1180
  key: "ArrowLeft",
1095
1181
  description: "Seek backward 5s",
1096
1182
  handler: (e) => {
1097
- e.preventDefault(), J.skip(-5);
1183
+ e.preventDefault(), Z.skip(-5);
1098
1184
  }
1099
1185
  }), l.register({
1100
1186
  key: "ArrowRight",
1101
1187
  description: "Seek forward 5s",
1102
1188
  handler: (e) => {
1103
- e.preventDefault(), J.skip(5);
1189
+ e.preventDefault(), Z.skip(5);
1104
1190
  }
1105
1191
  }), l.register({
1106
1192
  key: "ArrowUp",
@@ -1108,7 +1194,7 @@ function G(e) {
1108
1194
  handler: (e) => {
1109
1195
  e.preventDefault();
1110
1196
  let t = Math.min(1, r.state.volume + .1);
1111
- J.setVolume(t);
1197
+ Z.setVolume(t);
1112
1198
  }
1113
1199
  }), l.register({
1114
1200
  key: "ArrowDown",
@@ -1116,27 +1202,27 @@ function G(e) {
1116
1202
  handler: (e) => {
1117
1203
  e.preventDefault();
1118
1204
  let t = Math.max(0, r.state.volume - .1);
1119
- J.setVolume(t);
1205
+ Z.setVolume(t);
1120
1206
  }
1121
1207
  });
1122
1208
  }
1123
- i.defaultHotkeys !== !1 && ve();
1124
- function ye() {
1209
+ i.defaultHotkeys !== !1 && ge();
1210
+ function X() {
1125
1211
  if (typeof document > "u") return;
1126
1212
  let e = document;
1127
1213
  r.setState((t) => ({
1128
1214
  ...t,
1129
1215
  isFullscreen: !!(document.fullscreenElement || e.webkitFullscreenElement),
1130
- capabilities: d(g?.element ?? void 0, h)
1216
+ capabilities: d(h?.element ?? void 0, m)
1131
1217
  }));
1132
1218
  }
1133
- let J = {
1219
+ let Z = {
1134
1220
  play: () => {
1135
- g?.play();
1221
+ h?.play();
1136
1222
  },
1137
- pause: () => g?.pause(),
1223
+ pause: () => h?.pause(),
1138
1224
  togglePlay: () => {
1139
- let e = g;
1225
+ let e = h;
1140
1226
  e && (e.paused || e.ended ? e.play() : e.pause());
1141
1227
  },
1142
1228
  resumeFromSavedProgress: () => {
@@ -1144,24 +1230,30 @@ function G(e) {
1144
1230
  e.status === "prompt" && (r.setState((e) => ({
1145
1231
  ...e,
1146
1232
  resumeState: { status: "idle" }
1147
- })), g?.seek(e.progress.time), g?.play());
1233
+ })), h?.seek(e.progress.time), h?.play());
1148
1234
  },
1149
1235
  startPlaybackOver: () => {
1150
1236
  let e = L;
1151
1237
  r.setState((e) => ({
1152
1238
  ...e,
1153
1239
  resumeState: { status: "idle" }
1154
- })), g?.seek(0), z(e);
1240
+ })), h?.seek(0), B(e);
1241
+ },
1242
+ dismissSavedProgress: () => {
1243
+ r.setState((e) => ({
1244
+ ...e,
1245
+ resumeState: { status: "idle" }
1246
+ }));
1155
1247
  },
1156
- seek: (e) => g?.seek(e),
1248
+ seek: (e) => h?.seek(e),
1157
1249
  skip: (e) => {
1158
- let t = g;
1250
+ let t = h;
1159
1251
  if (!t) return;
1160
1252
  let n = f(t.duration) ? t.duration : Infinity, r = Math.max(0, Math.min(t.currentTime + e, n));
1161
1253
  t.seek(r);
1162
1254
  },
1163
1255
  setVolume: (e) => {
1164
- let t = g;
1256
+ let t = h;
1165
1257
  if (!t) return;
1166
1258
  let n = Math.max(0, Math.min(1, e));
1167
1259
  t.setVolume(n), n > 0 && t.setMuted(!1), r.setState((e) => ({
@@ -1171,28 +1263,28 @@ function G(e) {
1171
1263
  }));
1172
1264
  },
1173
1265
  toggleMute: () => {
1174
- let e = g;
1266
+ let e = h;
1175
1267
  e && (e.setMuted(!e.muted), r.setState((t) => ({
1176
1268
  ...t,
1177
1269
  isMuted: e.muted
1178
1270
  })));
1179
1271
  },
1180
1272
  setPlaybackRate: (e) => {
1181
- let t = g;
1273
+ let t = h;
1182
1274
  t && (t.setPlaybackRate(e), r.setState((e) => ({
1183
1275
  ...e,
1184
1276
  playbackRate: t.playbackRate
1185
1277
  })));
1186
1278
  },
1187
1279
  toggleFullscreen: () => {
1188
- if (!h || typeof document > "u") return;
1189
- let e = h, t = document, n = !!(document.fullscreenElement || t.webkitFullscreenElement), r = () => {
1190
- h?.focus({ preventScroll: !0 }), ye();
1191
- }, i = n ? typeof document.exitFullscreen == "function" ? document.exitFullscreen() : t.webkitExitFullscreen?.() : typeof h.requestFullscreen == "function" ? h.requestFullscreen() : e.webkitRequestFullscreen?.();
1280
+ if (!m || typeof document > "u") return;
1281
+ let e = m, t = document, n = !!(document.fullscreenElement || t.webkitFullscreenElement), r = () => {
1282
+ m?.focus({ preventScroll: !0 }), X();
1283
+ }, i = n ? typeof document.exitFullscreen == "function" ? document.exitFullscreen() : t.webkitExitFullscreen?.() : typeof m.requestFullscreen == "function" ? m.requestFullscreen() : e.webkitRequestFullscreen?.();
1192
1284
  Promise.resolve(i).then(r, r);
1193
1285
  },
1194
1286
  togglePiP: () => {
1195
- let e = g;
1287
+ let e = h;
1196
1288
  !e || typeof document > "u" || (document.pictureInPictureElement ? e.exitPictureInPicture() : e.requestPictureInPicture());
1197
1289
  },
1198
1290
  setActiveSubtitle: (e) => {
@@ -1206,20 +1298,20 @@ function G(e) {
1206
1298
  }));
1207
1299
  return;
1208
1300
  }
1209
- K(e);
1301
+ G(e);
1210
1302
  },
1211
1303
  addSubtitleTrack: (e) => {
1212
- let t = W(e);
1213
- G([t]), K(t);
1304
+ let t = Y(e);
1305
+ W([t]), G(t);
1214
1306
  },
1215
1307
  removeSubtitleTrack: (e) => {
1216
- r.state.activeSubtitle?.id === e && J.setActiveSubtitle(null), r.setState((t) => ({
1308
+ r.state.activeSubtitle?.id === e && Z.setActiveSubtitle(null), r.setState((t) => ({
1217
1309
  ...t,
1218
1310
  subtitleTracks: t.subtitleTracks.filter((t) => t.id !== e)
1219
1311
  }));
1220
1312
  },
1221
- searchSubtitles: me,
1222
- selectSubtitleResult: he,
1313
+ searchSubtitles: oe,
1314
+ selectSubtitleResult: se,
1223
1315
  clearSubtitleSearch: () => {
1224
1316
  E?.abort(), E = null, r.setState((e) => ({
1225
1317
  ...e,
@@ -1246,9 +1338,12 @@ function G(e) {
1246
1338
  resetCaptionSettings: () => {
1247
1339
  r.setState((e) => ({
1248
1340
  ...e,
1249
- captionSettings: { ...S }
1341
+ captionSettings: { ...k }
1250
1342
  }));
1251
1343
  },
1344
+ saveCaptionSettings: () => {
1345
+ s.set(x.CAPTION_SETTINGS, r.state.captionSettings);
1346
+ },
1252
1347
  setActiveQuality: (e) => {
1253
1348
  r.setState((t) => ({
1254
1349
  ...t,
@@ -1256,7 +1351,7 @@ function G(e) {
1256
1351
  }));
1257
1352
  },
1258
1353
  takeScreenshot: async () => {
1259
- let e = g;
1354
+ let e = h;
1260
1355
  if (!e) return;
1261
1356
  let t = await e.screenshot();
1262
1357
  if (!t) return;
@@ -1264,7 +1359,7 @@ function G(e) {
1264
1359
  r.href = n, r.download = `vplayer-screenshot-${Date.now()}.png`, r.click(), URL.revokeObjectURL(n);
1265
1360
  },
1266
1361
  setFlip: (e) => {
1267
- let t = g?.element;
1362
+ let t = h?.element;
1268
1363
  if (!t) return;
1269
1364
  let n = "";
1270
1365
  e === "horizontal" && (n = "scaleX(-1)"), e === "vertical" && (n = "scaleY(-1)"), t.style.transform = n, r.setState((t) => ({
@@ -1273,20 +1368,20 @@ function G(e) {
1273
1368
  }));
1274
1369
  },
1275
1370
  setAspectRatio: (e) => {
1276
- let t = fe(e), n = g?.element;
1371
+ let t = me(e), n = h?.element;
1277
1372
  if (!n) return;
1278
- let i = le[t];
1279
- i ? n.style.setProperty("--vplayer-media-aspect-ratio", i) : n.style.removeProperty("--vplayer-media-aspect-ratio"), n.style.objectFit = pe(t), n.style.setProperty("--vplayer-media-object-fit", pe(t)), h && (de(h), h.classList.add(`vplayer--media-${ue[t]}`)), r.setState((e) => ({
1373
+ let i = de[t];
1374
+ i ? n.style.setProperty("--vplayer-media-aspect-ratio", i) : n.style.removeProperty("--vplayer-media-aspect-ratio"), n.style.objectFit = he(t), n.style.setProperty("--vplayer-media-object-fit", he(t)), m && (pe(m), m.classList.add(`vplayer--media-${fe[t]}`)), r.setState((e) => ({
1280
1375
  ...e,
1281
1376
  aspectRatio: t
1282
1377
  }));
1283
1378
  },
1284
1379
  cycleAspectRatio: () => {
1285
- let e = r.state.aspectRatio, t = U[(U.indexOf(e) + 1) % U.length] ?? "default";
1286
- J.setAspectRatio(t);
1380
+ let e = r.state.aspectRatio, t = J[(J.indexOf(e) + 1) % J.length] ?? "default";
1381
+ Z.setAspectRatio(t);
1287
1382
  },
1288
1383
  toggleLoop: () => {
1289
- let e = g;
1384
+ let e = h;
1290
1385
  e && (e.setLooping(!e.looping), r.setState((t) => ({
1291
1386
  ...t,
1292
1387
  isLooping: e.looping
@@ -1299,13 +1394,10 @@ function G(e) {
1299
1394
  }));
1300
1395
  }
1301
1396
  };
1302
- function be(e) {
1397
+ function _e(e) {
1303
1398
  return [
1304
1399
  e.on("play", () => {
1305
- M = !0, r.setState((e) => ({
1306
- ...e,
1307
- resumeState: { status: "idle" }
1308
- })), _e(), r.setState((e) => ({
1400
+ D.syncMetadata(i.title, q()), D.setPlaybackState("playing"), r.setState((e) => ({
1309
1401
  ...e,
1310
1402
  status: "playing",
1311
1403
  isPlaying: !0,
@@ -1323,15 +1415,15 @@ function G(e) {
1323
1415
  isPaused: !e.isEnded,
1324
1416
  isBuffering: !1,
1325
1417
  controlsVisible: !0
1326
- })), e.ended || B(L, e);
1418
+ })), D.setPlaybackState("paused"), D.syncPosition(e.duration, e.currentTime, e.playbackRate, !0), e.ended || V(L, e);
1327
1419
  }),
1328
1420
  e.on("ended", () => {
1329
- v = 0, y = NaN;
1421
+ _ = 0, y = NaN;
1330
1422
  for (let e = P.length - 1; e >= 0; e--) {
1331
1423
  let t = P[e];
1332
1424
  t?.kind === "save" && t.target.generation === L.generation && P.splice(e, 1);
1333
1425
  }
1334
- z(L), r.setState((e) => ({
1426
+ B(L), D.setPlaybackState("paused"), D.syncPosition(e.duration, e.currentTime, e.playbackRate, !0), r.setState((e) => ({
1335
1427
  ...e,
1336
1428
  status: "ended",
1337
1429
  isPlaying: !1,
@@ -1346,10 +1438,10 @@ function G(e) {
1346
1438
  r.setState((t) => ({
1347
1439
  ...t,
1348
1440
  currentTime: e.currentTime
1349
- })), i.onTimeUpdate?.(e.currentTime), oe(e);
1441
+ })), i.onTimeUpdate?.(e.currentTime), D.syncPosition(e.duration, e.currentTime, e.playbackRate), ie(e);
1350
1442
  }),
1351
1443
  e.on("loadedmetadata", () => {
1352
- b !== null && (clearTimeout(b), b = null), C = 0, r.setState((t) => ({
1444
+ S !== null && (clearTimeout(S), S = null), C = 0, r.setState((t) => ({
1353
1445
  ...t,
1354
1446
  status: t.status === "idle" || t.status === "loading" || t.status === "error" ? "ready" : t.status,
1355
1447
  duration: f(e.duration) ? e.duration : 0,
@@ -1358,7 +1450,7 @@ function G(e) {
1358
1450
  isMuted: e.muted,
1359
1451
  playbackRate: e.playbackRate,
1360
1452
  error: null
1361
- })), H(e);
1453
+ })), U(e);
1362
1454
  }),
1363
1455
  e.on("progress", () => {
1364
1456
  let t = e.buffered;
@@ -1377,7 +1469,7 @@ function G(e) {
1377
1469
  }));
1378
1470
  }),
1379
1471
  e.on("canplay", () => {
1380
- b !== null && (clearTimeout(b), b = null), C = 0, r.setState((e) => ({
1472
+ S !== null && (clearTimeout(S), S = null), C = 0, r.setState((e) => ({
1381
1473
  ...e,
1382
1474
  status: e.isPlaying ? "playing" : "ready",
1383
1475
  isBuffering: !1,
@@ -1389,7 +1481,7 @@ function G(e) {
1389
1481
  ...t,
1390
1482
  duration: f(e.duration) ? e.duration : 0,
1391
1483
  isLive: !f(e.duration)
1392
- })), H(e);
1484
+ })), U(e);
1393
1485
  }),
1394
1486
  e.on("seeking", () => {
1395
1487
  r.setState((e) => ({
@@ -1401,16 +1493,15 @@ function G(e) {
1401
1493
  r.setState((e) => ({
1402
1494
  ...e,
1403
1495
  status: e.isPlaying ? "playing" : "ready"
1404
- })), B(L, e);
1496
+ })), D.syncPosition(e.duration, e.currentTime, e.playbackRate, !0), V(L, e);
1405
1497
  }),
1406
1498
  e.on("playing", () => {
1407
- M = !0, r.setState((e) => ({
1499
+ r.setState((e) => ({
1408
1500
  ...e,
1409
1501
  status: "playing",
1410
1502
  isPlaying: !0,
1411
1503
  isPaused: !1,
1412
- isBuffering: !1,
1413
- resumeState: { status: "idle" }
1504
+ isBuffering: !1
1414
1505
  }));
1415
1506
  }),
1416
1507
  e.on("volumechange", () => {
@@ -1455,16 +1546,27 @@ function G(e) {
1455
1546
  reconnectAttempt: C,
1456
1547
  isReconnecting: !0
1457
1548
  }
1458
- })), o.emit("video:reconnecting", { attempt: C + 1 }), b !== null && clearTimeout(b), b = setTimeout(() => {
1459
- b = null, C++, o.emit("video:reconnect", { attempt: C }), e.load();
1460
- }, ee));
1549
+ })), o.emit("video:reconnecting", { attempt: C + 1 }), S !== null && clearTimeout(S), S = setTimeout(() => {
1550
+ S = null, C++, o.emit("video:reconnect", { attempt: C }), e.load();
1551
+ }, p));
1461
1552
  })
1462
1553
  ];
1463
1554
  }
1464
- let Y = null;
1465
- function xe() {
1555
+ let Q = null;
1556
+ function ve() {
1557
+ let e = s.get(x.CAPTION_SETTINGS);
1558
+ e && r.setState((t) => ({
1559
+ ...t,
1560
+ captionSettings: {
1561
+ ...k,
1562
+ ...e,
1563
+ backgroundOpacity: Math.max(0, Math.min(1, e.backgroundOpacity))
1564
+ }
1565
+ }));
1566
+ }
1567
+ function ye() {
1466
1568
  if (!i.persistPreferences) return;
1467
- let e = s.get(m.VOLUME), t = s.get(m.MUTED), n = s.get(m.PLAYBACK_RATE), a = s.get(m.LOOP), o = s.get(m.FLIP), c = s.get(m.ASPECT_RATIO), l = s.get(m.CAPTION_SETTINGS);
1569
+ let e = s.get(x.VOLUME), t = s.get(x.MUTED), n = s.get(x.PLAYBACK_RATE), a = s.get(x.LOOP), o = s.get(x.FLIP), c = s.get(x.ASPECT_RATIO);
1468
1570
  r.setState((r) => ({
1469
1571
  ...r,
1470
1572
  volume: e ?? r.volume,
@@ -1472,21 +1574,19 @@ function G(e) {
1472
1574
  playbackRate: n ?? r.playbackRate,
1473
1575
  isLooping: a ?? r.isLooping,
1474
1576
  flip: o ?? r.flip,
1475
- aspectRatio: fe(c),
1476
- captionSettings: l ? {
1477
- ...S,
1478
- ...l,
1479
- backgroundOpacity: Math.max(0, Math.min(1, l.backgroundOpacity))
1480
- } : r.captionSettings
1481
- })), Y = r.subscribe(() => {
1577
+ aspectRatio: me(c)
1578
+ })), ve(), Q = r.subscribe(() => {
1482
1579
  let e = r.state;
1483
- e.volume !== 1 && s.set(m.VOLUME, e.volume), e.isMuted && s.set(m.MUTED, !0), e.playbackRate !== 1 && s.set(m.PLAYBACK_RATE, e.playbackRate), e.isLooping ? s.set(m.LOOP, !0) : s.remove(m.LOOP), e.flip === "normal" ? s.remove(m.FLIP) : s.set(m.FLIP, e.flip), e.aspectRatio === "default" ? s.remove(m.ASPECT_RATIO) : s.set(m.ASPECT_RATIO, e.aspectRatio), s.set(m.CAPTION_SETTINGS, e.captionSettings);
1580
+ e.volume !== 1 && s.set(x.VOLUME, e.volume), e.isMuted && s.set(x.MUTED, !0), e.playbackRate !== 1 && s.set(x.PLAYBACK_RATE, e.playbackRate), e.isLooping ? s.set(x.LOOP, !0) : s.remove(x.LOOP), e.flip === "normal" ? s.remove(x.FLIP) : s.set(x.FLIP, e.flip), e.aspectRatio === "default" ? s.remove(x.ASPECT_RATIO) : s.set(x.ASPECT_RATIO, e.aspectRatio), s.set(x.CAPTION_SETTINGS, e.captionSettings);
1484
1581
  });
1485
1582
  }
1486
- function Se() {
1487
- Y &&= (Y.unsubscribe(), null);
1583
+ function be() {
1584
+ if (Q) {
1585
+ let e = Q;
1586
+ typeof e == "function" ? e() : e.unsubscribe(), Q = null;
1587
+ }
1488
1588
  }
1489
- function X(e) {
1589
+ function $(e) {
1490
1590
  if (w?.abort(), w = null, !e) {
1491
1591
  r.setState((e) => ({
1492
1592
  ...e,
@@ -1507,21 +1607,21 @@ function G(e) {
1507
1607
  })));
1508
1608
  });
1509
1609
  }
1510
- function Ce(e) {
1610
+ function xe(e) {
1511
1611
  return {
1512
1612
  name: e,
1513
1613
  store: r,
1514
- remote: J,
1614
+ remote: Z,
1515
1615
  events: o,
1516
1616
  storage: s,
1517
1617
  hotkeys: l,
1518
1618
  i18n: c,
1519
1619
  context: {
1520
1620
  containerRef: { get current() {
1521
- return h;
1621
+ return m;
1522
1622
  } },
1523
1623
  videoRef: { get current() {
1524
- return g?.element;
1624
+ return h?.element;
1525
1625
  } }
1526
1626
  },
1527
1627
  addControl: (e) => (r.setState((t) => ({
@@ -1590,15 +1690,15 @@ function G(e) {
1590
1690
  }
1591
1691
  };
1592
1692
  }
1593
- let Z = [];
1594
- function we(e = !0) {
1595
- b !== null && (clearTimeout(b), b = null), C = 0;
1596
- for (let e of Z) e();
1597
- Z = [], g && (e && B(L, g), g.destroy(), g = null, $.engine = null);
1693
+ let Se = [];
1694
+ function Ce(e = !0) {
1695
+ S !== null && (clearTimeout(S), S = null), C = 0;
1696
+ for (let e of Se) e();
1697
+ Se = [], h && (e && V(L, h), h.pause(), h.destroy(), h = null, Ee.engine = null);
1598
1698
  }
1599
- function Q(e) {
1600
- let t = x(i), n = ne(e, i);
1601
- g = n, $.engine = n, Z = be(n), e.playsInline = !0, e.autoplay = !!i.autoPlay, e.preload = e.preload || "metadata", r.setState((n) => ({
1699
+ function we(e) {
1700
+ let t = O(i), n = te(e, i);
1701
+ h = n, Ee.engine = n, Se = _e(n), e.playsInline = !0, e.autoplay = !!i.autoPlay, e.preload = e.preload || "metadata", D.setPlaybackState("paused"), r.setState((n) => ({
1602
1702
  ...n,
1603
1703
  status: "loading",
1604
1704
  source: t,
@@ -1609,20 +1709,20 @@ function G(e) {
1609
1709
  currentTime: 0,
1610
1710
  duration: 0,
1611
1711
  bufferedPercent: 0,
1612
- capabilities: d(e, h),
1712
+ capabilities: d(e, m),
1613
1713
  error: null
1614
1714
  })), i.autoPlay && n.play();
1615
1715
  }
1616
1716
  function Te(e = !0) {
1617
- let t = g?.element;
1717
+ let t = h?.element;
1618
1718
  if (t) {
1619
- for (we(e), t.pause(), t.removeAttribute("src"); t.firstChild;) t.removeChild(t.firstChild);
1620
- t.load(), Q(t);
1719
+ for (Ce(e), t.pause(), t.removeAttribute("src"); t.firstChild;) t.removeChild(t.firstChild);
1720
+ t.load(), we(t);
1621
1721
  }
1622
1722
  }
1623
- let $ = {
1723
+ let Ee = {
1624
1724
  store: r,
1625
- remote: J,
1725
+ remote: Z,
1626
1726
  events: o,
1627
1727
  storage: s,
1628
1728
  i18n: c,
@@ -1633,29 +1733,29 @@ function G(e) {
1633
1733
  ...i,
1634
1734
  ...e
1635
1735
  }, l = I(c), u = l.id !== L.id || l.store !== L.store;
1636
- if ((t || u) && B(L, g), i = c, (t || u) && V(), (r.state.isPlaying || D) && _e(), r.setState((t) => {
1736
+ if ((t || u) && V(L, h), i = c, (t || u) && H(), (r.state.isPlaying || D.hasMetadata) && D.syncMetadata(i.title, q()), r.setState((t) => {
1637
1737
  let n = e.qualities ?? t.qualities;
1638
1738
  return {
1639
1739
  ...t,
1640
1740
  qualities: n,
1641
1741
  activeQuality: e.qualities ? e.qualities.includes(t.activeQuality) ? t.activeQuality : e.qualities[0] ?? "Auto" : t.activeQuality
1642
1742
  };
1643
- }), e.subtitles && (G(e.subtitles), !r.state.activeSubtitle)) {
1743
+ }), e.subtitles && (W(e.subtitles), !r.state.activeSubtitle)) {
1644
1744
  let t = e.subtitles.find((e) => e.default) ?? null;
1645
- t && J.setActiveSubtitle(W(t));
1745
+ t && Z.setActiveSubtitle(Y(t));
1646
1746
  }
1647
- s && (E?.abort(), E = null, q()), (a || o) && X(i.thumbnails), t || n ? Te(!(t || u)) : u && g && f(g.duration) && H(g);
1747
+ s && (E?.abort(), E = null, K()), (a || o) && $(i.thumbnails), t || n ? Te(!(t || u)) : u && h && f(h.duration) && U(h);
1648
1748
  },
1649
1749
  setThumbnails(e) {
1650
1750
  i = {
1651
1751
  ...i,
1652
1752
  thumbnails: e
1653
- }, X(e);
1753
+ }, $(e);
1654
1754
  },
1655
1755
  initPlugins(e) {
1656
1756
  let t = [];
1657
1757
  for (let n of e) {
1658
- let e = Ce(n.name);
1758
+ let e = xe(n.name);
1659
1759
  try {
1660
1760
  let r = n.setup?.(e);
1661
1761
  typeof r == "function" && t.push(r);
@@ -1672,12 +1772,12 @@ function G(e) {
1672
1772
  };
1673
1773
  },
1674
1774
  mount(e, t) {
1675
- g && this.unmount(), h = t, Q(e), _ = ye, document.addEventListener("fullscreenchange", _), document.addEventListener("webkitfullscreenchange", _), N = () => B(), window.addEventListener("pagehide", N), X(i.thumbnails);
1775
+ h && this.unmount(), m = t, we(e), g = X, document.addEventListener("fullscreenchange", g), document.addEventListener("webkitfullscreenchange", g), N = () => V(), window.addEventListener("pagehide", N), D.setup(Z), $(i.thumbnails);
1676
1776
  let n = r.state.subtitleTracks.find((e) => e.default);
1677
- n && J.setActiveSubtitle(n), xe(), J.setAspectRatio(r.state.aspectRatio);
1777
+ n && Z.setActiveSubtitle(n), ve(), ye(), Z.setAspectRatio(r.state.aspectRatio);
1678
1778
  },
1679
1779
  unmount() {
1680
- we(), V(), ge(), h = null, w?.abort(), w = null, T?.abort(), T = null, E?.abort(), E = null, Se(), b !== null && (clearTimeout(b), b = null), _ &&= (document.removeEventListener("fullscreenchange", _), document.removeEventListener("webkitfullscreenchange", _), null), N &&= (window.removeEventListener("pagehide", N), null), r.setState((e) => ({
1780
+ Ce(), H(), D.teardown(), m = null, w?.abort(), w = null, T?.abort(), T = null, E?.abort(), E = null, be(), S !== null && (clearTimeout(S), S = null), g &&= (document.removeEventListener("fullscreenchange", g), document.removeEventListener("webkitfullscreenchange", g), null), N &&= (window.removeEventListener("pagehide", N), null), r.setState((e) => ({
1681
1781
  ...e,
1682
1782
  activeSubtitle: null,
1683
1783
  subtitleTracks: e.subtitleTracks.filter((e) => !e.local),
@@ -1695,11 +1795,11 @@ function G(e) {
1695
1795
  this.unmount(), o.clear();
1696
1796
  }
1697
1797
  };
1698
- return $;
1798
+ return Ee;
1699
1799
  }
1700
1800
  //#endregion
1701
1801
  //#region src/gesture-engine.ts
1702
- function K(e, t) {
1802
+ function X(e, t) {
1703
1803
  let n = null, r = null, i = null, a = typeof window < "u" && "ontouchstart" in window;
1704
1804
  function o(t) {
1705
1805
  if (!a || t.touches.length !== 1) return;
@@ -1759,14 +1859,14 @@ function K(e, t) {
1759
1859
  }
1760
1860
  //#endregion
1761
1861
  //#region src/utils.ts
1762
- function q(e) {
1862
+ function Z(e) {
1763
1863
  if (!Number.isFinite(e) || e < 0) return "0:00";
1764
1864
  let t = Math.floor(e / 3600), n = Math.floor(e % 3600 / 60), r = Math.floor(e % 60);
1765
1865
  return t > 0 ? `${t}:${String(n).padStart(2, "0")}:${String(r).padStart(2, "0")}` : `${n}:${String(r).padStart(2, "0")}`;
1766
1866
  }
1767
1867
  //#endregion
1768
1868
  //#region src/defaults.ts
1769
- var me = {
1869
+ var _e = {
1770
1870
  play: "Play",
1771
1871
  pause: "Pause",
1772
1872
  replay: "Replay",
@@ -1802,6 +1902,8 @@ var me = {
1802
1902
  captionMedium: "Default",
1803
1903
  captionLarge: "Large",
1804
1904
  captionReset: "Reset",
1905
+ captionSave: "Save",
1906
+ captionSaved: "Saved",
1805
1907
  captionFontFamily: "Font",
1806
1908
  captionFontScale: "Scale",
1807
1909
  captionTextOpacity: "Text opacity",
@@ -1831,6 +1933,7 @@ var me = {
1831
1933
  continue: "Continue",
1832
1934
  continuePlay: "Continue playing at",
1833
1935
  continueStartOver: "Start over",
1936
+ dismiss: "Dismiss",
1834
1937
  error: "An error occurred",
1835
1938
  retry: "Retry",
1836
1939
  contextMenuPlay: "Play",
@@ -1840,4 +1943,4 @@ var me = {
1840
1943
  loop: "Loop"
1841
1944
  };
1842
1945
  //#endregion
1843
- export { h as BaseMediaEngine, v as DashMediaEngine, t as EventBus, _ as HlsMediaEngine, n as HotkeyRegistry, a as I18n, te as LocalPlaybackProgressStore, g as NativeVideoEngine, m as STORAGE_KEYS, p as Storage, c as canUseFullscreen, o as canUseMSE, s as canUseNativeHLS, l as canUsePictureInPicture, u as canUseTextTracks, K as createGestureEngine, ie as createMediaStore, G as createPlayer, ne as createResolvedMediaEngine, me as defaultPlayerLabels, b as detectSourceKind, j as fetchSubtitles, re as fetchThumbnails, q as formatTime, M as getActiveCue, L as getInitialMediaState, d as getMediaCapabilities, I as getThumbnailAtTime, f as isFiniteDuration, O as parseSRT, A as parseSubtitles, P as parseThumbnailVTT, E as parseTimestamp, k as parseVTT, ae as selectAudio, H as selectError, R as selectMedia, oe as selectPlugins, z as selectPreferences, V as selectThumbnails, B as selectUI, x as toPlayerSource };
1946
+ export { S as BaseMediaEngine, T as DashMediaEngine, t as EventBus, w as HlsMediaEngine, n as HotkeyRegistry, a as I18n, ee as LocalPlaybackProgressStore, C as NativeVideoEngine, x as STORAGE_KEYS, b as Storage, c as canUseFullscreen, o as canUseMSE, s as canUseNativeHLS, l as canUsePictureInPicture, u as canUseTextTracks, X as createGestureEngine, v as createMediaSessionController, ae as createMediaStore, ge as createPlayer, te as createResolvedMediaEngine, _e as defaultPlayerLabels, D as detectSourceKind, R as fetchSubtitles, re as fetchThumbnails, Z as formatTime, z as getActiveCue, H as getInitialMediaState, d as getMediaCapabilities, ie as getThumbnailAtTime, f as isFiniteDuration, F as parseSRT, L as parseSubtitles, B as parseThumbnailVTT, N as parseTimestamp, I as parseVTT, W as selectAudio, q as selectError, U as selectMedia, oe as selectPlugins, G as selectPreferences, se as selectThumbnails, K as selectUI, O as toPlayerSource };