three-vr-player 0.2.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 +1 -0
- package/dist/Player.d.ts +9 -0
- package/dist/three-vr-player.js +175 -144
- package/dist/three-vr-player.js.map +1 -1
- package/dist/three-vr-player.standalone.js +38 -38
- package/dist/three-vr-player.standalone.js.map +1 -1
- package/dist/ui/ControlsUI.d.ts +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,6 +87,7 @@ new Player(container, {
|
|
|
87
87
|
```ts
|
|
88
88
|
player.load(src, { projection? }); player.play(); player.pause();
|
|
89
89
|
player.setProjection(p); player.setSwapEyes(b); player.setFov(deg); player.setSupersampling(x);
|
|
90
|
+
player.setProxy({ url, apiPassword?, enabled }); // also exposed as a toggle in the ⚙ settings
|
|
90
91
|
player.enterVR(); player.dispose();
|
|
91
92
|
player.video; // the underlying <video>
|
|
92
93
|
player.three; // { renderer, scene, camera }
|
package/dist/Player.d.ts
CHANGED
|
@@ -18,6 +18,9 @@ export declare class Player {
|
|
|
18
18
|
private readyEmitted;
|
|
19
19
|
private native;
|
|
20
20
|
private loading;
|
|
21
|
+
private proxyConfig?;
|
|
22
|
+
private useProxy;
|
|
23
|
+
private currentSrc?;
|
|
21
24
|
constructor(container: HTMLElement, options?: PlayerOptions);
|
|
22
25
|
private vrSupported;
|
|
23
26
|
load(src: string, o?: {
|
|
@@ -31,6 +34,12 @@ export declare class Player {
|
|
|
31
34
|
setSwapEyes(v: boolean): void;
|
|
32
35
|
setFov(deg: number): void;
|
|
33
36
|
setSupersampling(x: number): void;
|
|
37
|
+
/** Update the CORS proxy config / toggle it, and reload the current source if any. */
|
|
38
|
+
setProxy(p: {
|
|
39
|
+
url: string;
|
|
40
|
+
apiPassword?: string;
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
}): void;
|
|
34
43
|
enterVR(): Promise<void>;
|
|
35
44
|
get three(): {
|
|
36
45
|
renderer: import('three').WebGLRenderer;
|
package/dist/three-vr-player.js
CHANGED
|
@@ -1,86 +1,109 @@
|
|
|
1
|
-
import { P as
|
|
2
|
-
import { M as
|
|
3
|
-
function
|
|
1
|
+
import { P as Y, V as _, S as H, L as K, a as G, b as Q } from "./VideoSource-CJGIX8gL.js";
|
|
2
|
+
import { M as nt, c as rt, d as at, i as pt } from "./VideoSource-CJGIX8gL.js";
|
|
3
|
+
function R(l) {
|
|
4
4
|
if (!Number.isFinite(l) || l < 0) return "0:00";
|
|
5
|
-
const t = Math.floor(l % 60),
|
|
6
|
-
return
|
|
5
|
+
const t = Math.floor(l % 60), e = Math.floor(l / 60 % 60), s = Math.floor(l / 3600), p = String(t).padStart(2, "0");
|
|
6
|
+
return s > 0 ? `${s}:${String(e).padStart(2, "0")}:${p}` : `${e}:${p}`;
|
|
7
7
|
}
|
|
8
|
-
function
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
for (const
|
|
12
|
-
return
|
|
8
|
+
function o(l, t = {}, e = []) {
|
|
9
|
+
const s = document.createElement(l), { class: p, ...c } = t;
|
|
10
|
+
p && (s.className = p), Object.assign(s, c);
|
|
11
|
+
for (const u of e) s.append(u);
|
|
12
|
+
return s;
|
|
13
13
|
}
|
|
14
|
-
class
|
|
15
|
-
constructor(t,
|
|
14
|
+
class X {
|
|
15
|
+
constructor(t, e) {
|
|
16
16
|
this.nodes = [], this.disposers = [];
|
|
17
|
-
const
|
|
18
|
-
for (const i of
|
|
19
|
-
const
|
|
20
|
-
|
|
17
|
+
const s = e.video, p = o("button", { class: "tvp-btn tvp-play", title: "Play/Pause", textContent: "▶" }), c = o("input", { class: "tvp-seek", type: "range", min: "0", max: "1000", value: "0" }), u = o("span", { class: "tvp-time", textContent: "0:00 / 0:00" }), r = o("button", { class: "tvp-btn tvp-mute", title: "Volume", textContent: "🔊" }), v = o("input", { class: "tvp-volume", type: "range", min: "0", max: "1", step: "0.01", value: "1" }), f = o("div", { class: "tvp-volpopup", hidden: !0 }, [v]), D = o("span", { class: "tvp-volwrap" }, [r, f]), N = o("span", { class: "tvp-vrslot" }), b = o("button", { class: "tvp-btn tvp-projbtn", title: "Projection", textContent: "🌐" }), h = o("div", { class: "tvp-projmenu", hidden: !0 });
|
|
18
|
+
for (const i of Y) {
|
|
19
|
+
const n = o("button", { textContent: i.label });
|
|
20
|
+
n.dataset.mode = i.value, h.append(n);
|
|
21
21
|
}
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const J = o("span", { class: "tvp-projwrap" }, [b, h]), k = o("button", { class: "tvp-btn tvp-settingsbtn", title: "Settings", textContent: "⚙" }), O = o("button", { class: "tvp-btn tvp-fullscreen", title: "Fullscreen", textContent: "⛶" }), S = o("footer", { class: "tvp-controls" }, [p, c, u, D, N, J, k, O]), P = o("input", { type: "checkbox", checked: e.initial.swapEyes }), x = o("input", { type: "range", min: "30", max: "100", step: "1", value: String(e.initial.fov) }), E = o("span", { textContent: String(e.initial.fov) }), j = o("input", { type: "range", min: "1", max: "2", step: "0.25", value: String(e.initial.supersampling) }), A = o("span", { textContent: String(e.initial.supersampling) }), C = o("input", { type: "checkbox", checked: e.proxy.enabled }), F = o("input", { type: "text", value: e.proxy.url, placeholder: "http://localhost:8888", spellcheck: !1 }), T = o("input", { type: "password", value: e.proxy.apiPassword, placeholder: "API password" }), g = o("section", { class: "tvp-settings" }, [
|
|
23
|
+
o("label", { class: "row" }, [P, "Swap eyes (if depth looks wrong)"]),
|
|
24
|
+
o("label", {}, [$("Field of view (zoom): ", E, "°"), x]),
|
|
25
|
+
o("label", {}, [$("Supersampling: ", A, "× (sharpness)"), j]),
|
|
26
|
+
o("hr", { class: "tvp-sep" }),
|
|
27
|
+
o("label", { class: "row" }, [C, "Use CORS proxy"]),
|
|
28
|
+
o("label", {}, ["Proxy URL", F]),
|
|
29
|
+
o("label", {}, ["API password", T])
|
|
30
|
+
]), W = o("div", { class: "tvp-toast" });
|
|
31
|
+
this.nodes.push(S, g, W);
|
|
28
32
|
for (const i of this.nodes) t.append(i);
|
|
29
|
-
const
|
|
30
|
-
i.addEventListener(
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}),
|
|
37
|
-
|
|
38
|
-
}),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
const a = (i, n, d, m) => {
|
|
34
|
+
i.addEventListener(n, d, m), this.disposers.push(() => i.removeEventListener(n, d, m));
|
|
35
|
+
}, I = (i) => c.style.setProperty("--seek", `${i}%`), y = () => {
|
|
36
|
+
f.hidden = !0, h.hidden = !0, g.classList.remove("open");
|
|
37
|
+
};
|
|
38
|
+
a(p, "click", () => {
|
|
39
|
+
s.paused ? s.play() : s.pause();
|
|
40
|
+
}), a(s, "play", () => {
|
|
41
|
+
p.textContent = "⏸";
|
|
42
|
+
}), a(s, "pause", () => {
|
|
43
|
+
p.textContent = "▶";
|
|
44
|
+
}), a(s, "timeupdate", () => {
|
|
45
|
+
if (s.duration) {
|
|
46
|
+
const i = s.currentTime / s.duration * 100;
|
|
47
|
+
c.value = String(i * 10), I(i), u.textContent = `${R(s.currentTime)} / ${R(s.duration)}`;
|
|
42
48
|
}
|
|
43
|
-
}),
|
|
44
|
-
|
|
45
|
-
}),
|
|
46
|
-
i.stopPropagation()
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
}), a(c, "input", () => {
|
|
50
|
+
I(Number(c.value) / 10), s.duration && (s.currentTime = Number(c.value) / 1e3 * s.duration);
|
|
51
|
+
}), a(r, "click", (i) => {
|
|
52
|
+
i.stopPropagation();
|
|
53
|
+
const n = f.hidden;
|
|
54
|
+
y(), f.hidden = !n;
|
|
55
|
+
}), a(v, "input", () => {
|
|
56
|
+
s.volume = Number(v.value), s.muted = s.volume === 0, r.textContent = s.muted ? "🔇" : "🔊";
|
|
49
57
|
});
|
|
50
|
-
const
|
|
51
|
-
const i =
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
}), b.title =
|
|
58
|
+
const M = () => {
|
|
59
|
+
const i = e.getProjection();
|
|
60
|
+
let n = "Projection";
|
|
61
|
+
h.querySelectorAll("button").forEach((d) => {
|
|
62
|
+
const m = d.dataset.mode === i;
|
|
63
|
+
d.classList.toggle("active", m), m && (n = `Projection: ${d.textContent}`);
|
|
64
|
+
}), b.title = n;
|
|
57
65
|
};
|
|
58
|
-
|
|
59
|
-
i.stopPropagation()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}),
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
a(b, "click", (i) => {
|
|
67
|
+
i.stopPropagation();
|
|
68
|
+
const n = h.hidden;
|
|
69
|
+
y(), h.hidden = !n;
|
|
70
|
+
}), a(h, "click", (i) => {
|
|
71
|
+
const n = i.target.closest("button[data-mode]");
|
|
72
|
+
n && (e.setProjection(n.dataset.mode), M(), h.hidden = !0);
|
|
73
|
+
}), M(), a(k, "click", (i) => {
|
|
74
|
+
i.stopPropagation();
|
|
75
|
+
const n = !g.classList.contains("open");
|
|
76
|
+
y(), g.classList.toggle("open", n);
|
|
77
|
+
}), a(P, "change", () => e.setSwapEyes(P.checked)), a(x, "input", () => {
|
|
78
|
+
const i = Number(x.value);
|
|
79
|
+
E.textContent = String(i), e.setFov(i);
|
|
80
|
+
}), a(j, "input", () => {
|
|
81
|
+
const i = Number(j.value);
|
|
82
|
+
A.textContent = String(i), e.setSupersampling(i);
|
|
83
|
+
});
|
|
84
|
+
const L = () => e.setProxy({ url: F.value.trim(), apiPassword: T.value, enabled: C.checked });
|
|
85
|
+
a(C, "change", L), a(F, "change", L), a(T, "change", L), a(e.surface, "wheel", (i) => {
|
|
72
86
|
i.preventDefault();
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
}, { passive: !1 }),
|
|
76
|
-
var
|
|
77
|
-
const i =
|
|
78
|
-
document.fullscreenElement ? (
|
|
79
|
-
}),
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
})
|
|
83
|
-
|
|
87
|
+
const n = Math.max(30, Math.min(100, Number(x.value) + Math.sign(i.deltaY) * 3));
|
|
88
|
+
x.value = String(n), E.textContent = String(n), e.setFov(n);
|
|
89
|
+
}, { passive: !1 }), a(O, "click", () => {
|
|
90
|
+
var n, d;
|
|
91
|
+
const i = e.fullscreenTarget;
|
|
92
|
+
document.fullscreenElement ? (d = document.exitFullscreen) == null || d.call(document) : (n = i.requestFullscreen) == null || n.call(i);
|
|
93
|
+
}), a(document, "click", (i) => {
|
|
94
|
+
const n = i.composedPath(), d = (m) => n.includes(m);
|
|
95
|
+
[f, r, h, b, g, k].some(d) || y();
|
|
96
|
+
});
|
|
97
|
+
let w = 0;
|
|
98
|
+
const q = () => !f.hidden || !h.hidden || g.classList.contains("open"), B = () => {
|
|
99
|
+
q() || S.classList.add("tvp-hidden");
|
|
100
|
+
}, z = () => {
|
|
101
|
+
S.classList.remove("tvp-hidden"), clearTimeout(w), w = window.setTimeout(B, 5e3);
|
|
102
|
+
};
|
|
103
|
+
a(e.fullscreenTarget, "pointermove", z), a(e.fullscreenTarget, "pointerdown", z), a(e.fullscreenTarget, "pointerleave", () => {
|
|
104
|
+
clearTimeout(w), B();
|
|
105
|
+
}), this.disposers.push(() => clearTimeout(w)), z(), e.vrSupported().then((i) => {
|
|
106
|
+
i && (Object.assign(e.vrButton.style, { position: "static", left: "auto", bottom: "auto", transform: "none", margin: "0" }), N.append(e.vrButton));
|
|
84
107
|
});
|
|
85
108
|
}
|
|
86
109
|
dispose() {
|
|
@@ -88,78 +111,82 @@ class J {
|
|
|
88
111
|
for (const t of this.nodes) t.remove();
|
|
89
112
|
}
|
|
90
113
|
}
|
|
91
|
-
function
|
|
92
|
-
const
|
|
93
|
-
return
|
|
114
|
+
function $(l, t, e) {
|
|
115
|
+
const s = document.createDocumentFragment();
|
|
116
|
+
return s.append(l, t, e), s;
|
|
94
117
|
}
|
|
95
|
-
const
|
|
96
|
-
class
|
|
97
|
-
constructor(t,
|
|
98
|
-
|
|
99
|
-
|
|
118
|
+
const U = ":host,:host *,.tvp,.tvp *{box-sizing:border-box}.tvp-canvas{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;display:block;touch-action:none;cursor:grab}.tvp-canvas:active{cursor:grabbing}.tvp-video{display:none}.tvp-controls{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;gap:10px;padding:12px;background:linear-gradient(transparent,#000c);z-index:5;font:14px system-ui,Segoe UI,Roboto,sans-serif;color:#e8eaed;transition:opacity .3s}.tvp-controls.tvp-hidden{opacity:0;pointer-events:none}.tvp-btn{padding:4px;border:0;background:none;color:#e8eaed;cursor:pointer;font-size:22px;line-height:1}.tvp-btn:hover{opacity:.7}.tvp-seek{flex:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:14px;background:transparent;cursor:pointer;margin:0}.tvp-seek::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(to right,#4f8cff var(--seek,0%),#3a4150 var(--seek,0%))}.tvp-seek::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-top:-4px;width:12px;height:12px;border-radius:50%;background:#fff;cursor:pointer}.tvp-seek::-moz-range-track{height:4px;border-radius:2px;background:#3a4150}.tvp-seek::-moz-range-progress{height:4px;border-radius:2px;background:#4f8cff}.tvp-seek::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50%;background:#fff;cursor:pointer}.tvp-time{font-variant-numeric:tabular-nums;min-width:96px;text-align:center;color:#cfd6e2}.tvp-volwrap,.tvp-projwrap{position:relative;display:inline-flex}.tvp-volpopup{position:absolute;bottom:calc(100% + 10px);left:50%;transform:translate(-50%);width:40px;height:132px;background:#121418eb;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid #2a2f3a;border-radius:10px;z-index:8;box-shadow:0 8px 24px #0009}.tvp-volpopup[hidden]{display:none}.tvp-volume{position:absolute;top:50%;left:50%;width:104px;height:14px;margin:0;transform:translate(-50%,-50%) rotate(-90deg);-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;cursor:pointer}.tvp-volume::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:#3a4150}.tvp-volume::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-top:-4px;width:12px;height:12px;border-radius:50%;background:#fff;cursor:pointer}.tvp-volume::-moz-range-track{height:4px;border-radius:2px;background:#3a4150}.tvp-volume::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50%;background:#fff;cursor:pointer}.tvp-projmenu{position:absolute;bottom:calc(100% + 8px);right:0;min-width:210px;background:#121418eb;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid #2a2f3a;border-radius:10px;padding:6px;display:flex;flex-direction:column;gap:2px;z-index:8;box-shadow:0 8px 24px #0009}.tvp-projmenu[hidden]{display:none}.tvp-projmenu button{text-align:left;background:transparent;border:0;color:#e8eaed;padding:8px 10px;border-radius:7px;cursor:pointer;font:inherit;white-space:nowrap}.tvp-projmenu button:hover{background:#252b39}.tvp-projmenu button.active{background:#4f8cff;color:#fff}.tvp-vrslot button{position:static!important}.tvp-settings{position:absolute;bottom:62px;right:10px;width:300px;max-width:calc(100% - 20px);max-height:70%;overflow-y:auto;background:#121418eb;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid #2a2f3a;border-radius:12px;padding:14px;display:none;flex-direction:column;gap:12px;z-index:6;font:14px system-ui,Segoe UI,Roboto,sans-serif;color:#e8eaed}.tvp-settings.open{display:flex}.tvp-settings label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:#aab2c0}.tvp-settings label.row{flex-direction:row;align-items:center;gap:8px;color:#e8eaed;font-size:13px}.tvp-settings input[type=range]{width:100%;accent-color:#4f8cff}.tvp-settings input[type=text],.tvp-settings input[type=password]{width:100%;padding:7px 9px;border-radius:7px;border:1px solid #333;background:#151821;color:#e8eaed;font:inherit}.tvp-sep{width:100%;border:0;border-top:1px solid #2a2f3a;margin:2px 0}.tvp-toast{position:absolute;left:50%;bottom:74px;transform:translate(-50%);max-width:80%;padding:10px 16px;border-radius:10px;background:#1b1f2aed;border:1px solid #2a2f3a;color:#e8eaed;opacity:0;pointer-events:none;transition:opacity .2s;z-index:7;font:13px system-ui}.tvp-toast.show{opacity:1}", V = "three-vr-player:settings";
|
|
119
|
+
class Z {
|
|
120
|
+
constructor(t, e = {}) {
|
|
121
|
+
var c, u;
|
|
122
|
+
this.source = new _(), this.listeners = /* @__PURE__ */ new Map(), this.readyEmitted = !1, this.native = !1, this.loading = !1, this.useProxy = !1, this.opts = e, this.proxyConfig = e.proxy, this.useProxy = !!e.proxy;
|
|
123
|
+
const s = e.persistSettings ? this.loadSettings() : null;
|
|
100
124
|
this.view = {
|
|
101
|
-
projection:
|
|
102
|
-
swapEyes:
|
|
103
|
-
fov:
|
|
104
|
-
supersampling:
|
|
125
|
+
projection: e.projection ?? (s == null ? void 0 : s.projection) ?? "180-sbs",
|
|
126
|
+
swapEyes: e.swapEyes ?? (s == null ? void 0 : s.swapEyes) ?? !1,
|
|
127
|
+
fov: e.fov ?? (s == null ? void 0 : s.fov) ?? 70,
|
|
128
|
+
supersampling: e.supersampling ?? (s == null ? void 0 : s.supersampling) ?? 1.5
|
|
105
129
|
}, this.wrap = document.createElement("div"), this.wrap.className = "tvp", this.wrap.style.cssText = "position:relative;width:100%;height:100%;overflow:hidden;", t.appendChild(this.wrap);
|
|
106
|
-
let
|
|
107
|
-
if (
|
|
108
|
-
const
|
|
109
|
-
|
|
130
|
+
let p;
|
|
131
|
+
if (e.shadowDom !== !1) {
|
|
132
|
+
const r = this.wrap.attachShadow({ mode: "open" }), v = document.createElement("style");
|
|
133
|
+
v.textContent = U, r.appendChild(v), p = r;
|
|
110
134
|
} else {
|
|
111
135
|
if (!document.getElementById("tvp-styles")) {
|
|
112
|
-
const
|
|
113
|
-
|
|
136
|
+
const r = document.createElement("style");
|
|
137
|
+
r.id = "tvp-styles", r.textContent = U, document.head.appendChild(r);
|
|
114
138
|
}
|
|
115
|
-
|
|
139
|
+
p = this.wrap;
|
|
116
140
|
}
|
|
117
|
-
this.canvas = document.createElement("canvas"), this.canvas.className = "tvp-canvas", this.video = document.createElement("video"), this.video.className = "tvp-video", this.video.playsInline = !0,
|
|
141
|
+
this.canvas = document.createElement("canvas"), this.canvas.className = "tvp-canvas", this.video = document.createElement("video"), this.video.className = "tvp-video", this.video.playsInline = !0, e.crossOrigin !== null && (this.video.crossOrigin = e.crossOrigin ?? "anonymous"), p.append(this.canvas, this.video), this.scene = new H({
|
|
118
142
|
canvas: this.canvas,
|
|
119
143
|
video: this.video,
|
|
120
144
|
projection: this.view.projection,
|
|
121
145
|
swapEyes: this.view.swapEyes,
|
|
122
146
|
fov: this.view.fov,
|
|
123
147
|
supersampling: this.view.supersampling
|
|
124
|
-
}), this.look = new
|
|
148
|
+
}), this.look = new K(this.scene.camera, this.canvas, { isPresenting: () => this.scene.renderer.xr.isPresenting }), this.scene.onFrame(() => this.look.update()), this.look.setEnabled(!this.scene.isFlat()), e.controls !== !1 && (this.ui = new X(p, {
|
|
125
149
|
video: this.video,
|
|
126
150
|
surface: this.canvas,
|
|
127
151
|
fullscreenTarget: this.wrap,
|
|
128
152
|
vrButton: this.scene.vrButton,
|
|
129
153
|
vrSupported: () => this.vrSupported(),
|
|
130
154
|
getProjection: () => this.scene.getProjection(),
|
|
131
|
-
setProjection: (
|
|
132
|
-
setSwapEyes: (
|
|
133
|
-
setFov: (
|
|
134
|
-
setSupersampling: (
|
|
135
|
-
initial: { swapEyes: this.view.swapEyes, fov: this.view.fov, supersampling: this.view.supersampling }
|
|
155
|
+
setProjection: (r) => this.setProjection(r),
|
|
156
|
+
setSwapEyes: (r) => this.setSwapEyes(r),
|
|
157
|
+
setFov: (r) => this.setFov(r),
|
|
158
|
+
setSupersampling: (r) => this.setSupersampling(r),
|
|
159
|
+
initial: { swapEyes: this.view.swapEyes, fov: this.view.fov, supersampling: this.view.supersampling },
|
|
160
|
+
proxy: { url: ((c = this.proxyConfig) == null ? void 0 : c.url) ?? "", apiPassword: ((u = this.proxyConfig) == null ? void 0 : u.apiPassword) ?? "", enabled: this.useProxy },
|
|
161
|
+
setProxy: (r) => this.setProxy(r)
|
|
136
162
|
})), this.video.addEventListener("play", () => this.emit("play")), this.video.addEventListener("pause", () => this.emit("pause")), this.video.addEventListener("ended", () => this.emit("ended")), this.video.addEventListener("timeupdate", () => this.emit("timeupdate", this.video.currentTime)), this.video.addEventListener("error", () => {
|
|
137
163
|
this.loading || this.emit("error", this.video.error);
|
|
138
164
|
}), this.video.addEventListener("loadedmetadata", () => {
|
|
139
165
|
this.readyEmitted || (this.readyEmitted = !0, this.emit("ready"));
|
|
140
|
-
}), this.scene.renderer.xr.addEventListener("sessionstart", () => this.emit("enterxr")), this.scene.renderer.xr.addEventListener("sessionend", () => this.emit("exitxr")),
|
|
166
|
+
}), this.scene.renderer.xr.addEventListener("sessionstart", () => this.emit("enterxr")), this.scene.renderer.xr.addEventListener("sessionend", () => this.emit("exitxr")), e.src && this.load(e.src, { projection: e.projection });
|
|
141
167
|
}
|
|
142
168
|
vrSupported() {
|
|
143
169
|
return this.opts.vrButton === !1 || !navigator.xr ? Promise.resolve(!1) : navigator.xr.isSessionSupported("immersive-vr").catch(() => !1);
|
|
144
170
|
}
|
|
145
|
-
async load(t,
|
|
146
|
-
|
|
147
|
-
e
|
|
148
|
-
|
|
171
|
+
async load(t, e = {}) {
|
|
172
|
+
this.currentSrc = t;
|
|
173
|
+
const s = e.projection ?? (this.opts.autoDetect !== !1 ? G(t) : null);
|
|
174
|
+
s && this.setProjection(s);
|
|
175
|
+
const { url: p, format: c } = Q(t, this.useProxy ? this.proxyConfig : void 0), u = this.opts.crossOrigin === void 0 ? "anonymous" : this.opts.crossOrigin;
|
|
149
176
|
this.loading = !0;
|
|
150
177
|
try {
|
|
151
|
-
await this.source.attach(this.video, { url:
|
|
178
|
+
await this.source.attach(this.video, { url: p, format: c }, { crossOrigin: u }), this.setNativeFallback(!1), await this.video.play().catch(() => {
|
|
152
179
|
});
|
|
153
|
-
} catch (
|
|
154
|
-
if (this.opts.nativeFallback !== !1 &&
|
|
180
|
+
} catch (r) {
|
|
181
|
+
if (this.opts.nativeFallback !== !1 && c === "progressive" && u !== null)
|
|
155
182
|
try {
|
|
156
|
-
this.setNativeFallback(!0), await this.source.attach(this.video, { url:
|
|
183
|
+
this.setNativeFallback(!0), await this.source.attach(this.video, { url: p, format: c }, { crossOrigin: null }), await this.video.play().catch(() => {
|
|
157
184
|
}), this.emit("fallback");
|
|
158
185
|
return;
|
|
159
186
|
} catch (v) {
|
|
160
187
|
throw this.setNativeFallback(!1), this.emit("error", v), v;
|
|
161
188
|
}
|
|
162
|
-
throw this.setNativeFallback(!1), this.emit("error",
|
|
189
|
+
throw this.setNativeFallback(!1), this.emit("error", r), r;
|
|
163
190
|
} finally {
|
|
164
191
|
this.loading = !1;
|
|
165
192
|
}
|
|
@@ -195,36 +222,40 @@ class W {
|
|
|
195
222
|
setSupersampling(t) {
|
|
196
223
|
this.scene.setSupersampling(t), this.view.supersampling = t, this.persist();
|
|
197
224
|
}
|
|
225
|
+
/** Update the CORS proxy config / toggle it, and reload the current source if any. */
|
|
226
|
+
setProxy(t) {
|
|
227
|
+
this.proxyConfig = t.url ? { url: t.url, apiPassword: t.apiPassword || void 0 } : void 0, this.useProxy = t.enabled, this.currentSrc && this.load(this.currentSrc);
|
|
228
|
+
}
|
|
198
229
|
async enterVR() {
|
|
199
|
-
var
|
|
230
|
+
var e;
|
|
200
231
|
const t = this.scene.vrButton;
|
|
201
|
-
(
|
|
232
|
+
(e = t == null ? void 0 : t.click) == null || e.call(t);
|
|
202
233
|
}
|
|
203
234
|
get three() {
|
|
204
235
|
return { renderer: this.scene.renderer, scene: this.scene.scene, camera: this.scene.camera };
|
|
205
236
|
}
|
|
206
|
-
on(t,
|
|
207
|
-
let
|
|
208
|
-
return
|
|
237
|
+
on(t, e) {
|
|
238
|
+
let s = this.listeners.get(t);
|
|
239
|
+
return s || (s = /* @__PURE__ */ new Set(), this.listeners.set(t, s)), s.add(e), this;
|
|
209
240
|
}
|
|
210
|
-
off(t,
|
|
211
|
-
var
|
|
212
|
-
return (
|
|
241
|
+
off(t, e) {
|
|
242
|
+
var s;
|
|
243
|
+
return (s = this.listeners.get(t)) == null || s.delete(e), this;
|
|
213
244
|
}
|
|
214
|
-
emit(t,
|
|
215
|
-
var
|
|
216
|
-
(
|
|
245
|
+
emit(t, e) {
|
|
246
|
+
var s;
|
|
247
|
+
(s = this.listeners.get(t)) == null || s.forEach((p) => p(e));
|
|
217
248
|
}
|
|
218
249
|
persist() {
|
|
219
250
|
if (this.opts.persistSettings)
|
|
220
251
|
try {
|
|
221
|
-
localStorage.setItem(
|
|
252
|
+
localStorage.setItem(V, JSON.stringify(this.view));
|
|
222
253
|
} catch {
|
|
223
254
|
}
|
|
224
255
|
}
|
|
225
256
|
loadSettings() {
|
|
226
257
|
try {
|
|
227
|
-
const t = localStorage.getItem(
|
|
258
|
+
const t = localStorage.getItem(V);
|
|
228
259
|
return t ? JSON.parse(t) : null;
|
|
229
260
|
} catch {
|
|
230
261
|
return null;
|
|
@@ -235,12 +266,12 @@ class W {
|
|
|
235
266
|
(t = this.ui) == null || t.dispose(), this.look.dispose(), this.source.dispose(), this.scene.dispose(), this.video.remove(), this.canvas.remove(), this.wrap.remove(), this.listeners.clear();
|
|
236
267
|
}
|
|
237
268
|
}
|
|
238
|
-
class
|
|
269
|
+
class tt extends HTMLElement {
|
|
239
270
|
static get observedAttributes() {
|
|
240
271
|
return ["src", "projection"];
|
|
241
272
|
}
|
|
242
273
|
connectedCallback() {
|
|
243
|
-
this.player || (this.style.display || (this.style.display = "block"), this.player = new
|
|
274
|
+
this.player || (this.style.display || (this.style.display = "block"), this.player = new Z(this, {
|
|
244
275
|
src: this.getAttribute("src") ?? void 0,
|
|
245
276
|
projection: this.getAttribute("projection") ?? void 0,
|
|
246
277
|
controls: this.hasAttribute("controls"),
|
|
@@ -251,39 +282,39 @@ class q extends HTMLElement {
|
|
|
251
282
|
proxy: this.getAttribute("proxy-url") ? { url: this.getAttribute("proxy-url"), apiPassword: this.getAttribute("proxy-password") ?? void 0 } : void 0
|
|
252
283
|
}));
|
|
253
284
|
}
|
|
254
|
-
attributeChangedCallback(t,
|
|
255
|
-
!this.player ||
|
|
285
|
+
attributeChangedCallback(t, e, s) {
|
|
286
|
+
!this.player || s == null || (t === "src" && this.player.load(s), t === "projection" && this.player.setProjection(s));
|
|
256
287
|
}
|
|
257
288
|
disconnectedCallback() {
|
|
258
289
|
var t;
|
|
259
290
|
(t = this.player) == null || t.dispose(), this.player = void 0;
|
|
260
291
|
}
|
|
261
292
|
numAttr(t) {
|
|
262
|
-
const
|
|
263
|
-
return
|
|
293
|
+
const e = this.getAttribute(t);
|
|
294
|
+
return e == null ? void 0 : Number(e);
|
|
264
295
|
}
|
|
265
296
|
/** The underlying Player instance (for programmatic control). */
|
|
266
297
|
get api() {
|
|
267
298
|
return this.player;
|
|
268
299
|
}
|
|
269
300
|
}
|
|
270
|
-
function
|
|
271
|
-
typeof customElements < "u" && !customElements.get(l) && customElements.define(l,
|
|
301
|
+
function et(l = "three-video") {
|
|
302
|
+
typeof customElements < "u" && !customElements.get(l) && customElements.define(l, tt);
|
|
272
303
|
}
|
|
273
|
-
|
|
304
|
+
et();
|
|
274
305
|
export {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
306
|
+
K as LookControls,
|
|
307
|
+
nt as MODES,
|
|
308
|
+
Y as PROJECTIONS,
|
|
309
|
+
Z as Player,
|
|
310
|
+
H as StereoScene,
|
|
311
|
+
tt as ThreeVideoElement,
|
|
312
|
+
_ as VideoSource,
|
|
313
|
+
Q as buildProxyUrl,
|
|
314
|
+
rt as clampAngles,
|
|
315
|
+
at as detectFormat,
|
|
316
|
+
G as detectProjection,
|
|
317
|
+
pt as isFlatMode,
|
|
318
|
+
et as registerWebComponent
|
|
288
319
|
};
|
|
289
320
|
//# sourceMappingURL=three-vr-player.js.map
|