three-vr-player 0.9.0 → 0.10.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.
@@ -1,5 +1,5 @@
1
1
  import * as a from "three";
2
- function D(h) {
2
+ function Q(h) {
3
3
  let e = h;
4
4
  try {
5
5
  e = new URL(h).pathname;
@@ -8,21 +8,21 @@ function D(h) {
8
8
  const t = e.toLowerCase();
9
9
  return t.endsWith(".m3u8") ? "hls" : t.endsWith(".mpd") ? "dash" : "progressive";
10
10
  }
11
- const G = {
11
+ const D = {
12
12
  progressive: "/proxy/stream",
13
13
  hls: "/proxy/hls/manifest.m3u8",
14
14
  dash: "/proxy/mpd/manifest.m3u8"
15
15
  };
16
- function q(h, e) {
17
- const t = D(h);
16
+ function Y(h, e) {
17
+ const t = Q(h);
18
18
  if (!e || !e.url) return { url: h, format: t };
19
19
  const i = e.url.replace(/\/+$/, ""), s = new URLSearchParams();
20
20
  s.set("d", h), e.apiPassword && s.set("api_password", e.apiPassword);
21
21
  for (const [r, n] of Object.entries(e.headers ?? {}))
22
22
  n != null && n !== "" && s.set(`h_${r}`, n);
23
- return { url: `${i}${G[t]}?${s.toString()}`, format: t };
23
+ return { url: `${i}${D[t]}?${s.toString()}`, format: t };
24
24
  }
25
- const b = {
25
+ const S = {
26
26
  "180-sbs": { geom: "sphere180", split: "sbs", stereo: !0 },
27
27
  "180-mono": { geom: "sphere180", split: "mono", stereo: !1 },
28
28
  "360-mono": { geom: "sphere360", split: "mono", stereo: !1 },
@@ -34,7 +34,7 @@ const b = {
34
34
  "flat-2d": { geom: "plane", split: "mono", stereo: !1, flat: !0, aspect: "full" },
35
35
  "flat-sbs-full": { geom: "plane", split: "sbs", stereo: !0, flat: !0, aspect: "per-eye" },
36
36
  "flat-sbs-half": { geom: "plane", split: "sbs", stereo: !0, flat: !0, aspect: "full" }
37
- }, X = [
37
+ }, G = [
38
38
  { value: "180-sbs", label: "180° SBS (VR180)" },
39
39
  { value: "180-mono", label: "180° Mono" },
40
40
  { value: "360-mono", label: "360° Mono" },
@@ -45,23 +45,34 @@ const b = {
45
45
  { value: "flat-2d", label: "Flat 2D" },
46
46
  { value: "flat-sbs-full", label: "Flat 3D — Full SBS" },
47
47
  { value: "flat-sbs-half", label: "Flat 3D — Half SBS" }
48
- ];
49
- function $(h) {
48
+ ], V = {
49
+ "180-sbs": "180° SBS",
50
+ "180-mono": "180° Mono",
51
+ "360-mono": "360° Mono",
52
+ "360-sbs": "360° SBS",
53
+ "360-tb": "360° TB",
54
+ "fisheye190-sbs": "Fisheye SBS",
55
+ "fisheye190-mono": "Fisheye Mono",
56
+ "flat-2d": "Flat 2D",
57
+ "flat-sbs-full": "Flat SBS",
58
+ "flat-sbs-half": "Flat SBS½"
59
+ };
60
+ function Z(h) {
50
61
  var e;
51
- return !!((e = b[h]) != null && e.flat);
62
+ return !!((e = S[h]) != null && e.flat);
52
63
  }
53
- function Y(h) {
64
+ function J(h) {
54
65
  const e = String(h).toLowerCase(), t = /(^|[^a-z])(tb|ou|top.?bottom|over.?under)([^a-z]|$)/.test(e), i = /(sbs|side.?by.?side)/.test(e);
55
66
  return /(fisheye|mkx200|rf52|vrca220)/.test(e) ? e.includes("mono") ? "fisheye190-mono" : "fisheye190-sbs" : e.includes("360") ? t ? "360-tb" : i ? "360-sbs" : "360-mono" : e.includes("180") || e.includes("vr180") ? e.includes("mono") ? "180-mono" : "180-sbs" : i ? e.includes("half") ? "flat-sbs-half" : "flat-sbs-full" : null;
56
67
  }
57
- function F(h) {
68
+ function k(h) {
58
69
  if (!Number.isFinite(h) || h < 0) return "0:00";
59
70
  const e = Math.floor(h % 60), t = Math.floor(h / 60 % 60), i = Math.floor(h / 3600), s = String(e).padStart(2, "0");
60
71
  return i > 0 ? `${i}:${String(t).padStart(2, "0")}:${s}` : `${t}:${s}`;
61
72
  }
62
- const S = 1024, y = 340;
63
- function Q() {
64
- const h = S, e = y, t = 48;
73
+ const y = 1024, w = 340;
74
+ function O() {
75
+ const h = y, e = w, t = 48;
65
76
  return {
66
77
  width: h,
67
78
  height: e,
@@ -74,24 +85,28 @@ function Q() {
74
85
  play: { x: h / 2 - 44, y: 150, w: 88, h: 88 },
75
86
  volIcon: { x: t, y: 178, w: 44, h: 44 },
76
87
  volBar: { x: t + 60, y: 192, w: 200, h: 16 },
88
+ // Projection stepper on the right: ◀ [label] ▶
89
+ projPrev: { x: 592, y: 178, w: 46, h: 46 },
90
+ projNext: { x: h - 94, y: 178, w: 46, h: 46 },
91
+ projLabel: { x: 646, y: 178, w: h - 94 - 646, h: 46 },
77
92
  seekBar: { x: t, y: 286, w: h - t * 2, h: 14 },
78
93
  timeCur: { x: t, y: 262 },
79
94
  timeDur: { x: h - t, y: 262 }
80
95
  };
81
96
  }
82
97
  const C = (h) => h < 0 ? 0 : h > 1 ? 1 : h;
83
- function w(h, e, t, i = 0, s = 0) {
98
+ function x(h, e, t, i = 0, s = 0) {
84
99
  return e >= h.x - i && e <= h.x + h.w + i && t >= h.y - s && t <= h.y + h.h + s;
85
100
  }
86
- function V(h, e, t = Q()) {
87
- return w(t.recenter, h, e) ? { region: "recenter" } : w(t.passthrough, h, e) ? { region: "passthrough" } : w(t.exit, h, e) ? { region: "exit" } : w(t.play, h, e) ? { region: "play" } : w(t.volIcon, h, e) ? { region: "volume" } : w(t.volBar, h, e, 12, 26) ? { region: "volume", value: C((h - t.volBar.x) / t.volBar.w) } : w(t.seekBar, h, e, 12, 26) ? { region: "seek", value: C((h - t.seekBar.x) / t.seekBar.w) } : null;
101
+ function W(h, e, t = O()) {
102
+ return x(t.recenter, h, e) ? { region: "recenter" } : x(t.passthrough, h, e) ? { region: "passthrough" } : x(t.exit, h, e) ? { region: "exit" } : x(t.projPrev, h, e) ? { region: "projPrev" } : x(t.projNext, h, e) ? { region: "projNext" } : x(t.play, h, e) ? { region: "play" } : x(t.volIcon, h, e) ? { region: "volume" } : x(t.volBar, h, e, 12, 26) ? { region: "volume", value: C((h - t.volBar.x) / t.volBar.w) } : x(t.seekBar, h, e, 12, 26) ? { region: "seek", value: C((h - t.seekBar.x) / t.seekBar.w) } : null;
88
103
  }
89
- const T = "#4f8cff", M = "#e8eaed", I = "#aab2c0", W = [4, 5], E = 8e3, U = 0.05, j = 0.02, B = 1500, R = 0.15, _ = 0.012, N = 0.08;
90
- class z {
104
+ const R = "#4f8cff", P = "#e8eaed", L = "#aab2c0", U = [4, 5], A = 8e3, N = 0.05, _ = 0.02, I = 1500, T = 0.15, q = 0.012, z = 0.012, H = 0.08;
105
+ class X {
91
106
  // re-lock the panel to the head pose for a few frames after summon
92
107
  constructor(e) {
93
- this.layout = Q(), this.raycaster = new a.Raycaster(), this.tmpMatrix = new a.Matrix4(), this.tmpVec = new a.Vector3(), this.tmpQuat = new a.Quaternion(), this.prevQuat = [], this.prevPos = [], this.revealCooldownUntil = 0, this.grabbing = null, this.grabStartQuat = new a.Quaternion(), this.prevGrabQuat = new a.Quaternion(), this.grabQuat = new a.Quaternion(), this.deltaQuat = new a.Quaternion(), this.grabEuler = new a.Euler(0, 0, 0, "YXZ"), this.controllers = [], this.lasers = [], this.connected = [], this.cleanups = [], this.visible = !1, this.hover = null, this.paintKey = "", this.idleAt = 0, this.togglePrev = !1, this.placeFrames = 0, this.renderer = e.renderer, this.scene = e.scene, this.actions = e.actions, this.canvas = document.createElement("canvas"), this.canvas.width = S, this.canvas.height = y, this.ctx = this.canvas.getContext("2d"), this.texture = new a.CanvasTexture(this.canvas), this.texture.colorSpace = a.SRGBColorSpace, this.texture.minFilter = a.LinearFilter;
94
- const t = 1, i = t * y / S;
108
+ this.layout = O(), this.raycaster = new a.Raycaster(), this.tmpMatrix = new a.Matrix4(), this.tmpVec = new a.Vector3(), this.tmpQuat = new a.Quaternion(), this.prevQuat = [], this.prevPos = [], this.revealCooldownUntil = 0, this.grabbing = null, this.grabStartQuat = new a.Quaternion(), this.prevGrabQuat = new a.Quaternion(), this.grabQuat = new a.Quaternion(), this.deltaQuat = new a.Quaternion(), this.grabEuler = new a.Euler(0, 0, 0, "YXZ"), this.controllers = [], this.lasers = [], this.connected = [], this.cleanups = [], this.visible = !1, this.hover = null, this.paintKey = "", this.idleAt = 0, this.togglePrev = !1, this.placeFrames = 0, this.renderer = e.renderer, this.scene = e.scene, this.actions = e.actions, this.canvas = document.createElement("canvas"), this.canvas.width = y, this.canvas.height = w, this.ctx = this.canvas.getContext("2d"), this.texture = new a.CanvasTexture(this.canvas), this.texture.colorSpace = a.SRGBColorSpace, this.texture.minFilter = a.LinearFilter;
109
+ const t = 1, i = t * w / y;
95
110
  this.panel = new a.Mesh(
96
111
  new a.PlaneGeometry(t, i),
97
112
  new a.MeshBasicMaterial({ map: this.texture, transparent: !0, depthTest: !1, side: a.DoubleSide })
@@ -103,13 +118,13 @@ class z {
103
118
  for (let n = 0; n < 2; n++) {
104
119
  const l = this.renderer.xr.getController(n), o = this.makeLaser();
105
120
  o.visible = !1, l.add(o), this.scene.add(l), this.controllers.push(l), this.lasers.push(o), this.connected.push(n < r);
106
- const c = () => this.onSelect(n), p = () => this.onGrabStart(n), d = () => this.onGrabEnd(n), m = (f) => {
107
- this.connected[n] = !(f != null && f.data) || f.data.targetRayMode === "tracked-pointer";
121
+ const c = () => this.onSelect(n), f = () => this.onGrabStart(n), u = () => this.onGrabEnd(n), g = (d) => {
122
+ this.connected[n] = !(d != null && d.data) || d.data.targetRayMode === "tracked-pointer";
108
123
  }, v = () => {
109
124
  this.connected[n] = !1;
110
- }, u = l;
111
- u.addEventListener("selectstart", c), u.addEventListener("squeezestart", p), u.addEventListener("squeezeend", d), u.addEventListener("connected", m), u.addEventListener("disconnected", v), this.cleanups.push(() => {
112
- u.removeEventListener("selectstart", c), u.removeEventListener("squeezestart", p), u.removeEventListener("squeezeend", d), u.removeEventListener("connected", m), u.removeEventListener("disconnected", v);
125
+ }, p = l;
126
+ p.addEventListener("selectstart", c), p.addEventListener("squeezestart", f), p.addEventListener("squeezeend", u), p.addEventListener("connected", g), p.addEventListener("disconnected", v), this.cleanups.push(() => {
127
+ p.removeEventListener("selectstart", c), p.removeEventListener("squeezestart", f), p.removeEventListener("squeezeend", u), p.removeEventListener("connected", g), p.removeEventListener("disconnected", v);
113
128
  });
114
129
  }
115
130
  this.paint(!0);
@@ -140,7 +155,7 @@ class z {
140
155
  const o = this.rayHit(n);
141
156
  o.point ? (r.visible = !0, r.scale.z = o.distance, i = o.point, o.hit && (t = o.hit.region)) : r.visible = !1;
142
157
  }
143
- i ? (this.cursor.position.copy(i), this.cursor.visible = !0) : this.cursor.visible = !1, t && (this.idleAt = e + E), this.hover = t, this.paint(!1);
158
+ i ? (this.cursor.position.copy(i), this.cursor.visible = !0) : this.cursor.visible = !1, t && (this.idleAt = e + A), this.hover = t, this.paint(!1);
144
159
  }
145
160
  /** Ray from a controller against the panel: the region under it (if any) and
146
161
  * how far the laser reaches. */
@@ -149,13 +164,13 @@ class z {
149
164
  const t = this.raycaster.intersectObject(this.panel, !1);
150
165
  if (!t.length) return { hit: null, distance: 5, point: null };
151
166
  const i = t[0];
152
- return { hit: i.uv ? V(i.uv.x * S, (1 - i.uv.y) * y, this.layout) : null, distance: i.distance, point: i.point };
167
+ return { hit: i.uv ? W(i.uv.x * y, (1 - i.uv.y) * w, this.layout) : null, distance: i.distance, point: i.point };
153
168
  }
154
169
  onSelect(e) {
155
170
  if (!this.visible || !this.connected[e]) return;
156
171
  const { hit: t } = this.rayHit(this.controllers[e]);
157
172
  if (t) {
158
- switch (this.idleAt = P() + E, t.region) {
173
+ switch (this.idleAt = E() + A, t.region) {
159
174
  case "play":
160
175
  this.actions.togglePlay();
161
176
  break;
@@ -165,6 +180,12 @@ class z {
165
180
  case "passthrough":
166
181
  this.actions.passthroughAvailable() && this.actions.togglePassthrough();
167
182
  break;
183
+ case "projPrev":
184
+ this.actions.cycleProjection(-1);
185
+ break;
186
+ case "projNext":
187
+ this.actions.cycleProjection(1);
188
+ break;
168
189
  case "recenter":
169
190
  this.actions.recenter(), this.placeFrames = 12;
170
191
  break;
@@ -186,26 +207,28 @@ class z {
186
207
  const i = this.controllers[t], s = this.tmpVec.setFromMatrixPosition(i.matrixWorld);
187
208
  if (!this.connected[t] || s.lengthSq() <= 1e-6) continue;
188
209
  const r = this.tmpQuat.setFromRotationMatrix(i.matrixWorld), n = this.prevQuat[t], l = this.prevPos[t];
189
- n && l && !this.visible && e > this.revealCooldownUntil && (r.angleTo(n) > U || s.distanceTo(l) > j) && this.show(), this.prevQuat[t] || (this.prevQuat[t] = new a.Quaternion()), this.prevPos[t] || (this.prevPos[t] = new a.Vector3()), this.prevQuat[t].copy(r), this.prevPos[t].copy(s);
210
+ n && l && !this.visible && e > this.revealCooldownUntil && (r.angleTo(n) > N || s.distanceTo(l) > _) && this.show(), this.prevQuat[t] || (this.prevQuat[t] = new a.Quaternion()), this.prevPos[t] || (this.prevPos[t] = new a.Vector3()), this.prevQuat[t].copy(r), this.prevPos[t].copy(s);
190
211
  }
191
212
  }
192
- /** Right thumbstick X zooms the content fov every frame it's held (push right =
193
- * zoom in). Pitch/yaw are handled by the grip grab-rotate, not the stick. */
213
+ /** Right thumbstick, applied every frame it's held: X zooms the content fov (push right =
214
+ * zoom in), Y tilts the content pitch (push up = tilt up). The grip grab-rotate also does
215
+ * pitch/yaw; the two coexist. */
194
216
  handleThumbstick() {
195
217
  const e = this.renderer.xr.getSession();
196
- if (e)
197
- for (const t of e.inputSources) {
198
- if (t.handedness !== "right" || !t.gamepad) continue;
199
- const i = t.gamepad.axes, s = i.length >= 4 ? i[2] ?? 0 : i[0] ?? 0, r = Math.abs(s);
200
- r > R && this.actions.adjustZoom(Math.sign(s) * (r - R) / (1 - R) * _);
201
- break;
202
- }
218
+ if (!e) return;
219
+ const t = (i) => Math.sign(i) * (Math.abs(i) - T) / (1 - T);
220
+ for (const i of e.inputSources) {
221
+ if (i.handedness !== "right" || !i.gamepad) continue;
222
+ const s = i.gamepad.axes, r = s.length >= 4 ? s[2] ?? 0 : s[0] ?? 0, n = s.length >= 4 ? s[3] ?? 0 : s[1] ?? 0;
223
+ Math.abs(r) > T && this.actions.adjustZoom(t(r) * q), Math.abs(n) > T && this.actions.adjustTilt(-t(n) * z);
224
+ break;
225
+ }
203
226
  }
204
227
  onGrabStart(e) {
205
228
  this.connected[e] && (this.grabbing = e, this.controllers[e].getWorldQuaternion(this.grabStartQuat), this.prevGrabQuat.copy(this.grabStartQuat));
206
229
  }
207
230
  onGrabEnd(e) {
208
- this.grabbing === e && (this.grabbing = null, this.revealCooldownUntil = P() + B, this.controllers[e].getWorldQuaternion(this.grabQuat).angleTo(this.grabStartQuat) < N && this.toggle());
231
+ this.grabbing === e && (this.grabbing = null, this.revealCooldownUntil = E() + I, this.controllers[e].getWorldQuaternion(this.grabQuat).angleTo(this.grabStartQuat) < H && this.toggle());
209
232
  }
210
233
  /** While the grip is held, apply the controller's frame-to-frame rotation to the
211
234
  * content's yaw and pitch — a 1:1 grab-and-turn. Roll is ignored. */
@@ -223,7 +246,7 @@ class z {
223
246
  let t = !1;
224
247
  for (const i of (e == null ? void 0 : e.inputSources) ?? []) {
225
248
  const s = i.gamepad;
226
- s && W.some((r) => {
249
+ s && U.some((r) => {
227
250
  var n;
228
251
  return (n = s.buttons[r]) == null ? void 0 : n.pressed;
229
252
  }) && (t = !0);
@@ -234,12 +257,12 @@ class z {
234
257
  this.visible ? this.hide() : this.show();
235
258
  }
236
259
  show() {
237
- this.place(), this.placeFrames = 12, this.visible = !0, this.panel.visible = !0, this.idleAt = P() + E, this.paint(!0);
260
+ this.place(), this.placeFrames = 12, this.visible = !0, this.panel.visible = !0, this.idleAt = E() + A, this.paint(!0);
238
261
  }
239
262
  hide() {
240
263
  this.visible = !1, this.panel.visible = !1, this.cursor.visible = !1;
241
264
  for (const e of this.lasers) e.visible = !1;
242
- this.revealCooldownUntil = P() + B;
265
+ this.revealCooldownUntil = E() + I;
243
266
  }
244
267
  /** World-lock the panel in front of the current head pose (the "recenter"). Uses
245
268
  * yaw only (so head pitch/roll at summon doesn't skew it), drops it into the lower
@@ -262,33 +285,35 @@ class z {
262
285
  }
263
286
  /** Repaint the panel only when something visible changed (state or hover). */
264
287
  paint(e) {
265
- const t = this.actions.currentTime(), i = this.actions.duration(), s = this.actions.volume(), r = this.actions.muted(), n = this.actions.passthroughAvailable() && this.actions.passthroughEnabled(), l = [this.actions.isPlaying(), Math.floor(t), Math.floor(i), s.toFixed(2), r, this.hover, this.actions.title(), this.actions.passthroughAvailable(), n].join("|");
288
+ const t = this.actions.currentTime(), i = this.actions.duration(), s = this.actions.volume(), r = this.actions.muted(), n = this.actions.passthroughAvailable() && this.actions.passthroughEnabled(), l = [this.actions.isPlaying(), Math.floor(t), Math.floor(i), s.toFixed(2), r, this.hover, this.actions.title(), this.actions.passthroughAvailable(), n, this.actions.projectionLabel()].join("|");
266
289
  if (!e && l === this.paintKey) return;
267
290
  this.paintKey = l;
268
291
  const o = this.ctx, c = this.layout;
269
- o.clearRect(0, 0, S, y), this.roundRect(0, 0, S, y, 28), o.fillStyle = "rgba(22,24,30,0.84)", o.fill(), o.lineWidth = 2, o.strokeStyle = "rgba(255,255,255,0.08)", o.stroke();
270
- const p = this.actions.title();
271
- if (p) {
272
- o.font = '600 30px system-ui,"Segoe UI",Roboto,sans-serif', o.fillStyle = M, o.textAlign = "center", o.textBaseline = "middle";
273
- const u = 2 * c.exit.x - 48 - S;
274
- o.fillText(this.ellipsize(p, u), S / 2, c.title.y + c.title.h / 2);
292
+ o.clearRect(0, 0, y, w), this.roundRect(0, 0, y, w, 28), o.fillStyle = "rgba(22,24,30,0.84)", o.fill(), o.lineWidth = 2, o.strokeStyle = "rgba(255,255,255,0.08)", o.stroke();
293
+ const f = this.actions.title();
294
+ if (f) {
295
+ o.font = '600 30px system-ui,"Segoe UI",Roboto,sans-serif', o.fillStyle = P, o.textAlign = "center", o.textBaseline = "middle";
296
+ const d = 2 * c.exit.x - 48 - y;
297
+ o.fillText(this.ellipsize(f, d), y / 2, c.title.y + c.title.h / 2);
275
298
  }
276
- if (this.drawIconButton(c.recenter, this.hover === "recenter", !1, (u, f, g) => this.iconRecenter(u, f, g)), this.drawIconButton(c.exit, this.hover === "exit", !1, (u, f, g) => this.iconExit(u, f, g)), this.actions.passthroughAvailable()) {
277
- const u = this.actions.passthroughEnabled();
278
- this.drawIconButton(c.passthrough, u, this.hover === "passthrough", (f, g, x) => this.iconEye(f, g, !u, x));
299
+ if (this.drawIconButton(c.recenter, this.hover === "recenter", !1, (d, m, b) => this.iconRecenter(d, m, b)), this.drawIconButton(c.exit, this.hover === "exit", !1, (d, m, b) => this.iconExit(d, m, b)), this.actions.passthroughAvailable()) {
300
+ const d = this.actions.passthroughEnabled();
301
+ this.drawIconButton(c.passthrough, d, this.hover === "passthrough", (m, b, M) => this.iconEye(m, b, !d, M));
279
302
  }
280
- const d = { x: c.play.x + c.play.w / 2, y: c.play.y + c.play.h / 2 };
281
- o.beginPath(), o.arc(d.x, d.y, 44, 0, Math.PI * 2), o.fillStyle = this.hover === "play" ? T : "rgba(255,255,255,0.14)", o.fill(), o.fillStyle = "#fff", this.actions.isPlaying() ? (o.fillRect(d.x - 13, d.y - 16, 9, 32), o.fillRect(d.x + 4, d.y - 16, 9, 32)) : (o.beginPath(), o.moveTo(d.x - 12, d.y - 17), o.lineTo(d.x - 12, d.y + 17), o.lineTo(d.x + 18, d.y), o.closePath(), o.fill()), this.drawSpeaker(c.volIcon, r);
282
- const m = r ? 0 : Math.max(0, Math.min(1, s));
283
- this.drawBar(c.volBar, m, this.hover === "volume");
284
- const v = i > 0 ? Math.max(0, Math.min(1, t / i)) : 0;
285
- this.drawBar(c.seekBar, v, this.hover === "seek", !0), o.fillStyle = I, o.font = "22px system-ui,sans-serif", o.textBaseline = "alphabetic", o.textAlign = "left", o.fillText(F(t), c.timeCur.x, c.timeCur.y), o.textAlign = "right", o.fillText(i > 0 ? F(i) : "--:--", c.timeDur.x, c.timeDur.y), this.texture.needsUpdate = !0;
303
+ const u = { x: c.play.x + c.play.w / 2, y: c.play.y + c.play.h / 2 };
304
+ o.beginPath(), o.arc(u.x, u.y, 44, 0, Math.PI * 2), o.fillStyle = this.hover === "play" ? R : "rgba(255,255,255,0.14)", o.fill(), o.fillStyle = "#fff", this.actions.isPlaying() ? (o.fillRect(u.x - 13, u.y - 16, 9, 32), o.fillRect(u.x + 4, u.y - 16, 9, 32)) : (o.beginPath(), o.moveTo(u.x - 12, u.y - 17), o.lineTo(u.x - 12, u.y + 17), o.lineTo(u.x + 18, u.y), o.closePath(), o.fill()), this.drawSpeaker(c.volIcon, r);
305
+ const g = r ? 0 : Math.max(0, Math.min(1, s));
306
+ this.drawBar(c.volBar, g, this.hover === "volume");
307
+ const v = c.projLabel.x + c.projLabel.w / 2;
308
+ o.fillStyle = L, o.font = "600 15px system-ui,sans-serif", o.textAlign = "center", o.textBaseline = "alphabetic", o.fillText("PROJECTION", v, c.projPrev.y - 8), this.drawIconButton(c.projPrev, this.hover === "projPrev", !1, (d, m, b) => this.iconArrow(d, m, -1, b)), this.drawIconButton(c.projNext, this.hover === "projNext", !1, (d, m, b) => this.iconArrow(d, m, 1, b)), o.fillStyle = P, o.font = "600 26px system-ui,sans-serif", o.textAlign = "center", o.textBaseline = "middle", o.fillText(this.ellipsize(this.actions.projectionLabel(), c.projLabel.w - 12), v, c.projLabel.y + c.projLabel.h / 2);
309
+ const p = i > 0 ? Math.max(0, Math.min(1, t / i)) : 0;
310
+ this.drawBar(c.seekBar, p, this.hover === "seek", !0), o.fillStyle = L, o.font = "22px system-ui,sans-serif", o.textBaseline = "alphabetic", o.textAlign = "left", o.fillText(k(t), c.timeCur.x, c.timeCur.y), o.textAlign = "right", o.fillText(i > 0 ? k(i) : "--:--", c.timeDur.x, c.timeDur.y), this.texture.needsUpdate = !0;
286
311
  }
287
312
  /** A rounded-square icon button: accent fill when `filled`, white border when `hover`; the
288
313
  * icon is drawn centred in `filled ? white : TEXT`. */
289
314
  drawIconButton(e, t, i, s) {
290
315
  const r = this.ctx;
291
- this.roundRect(e.x, e.y, e.w, e.h, 14), r.fillStyle = t ? T : "rgba(255,255,255,0.12)", r.fill(), i && (r.lineWidth = 3, r.strokeStyle = "rgba(255,255,255,0.9)", r.stroke()), s(e.x + e.w / 2, e.y + e.h / 2, t ? "#fff" : M);
316
+ this.roundRect(e.x, e.y, e.w, e.h, 14), r.fillStyle = t ? R : "rgba(255,255,255,0.12)", r.fill(), i && (r.lineWidth = 3, r.strokeStyle = "rgba(255,255,255,0.9)", r.stroke()), s(e.x + e.w / 2, e.y + e.h / 2, t ? "#fff" : P);
292
317
  }
293
318
  /** Recenter — a reticle (ring + centre dot + crosshair ticks). */
294
319
  iconRecenter(e, t, i) {
@@ -300,6 +325,11 @@ class z {
300
325
  const r = this.ctx, n = 16, l = 10;
301
326
  r.strokeStyle = s, r.fillStyle = s, r.lineWidth = 2.5, r.lineCap = "round", r.beginPath(), r.moveTo(e - n, t), r.quadraticCurveTo(e, t - l * 1.7, e + n, t), r.quadraticCurveTo(e, t + l * 1.7, e - n, t), r.stroke(), r.beginPath(), r.arc(e, t, 4, 0, Math.PI * 2), r.fill(), i && (r.beginPath(), r.moveTo(e - n, t + l), r.lineTo(e + n, t - l), r.stroke());
302
327
  }
328
+ /** A solid triangle pointing left (dir −1) or right (dir +1) — the projection stepper arrows. */
329
+ iconArrow(e, t, i, s) {
330
+ const r = this.ctx, n = 8, l = 10;
331
+ r.fillStyle = s, r.beginPath(), r.moveTo(e + i * n, t), r.lineTo(e - i * n, t - l), r.lineTo(e - i * n, t + l), r.closePath(), r.fill();
332
+ }
303
333
  /** Exit — a door frame with an arrow pointing out to the right. */
304
334
  iconExit(e, t, i) {
305
335
  const s = this.ctx, r = e - 15, n = 11, l = 22, o = e + 16;
@@ -307,11 +337,11 @@ class z {
307
337
  }
308
338
  drawBar(e, t, i, s = !1) {
309
339
  const r = this.ctx, n = e.h / 2;
310
- this.roundRect(e.x, e.y, e.w, e.h, n), r.fillStyle = "rgba(255,255,255,0.22)", r.fill(), t > 0 && (this.roundRect(e.x, e.y, e.w * t, e.h, n), r.fillStyle = T, r.fill()), (s || i) && (r.beginPath(), r.arc(e.x + e.w * t, e.y + e.h / 2, i ? 12 : 9, 0, Math.PI * 2), r.fillStyle = "#fff", r.fill());
340
+ this.roundRect(e.x, e.y, e.w, e.h, n), r.fillStyle = "rgba(255,255,255,0.22)", r.fill(), t > 0 && (this.roundRect(e.x, e.y, e.w * t, e.h, n), r.fillStyle = R, r.fill()), (s || i) && (r.beginPath(), r.arc(e.x + e.w * t, e.y + e.h / 2, i ? 12 : 9, 0, Math.PI * 2), r.fillStyle = "#fff", r.fill());
311
341
  }
312
342
  drawSpeaker(e, t) {
313
343
  const i = this.ctx, s = e.x, r = e.y + e.h / 2;
314
- i.fillStyle = t ? I : M, i.beginPath(), i.moveTo(s, r - 7), i.lineTo(s + 10, r - 7), i.lineTo(s + 20, r - 16), i.lineTo(s + 20, r + 16), i.lineTo(s + 10, r + 7), i.lineTo(s, r + 7), i.closePath(), i.fill(), i.strokeStyle = t ? "#e06a6a" : M, i.lineWidth = 3, t ? (i.beginPath(), i.moveTo(s + 26, r - 9), i.lineTo(s + 40, r + 9), i.moveTo(s + 40, r - 9), i.lineTo(s + 26, r + 9), i.stroke()) : (i.beginPath(), i.arc(s + 24, r, 8, -Math.PI / 3, Math.PI / 3), i.stroke(), i.beginPath(), i.arc(s + 24, r, 15, -Math.PI / 3, Math.PI / 3), i.stroke());
344
+ i.fillStyle = t ? L : P, i.beginPath(), i.moveTo(s, r - 7), i.lineTo(s + 10, r - 7), i.lineTo(s + 20, r - 16), i.lineTo(s + 20, r + 16), i.lineTo(s + 10, r + 7), i.lineTo(s, r + 7), i.closePath(), i.fill(), i.strokeStyle = t ? "#e06a6a" : P, i.lineWidth = 3, t ? (i.beginPath(), i.moveTo(s + 26, r - 9), i.lineTo(s + 40, r + 9), i.moveTo(s + 40, r - 9), i.lineTo(s + 26, r + 9), i.stroke()) : (i.beginPath(), i.arc(s + 24, r, 8, -Math.PI / 3, Math.PI / 3), i.stroke(), i.beginPath(), i.arc(s + 24, r, 15, -Math.PI / 3, Math.PI / 3), i.stroke());
315
345
  }
316
346
  dispose() {
317
347
  for (const e of this.cleanups) e();
@@ -322,14 +352,14 @@ class z {
322
352
  this.scene.remove(this.panel), this.panel.geometry.dispose(), this.panel.material.dispose(), this.scene.remove(this.cursor), this.cursor.geometry.dispose(), this.cursor.material.dispose(), this.texture.dispose();
323
353
  }
324
354
  }
325
- function P() {
355
+ function E() {
326
356
  return typeof performance < "u" ? performance.now() : 0;
327
357
  }
328
- class Z {
358
+ class K {
329
359
  constructor(e) {
330
360
  this.scene = new a.Scene(), this.meshes = [], this.rig = new a.Group(), this.tilt = 0, this.fov = 1, this.builtFov = 1, this.frameCbs = [], this.alphaFisheye = !1, this.inPassthroughSession = !1, this.passthroughOn = !0, this.animate = (o) => {
331
361
  var c;
332
- for (const p of this.frameCbs) p();
362
+ for (const f of this.frameCbs) f();
333
363
  (c = this.vrControls) == null || c.update(o ?? 0), this.video.readyState >= this.video.HAVE_CURRENT_DATA && (this.texture.needsUpdate = !0), this.renderer.render(this.scene, this.camera);
334
364
  }, this.vrSessionInit = { optionalFeatures: ["local-floor"] }, this.arSessionInit = { optionalFeatures: ["local-floor"] }, this.vrTitle = "", this.resize = () => {
335
365
  if (this.renderer.xr.isPresenting) return;
@@ -337,8 +367,8 @@ class Z {
337
367
  this.camera.aspect = o / c, this.camera.updateProjectionMatrix(), this.renderer.setSize(o, c, !1);
338
368
  };
339
369
  const { canvas: t, video: i, projection: s = "180-sbs", swapEyes: r = !1, fov: n = 70, supersampling: l = 1.5 } = e;
340
- this.canvas = t, this.video = i, this.currentMode = b[s] ? s : "180-sbs", this.currentSwap = r, this.renderer = new a.WebGLRenderer({ canvas: t, antialias: !0, alpha: !0 }), this.renderer.setClearColor(0, 1), this.renderer.setPixelRatio(this.pixelRatioFor(l)), this.renderer.setSize(this.w(), this.h(), !1), this.renderer.xr.enabled = !0, this.camera = new a.PerspectiveCamera(n, this.w() / this.h(), 0.1, 1e3), this.camera.position.set(0, 0, 0), this.maxAnisotropy = this.renderer.capabilities.getMaxAnisotropy(), this.texture = new a.VideoTexture(i), this.texture.colorSpace = a.SRGBColorSpace, this.texture.minFilter = a.LinearFilter, this.texture.magFilter = a.LinearFilter, this.texture.anisotropy = 1, this.rig.rotation.order = "YXZ", this.scene.add(this.rig), this.applyProjection(this.currentMode, this.currentSwap), i.addEventListener("loadedmetadata", () => {
341
- b[this.currentMode].flat && this.applyProjection(this.currentMode, this.currentSwap);
370
+ this.canvas = t, this.video = i, this.currentMode = S[s] ? s : "180-sbs", this.currentSwap = r, this.renderer = new a.WebGLRenderer({ canvas: t, antialias: !0, alpha: !0 }), this.renderer.setClearColor(0, 1), this.renderer.setPixelRatio(this.pixelRatioFor(l)), this.renderer.setSize(this.w(), this.h(), !1), this.renderer.xr.enabled = !0, this.camera = new a.PerspectiveCamera(n, this.w() / this.h(), 0.1, 1e3), this.camera.position.set(0, 0, 0), this.maxAnisotropy = this.renderer.capabilities.getMaxAnisotropy(), this.texture = new a.VideoTexture(i), this.texture.colorSpace = a.SRGBColorSpace, this.texture.minFilter = a.LinearFilter, this.texture.magFilter = a.LinearFilter, this.texture.anisotropy = 1, this.rig.rotation.order = "YXZ", this.scene.add(this.rig), this.applyProjection(this.currentMode, this.currentSwap), i.addEventListener("loadedmetadata", () => {
371
+ S[this.currentMode].flat && this.applyProjection(this.currentMode, this.currentSwap);
342
372
  }), this.renderer.setAnimationLoop(this.animate), this.renderer.xr.addEventListener("sessionstart", () => {
343
373
  var c;
344
374
  const o = (c = this.renderer.xr.getSession()) == null ? void 0 : c.environmentBlendMode;
@@ -350,7 +380,7 @@ class Z {
350
380
  }
351
381
  buildVRControls() {
352
382
  const e = this.video;
353
- this.vrControls = new z({
383
+ this.vrControls = new X({
354
384
  renderer: this.renderer,
355
385
  scene: this.scene,
356
386
  actions: {
@@ -380,7 +410,9 @@ class Z {
380
410
  passthroughAvailable: () => this.inPassthroughSession,
381
411
  // any AR session, not just alpha content
382
412
  passthroughEnabled: () => this.passthroughOn,
383
- togglePassthrough: () => this.setPassthrough(!this.passthroughOn)
413
+ togglePassthrough: () => this.setPassthrough(!this.passthroughOn),
414
+ projectionLabel: () => this.projectionLabel(),
415
+ cycleProjection: (t) => this.cycleProjection(t)
384
416
  }
385
417
  });
386
418
  }
@@ -410,10 +442,10 @@ class Z {
410
442
  }
411
443
  planeAspect(e) {
412
444
  const t = this.video.videoWidth, i = this.video.videoHeight;
413
- return !t || !i ? 16 / 9 : b[e].aspect === "per-eye" ? t / 2 / i : t / i;
445
+ return !t || !i ? 16 / 9 : S[e].aspect === "per-eye" ? t / 2 / i : t / i;
414
446
  }
415
447
  buildGeometry(e) {
416
- const t = b[e].geom, i = this.fov;
448
+ const t = S[e].geom, i = this.fov;
417
449
  if (t === "sphere180") {
418
450
  const l = Math.PI * i, o = Math.PI * i, c = new a.SphereGeometry(50, 64, 32, -l / 2, l, Math.PI / 2 - o / 2, o);
419
451
  return c.scale(-1, 1, 1), c;
@@ -435,21 +467,21 @@ class Z {
435
467
  */
436
468
  buildFisheyeDome(e = 95) {
437
469
  const r = a.MathUtils.degToRad(e), n = [], l = [], o = [];
438
- for (let d = 0; d <= 64; d++) {
439
- const m = d / 64, v = m * r, u = m * 0.5, f = Math.sin(v), g = Math.cos(v);
440
- for (let x = 0; x <= 128; x++) {
441
- const A = x / 128 * Math.PI * 2, L = Math.cos(A), k = Math.sin(A);
442
- n.push(f * L * 50, f * k * 50, -g * 50), l.push(0.5 + u * L, 0.5 + u * k);
470
+ for (let u = 0; u <= 64; u++) {
471
+ const g = u / 64, v = g * r, p = g * 0.5, d = Math.sin(v), m = Math.cos(v);
472
+ for (let b = 0; b <= 128; b++) {
473
+ const M = b / 128 * Math.PI * 2, j = Math.cos(M), F = Math.sin(M);
474
+ n.push(d * j * 50, d * F * 50, -m * 50), l.push(0.5 + p * j, 0.5 + p * F);
443
475
  }
444
476
  }
445
477
  const c = 129;
446
- for (let d = 0; d < 64; d++)
447
- for (let m = 0; m < 128; m++) {
448
- const v = d * c + m, u = v + 1, f = v + c, g = f + 1;
449
- o.push(v, f, u, u, f, g);
478
+ for (let u = 0; u < 64; u++)
479
+ for (let g = 0; g < 128; g++) {
480
+ const v = u * c + g, p = v + 1, d = v + c, m = d + 1;
481
+ o.push(v, d, p, p, d, m);
450
482
  }
451
- const p = new a.BufferGeometry();
452
- return p.setAttribute("position", new a.Float32BufferAttribute(n, 3)), p.setAttribute("uv", new a.Float32BufferAttribute(l, 2)), p.setIndex(o), p.computeVertexNormals(), p;
483
+ const f = new a.BufferGeometry();
484
+ return f.setAttribute("position", new a.Float32BufferAttribute(n, 3)), f.setAttribute("uv", new a.Float32BufferAttribute(l, 2)), f.setIndex(o), f.computeVertexNormals(), f;
453
485
  }
454
486
  /**
455
487
  * Transparent material for fisheye content with a DeoVR-style packed alpha matte. Built by
@@ -509,7 +541,7 @@ varying vec2 vDiscUv;
509
541
  /** Shift the shared video texture for the eye/half being drawn. Runs from the mesh's
510
542
  * onBeforeRender, so it's called once per eye per frame (the reference approach). */
511
543
  updateStereoUV(e) {
512
- const t = this.texture, i = b[this.currentMode].split;
544
+ const t = this.texture, i = S[this.currentMode].split;
513
545
  let s = !0;
514
546
  if (this.renderer.xr.isPresenting) {
515
547
  const n = e, l = this.renderer.xr.getCamera().cameras;
@@ -528,16 +560,16 @@ varying vec2 vDiscUv;
528
560
  this.meshes.length = 0;
529
561
  }
530
562
  applyProjection(e, t) {
531
- b[e] || (e = "180-sbs"), this.clearMeshes(), this.currentMode = e, this.currentSwap = t, this.alphaUniforms = void 0;
563
+ S[e] || (e = "180-sbs"), this.clearMeshes(), this.currentMode = e, this.currentSwap = t, this.alphaUniforms = void 0;
532
564
  let i;
533
- if (b[e].geom === "fisheye" && this.alphaFisheye)
565
+ if (S[e].geom === "fisheye" && this.alphaFisheye)
534
566
  i = this.makeFisheyeAlphaMaterial();
535
567
  else {
536
- const r = b[e].geom === "fisheye" ? a.DoubleSide : a.FrontSide;
568
+ const r = S[e].geom === "fisheye" ? a.DoubleSide : a.FrontSide;
537
569
  i = new a.MeshBasicMaterial({ map: this.texture, side: r });
538
570
  }
539
571
  const s = new a.Mesh(this.buildGeometry(e), i);
540
- s.layers.set(0), b[e].geom === "sphere180" && (s.rotation.y = Math.PI / 2), s.onBeforeRender = (r, n, l) => this.updateStereoUV(l), this.rig.add(s), this.meshes.push(s);
572
+ s.layers.set(0), S[e].geom === "sphere180" && (s.rotation.y = Math.PI / 2), s.onBeforeRender = (r, n, l) => this.updateStereoUV(l), this.rig.add(s), this.meshes.push(s);
541
573
  }
542
574
  /** Pitch the video content up/down (radians, accumulated and clamped). */
543
575
  adjustTilt(e) {
@@ -564,6 +596,20 @@ varying vec2 vDiscUv;
564
596
  setProjection(e) {
565
597
  this.applyProjection(e, this.currentSwap);
566
598
  }
599
+ /** Player registers this so an in-VR projection change flows back through Player — keeping its
600
+ * state, persistence, and the DOM controls in sync. Falls back to a direct geometry swap. */
601
+ setProjectionRequester(e) {
602
+ this.projectionRequester = e;
603
+ }
604
+ /** Short label of the current projection, for the in-VR stepper. */
605
+ projectionLabel() {
606
+ return V[this.currentMode] ?? this.currentMode;
607
+ }
608
+ /** Step the projection by dir (±1) through the PROJECTIONS list (wraps around). */
609
+ cycleProjection(e) {
610
+ const t = G.map((r) => r.value), i = Math.max(0, t.indexOf(this.currentMode)), s = t[(i + e + t.length) % t.length];
611
+ (this.projectionRequester ?? ((r) => this.setProjection(r)))(s);
612
+ }
567
613
  setSwapEyes(e) {
568
614
  this.applyProjection(this.currentMode, e);
569
615
  }
@@ -577,7 +623,7 @@ varying vec2 vDiscUv;
577
623
  return this.currentMode;
578
624
  }
579
625
  isFlat() {
580
- return !!b[this.currentMode].flat;
626
+ return !!S[this.currentMode].flat;
581
627
  }
582
628
  onFrame(e) {
583
629
  this.frameCbs.push(e);
@@ -622,21 +668,21 @@ varying vec2 vDiscUv;
622
668
  this.ro.disconnect(), this.renderer.setAnimationLoop(null), (e = this.vrControls) == null || e.dispose(), this.texture.dispose(), this.clearMeshes(), this.renderer.dispose();
623
669
  }
624
670
  }
625
- const O = Math.PI / 180;
626
- function H(h, e) {
671
+ const B = Math.PI / 180;
672
+ function $(h, e) {
627
673
  return {
628
674
  lon: Math.max(-90, Math.min(90, h)),
629
675
  lat: Math.max(-85, Math.min(85, e))
630
676
  };
631
677
  }
632
- class K {
678
+ class ee {
633
679
  constructor(e, t, i = {}) {
634
680
  this.camera = e, this.dom = t, this.lon = 0, this.lat = 0, this.dragging = !1, this.px = 0, this.py = 0, this.enabled = !0, this.onDown = (s) => {
635
681
  this.enabled && (this.dragging = !0, this.px = s.clientX, this.py = s.clientY, this.capture("setPointerCapture", s.pointerId));
636
682
  }, this.onMove = (s) => {
637
683
  if (!this.dragging) return;
638
684
  const r = s.clientX - this.px, n = s.clientY - this.py;
639
- this.px = s.clientX, this.py = s.clientY, { lon: this.lon, lat: this.lat } = H(this.lon - r * 0.15, this.lat + n * 0.15);
685
+ this.px = s.clientX, this.py = s.clientY, { lon: this.lon, lat: this.lat } = $(this.lon - r * 0.15, this.lat + n * 0.15);
640
686
  }, this.onUp = (s) => {
641
687
  this.dragging = !1, this.capture("releasePointerCapture", s.pointerId);
642
688
  }, this.isPresenting = i.isPresenting ?? (() => !1), this.dom.addEventListener("pointerdown", this.onDown), this.dom.addEventListener("pointermove", this.onMove), this.dom.addEventListener("pointerup", this.onUp), this.dom.addEventListener("pointercancel", this.onUp);
@@ -650,7 +696,7 @@ class K {
650
696
  }
651
697
  update() {
652
698
  if (this.isPresenting() || !this.enabled) return;
653
- const e = (90 - this.lat) * O, t = this.lon * O;
699
+ const e = (90 - this.lat) * B, t = this.lon * B;
654
700
  this.camera.lookAt(
655
701
  Math.sin(e) * Math.sin(t),
656
702
  Math.cos(e),
@@ -670,7 +716,7 @@ class K {
670
716
  this.dom.removeEventListener("pointerdown", this.onDown), this.dom.removeEventListener("pointermove", this.onMove), this.dom.removeEventListener("pointerup", this.onUp), this.dom.removeEventListener("pointercancel", this.onUp);
671
717
  }
672
718
  }
673
- class J {
719
+ class te {
674
720
  constructor() {
675
721
  this.hls = null;
676
722
  }
@@ -679,26 +725,26 @@ class J {
679
725
  const s = i.crossOrigin === void 0 ? "anonymous" : i.crossOrigin;
680
726
  s === null ? e.removeAttribute("crossorigin") : e.crossOrigin = s, e.playsInline = !0;
681
727
  const { url: r, format: n } = t, l = n === "hls" || n === "dash", o = e.canPlayType("application/vnd.apple.mpegurl") !== "";
682
- return new Promise((c, p) => {
683
- const d = () => {
684
- e.removeEventListener("loadedmetadata", m), e.removeEventListener("error", v);
685
- }, m = () => {
686
- d(), c();
728
+ return new Promise((c, f) => {
729
+ const u = () => {
730
+ e.removeEventListener("loadedmetadata", g), e.removeEventListener("error", v);
731
+ }, g = () => {
732
+ u(), c();
687
733
  }, v = () => {
688
- d();
689
- const u = e.error ? e.error.code : "unknown";
690
- p(new Error(`Video failed to load (media error ${u}). Is the source reachable and CORS-clean?`));
734
+ u();
735
+ const p = e.error ? e.error.code : "unknown";
736
+ f(new Error(`Video failed to load (media error ${p}). Is the source reachable and CORS-clean?`));
691
737
  };
692
- e.addEventListener("loadedmetadata", m), e.addEventListener("error", v), l && !o ? import("hls.js").then(({ default: u }) => {
693
- if (!u.isSupported()) {
694
- d(), p(new Error("HLS/DASH stream needs hls.js, which is unsupported in this browser."));
738
+ e.addEventListener("loadedmetadata", g), e.addEventListener("error", v), l && !o ? import("hls.js").then(({ default: p }) => {
739
+ if (!p.isSupported()) {
740
+ u(), f(new Error("HLS/DASH stream needs hls.js, which is unsupported in this browser."));
695
741
  return;
696
742
  }
697
- this.hls = new u({ enableWorker: !0 }), this.hls.on(u.Events.ERROR, (f, g) => {
698
- g.fatal && (d(), this.dispose(), p(new Error(`HLS fatal error: ${g.type} / ${g.details}`)));
743
+ this.hls = new p({ enableWorker: !0 }), this.hls.on(p.Events.ERROR, (d, m) => {
744
+ m.fatal && (u(), this.dispose(), f(new Error(`HLS fatal error: ${m.type} / ${m.details}`)));
699
745
  }), this.hls.loadSource(r), this.hls.attachMedia(e);
700
746
  }).catch(() => {
701
- d(), p(new Error('This looks like an HLS/DASH stream but hls.js could not be loaded. Install "hls.js".'));
747
+ u(), f(new Error('This looks like an HLS/DASH stream but hls.js could not be loaded. Install "hls.js".'));
702
748
  }) : (e.src = r, e.load());
703
749
  });
704
750
  }
@@ -707,16 +753,16 @@ class J {
707
753
  }
708
754
  }
709
755
  export {
710
- K as L,
711
- b as M,
712
- X as P,
713
- Z as S,
714
- J as V,
715
- Y as a,
716
- q as b,
717
- H as c,
718
- D as d,
719
- F as f,
720
- $ as i
756
+ ee as L,
757
+ S as M,
758
+ G as P,
759
+ K as S,
760
+ te as V,
761
+ J as a,
762
+ Y as b,
763
+ $ as c,
764
+ Q as d,
765
+ k as f,
766
+ Z as i
721
767
  };
722
- //# sourceMappingURL=VideoSource-BXMPMJzW.js.map
768
+ //# sourceMappingURL=VideoSource-DHj5tBsK.js.map