three-vr-player 0.4.0 → 0.6.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 +3 -0
- package/dist/Player.d.ts +10 -2
- package/dist/VideoSource-CMM_vlRP.js +263 -0
- package/dist/VideoSource-CMM_vlRP.js.map +1 -0
- package/dist/core/StereoScene.d.ts +16 -5
- package/dist/core.js +1 -1
- package/dist/three-vr-player.js +189 -143
- package/dist/three-vr-player.js.map +1 -1
- package/dist/three-vr-player.standalone.js +1043 -613
- package/dist/three-vr-player.standalone.js.map +1 -1
- package/dist/ui/ControlsUI.d.ts +6 -3
- package/package.json +5 -5
- package/dist/VideoSource-CJGIX8gL.js +0 -248
- package/dist/VideoSource-CJGIX8gL.js.map +0 -1
package/dist/three-vr-player.js
CHANGED
|
@@ -1,109 +1,134 @@
|
|
|
1
|
-
import { P as
|
|
2
|
-
import { M as
|
|
3
|
-
function
|
|
4
|
-
if (!Number.isFinite(
|
|
5
|
-
const t = Math.floor(
|
|
6
|
-
return s > 0 ? `${s}:${String(e).padStart(2, "0")}:${
|
|
1
|
+
import { P as X, V as Z, S as tt, L as et, a as st, b as it } from "./VideoSource-CMM_vlRP.js";
|
|
2
|
+
import { M as dt, c as ht, d as ut, i as vt } from "./VideoSource-CMM_vlRP.js";
|
|
3
|
+
function J(c) {
|
|
4
|
+
if (!Number.isFinite(c) || c < 0) return "0:00";
|
|
5
|
+
const t = Math.floor(c % 60), e = Math.floor(c / 60 % 60), s = Math.floor(c / 3600), a = String(t).padStart(2, "0");
|
|
6
|
+
return s > 0 ? `${s}:${String(e).padStart(2, "0")}:${a}` : `${e}:${a}`;
|
|
7
7
|
}
|
|
8
|
-
function o(
|
|
9
|
-
const s = document.createElement(
|
|
10
|
-
|
|
8
|
+
function o(c, t = {}, e = []) {
|
|
9
|
+
const s = document.createElement(c), { class: a, ...d } = t;
|
|
10
|
+
a && (s.className = a), Object.assign(s, d);
|
|
11
11
|
for (const u of e) s.append(u);
|
|
12
12
|
return s;
|
|
13
13
|
}
|
|
14
|
-
class
|
|
14
|
+
class ot {
|
|
15
15
|
constructor(t, e) {
|
|
16
16
|
this.nodes = [], this.disposers = [];
|
|
17
|
-
const s = e.video,
|
|
18
|
-
for (const i of
|
|
19
|
-
const
|
|
20
|
-
|
|
17
|
+
const s = e.video, a = o("button", { class: "tvp-btn tvp-play", title: "Play/Pause", textContent: "▶" }), d = o("input", { class: "tvp-seek", type: "range", min: "0", max: "1000", value: "0" }), u = o("span", { class: "tvp-time", textContent: "0:00 / 0:00" }), n = o("button", { class: "tvp-btn tvp-mute", title: "Volume", textContent: "🔊" }), m = o("input", { class: "tvp-volume", type: "range", min: "0", max: "1", step: "0.01", value: "1" }), g = o("div", { class: "tvp-volpopup", hidden: !0 }, [m]), _ = o("span", { class: "tvp-volwrap" }, [n, g]), y = o("button", { class: "tvp-btn tvp-vrbtn", title: "Enter VR", textContent: "🥽", hidden: !0 }), k = o("button", { class: "tvp-btn tvp-projbtn", title: "Projection", textContent: "🌐" }), h = o("div", { class: "tvp-projmenu", hidden: !0 });
|
|
18
|
+
for (const i of X) {
|
|
19
|
+
const r = o("button", { textContent: i.label });
|
|
20
|
+
r.dataset.mode = i.value, h.append(r);
|
|
21
21
|
}
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
o("label", {
|
|
22
|
+
const O = o("button", { textContent: "Off (native player)" });
|
|
23
|
+
O.dataset.mode = "off", h.append(o("hr", { class: "tvp-sep" }), O);
|
|
24
|
+
const H = o("span", { class: "tvp-projwrap" }, [k, h]), j = o("button", { class: "tvp-btn tvp-settingsbtn", title: "Settings", textContent: "⚙" }), A = o("button", { class: "tvp-btn tvp-fullscreen", title: "Fullscreen", textContent: "⛶" }), C = o("footer", { class: "tvp-controls" }, [a, d, u, _, y, H, j, A]), F = o("input", { type: "checkbox", checked: e.initial.swapEyes }), w = o("input", { type: "range", min: "30", max: "100", step: "1", value: String(e.initial.fov) }), T = o("span", { textContent: String(e.initial.fov) }), R = o("input", { type: "range", min: "1", max: "2", step: "0.25", value: String(e.initial.supersampling) }), I = o("span", { textContent: String(e.initial.supersampling) }), L = o("input", { type: "checkbox", checked: e.proxy.enabled }), V = o("input", { type: "text", value: e.proxy.url, placeholder: "http://localhost:8888", spellcheck: !1 }), N = o("input", { type: "password", value: e.proxy.apiPassword, placeholder: "API password" }), b = o("section", { class: "tvp-settings" }, [
|
|
25
|
+
o("label", { class: "row" }, [F, "Swap eyes (if depth looks wrong)"]),
|
|
26
|
+
o("label", {}, [W("Field of view (zoom): ", T, "°"), w]),
|
|
27
|
+
o("label", {}, [W("Supersampling: ", I, "× (sharpness)"), R]),
|
|
26
28
|
o("hr", { class: "tvp-sep" }),
|
|
27
|
-
o("label", { class: "row" }, [
|
|
28
|
-
o("label", {}, ["Proxy URL",
|
|
29
|
-
o("label", {}, ["API password",
|
|
30
|
-
]),
|
|
31
|
-
this.nodes.push(
|
|
29
|
+
o("label", { class: "row" }, [L, "Use CORS proxy"]),
|
|
30
|
+
o("label", {}, ["Proxy URL", V]),
|
|
31
|
+
o("label", {}, ["API password", N])
|
|
32
|
+
]), S = o("div", { class: "tvp-toast" });
|
|
33
|
+
this.nodes.push(C, b, S);
|
|
32
34
|
for (const i of this.nodes) t.append(i);
|
|
33
|
-
const
|
|
34
|
-
i.addEventListener(
|
|
35
|
-
},
|
|
36
|
-
|
|
35
|
+
const p = (i, r, l, v) => {
|
|
36
|
+
i.addEventListener(r, l, v), this.disposers.push(() => i.removeEventListener(r, l, v));
|
|
37
|
+
}, $ = (i) => d.style.setProperty("--seek", `${i}%`), E = () => {
|
|
38
|
+
g.hidden = !0, h.hidden = !0, b.classList.remove("open");
|
|
37
39
|
};
|
|
38
|
-
|
|
40
|
+
let B = 0;
|
|
41
|
+
const K = (i) => {
|
|
42
|
+
S.textContent = i, S.classList.add("show"), clearTimeout(B), B = window.setTimeout(() => S.classList.remove("show"), 4500);
|
|
43
|
+
}, f = (i, r) => {
|
|
44
|
+
let l = !1, v = -1e9;
|
|
45
|
+
const G = (x) => {
|
|
46
|
+
v = x.timeStamp, r(x);
|
|
47
|
+
};
|
|
48
|
+
p(i, "pointerdown", () => {
|
|
49
|
+
l = !0;
|
|
50
|
+
}), p(i, "pointercancel", () => {
|
|
51
|
+
l = !1;
|
|
52
|
+
}), p(i, "pointerup", (x) => {
|
|
53
|
+
l && (l = !1, G(x));
|
|
54
|
+
}), p(i, "click", (x) => {
|
|
55
|
+
x.timeStamp - v > 700 && G(x);
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
f(a, () => {
|
|
39
59
|
s.paused ? s.play() : s.pause();
|
|
40
|
-
}),
|
|
41
|
-
|
|
42
|
-
}),
|
|
43
|
-
|
|
44
|
-
}),
|
|
60
|
+
}), p(s, "play", () => {
|
|
61
|
+
a.textContent = "⏸";
|
|
62
|
+
}), p(s, "pause", () => {
|
|
63
|
+
a.textContent = "▶";
|
|
64
|
+
}), p(s, "timeupdate", () => {
|
|
45
65
|
if (s.duration) {
|
|
46
66
|
const i = s.currentTime / s.duration * 100;
|
|
47
|
-
|
|
67
|
+
d.value = String(i * 10), $(i), u.textContent = `${J(s.currentTime)} / ${J(s.duration)}`;
|
|
48
68
|
}
|
|
49
|
-
}),
|
|
50
|
-
|
|
51
|
-
}),
|
|
52
|
-
i.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
s.volume = Number(v.value), s.muted = s.volume === 0, r.textContent = s.muted ? "🔇" : "🔊";
|
|
69
|
+
}), p(d, "input", () => {
|
|
70
|
+
$(Number(d.value) / 10), s.duration && (s.currentTime = Number(d.value) / 1e3 * s.duration);
|
|
71
|
+
}), f(n, () => {
|
|
72
|
+
const i = g.hidden;
|
|
73
|
+
E(), g.hidden = !i;
|
|
74
|
+
}), p(m, "input", () => {
|
|
75
|
+
s.volume = Number(m.value), s.muted = s.volume === 0, n.textContent = s.muted ? "🔇" : "🔊";
|
|
57
76
|
});
|
|
58
|
-
const
|
|
77
|
+
const D = () => {
|
|
59
78
|
const i = e.getProjection();
|
|
60
|
-
let
|
|
61
|
-
h.querySelectorAll("button").forEach((
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
}),
|
|
79
|
+
let r = "Projection";
|
|
80
|
+
h.querySelectorAll("button").forEach((l) => {
|
|
81
|
+
const v = l.dataset.mode === i;
|
|
82
|
+
l.classList.toggle("active", v), v && (r = `Projection: ${l.textContent}`);
|
|
83
|
+
}), k.title = r;
|
|
65
84
|
};
|
|
66
|
-
|
|
67
|
-
i.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const i = Number(j.value);
|
|
82
|
-
A.textContent = String(i), e.setSupersampling(i);
|
|
85
|
+
f(k, () => {
|
|
86
|
+
const i = h.hidden;
|
|
87
|
+
E(), h.hidden = !i;
|
|
88
|
+
}), f(h, (i) => {
|
|
89
|
+
const r = i.target.closest("button[data-mode]");
|
|
90
|
+
r && (e.setProjection(r.dataset.mode), D(), h.hidden = !0);
|
|
91
|
+
}), D(), f(j, () => {
|
|
92
|
+
const i = !b.classList.contains("open");
|
|
93
|
+
E(), b.classList.toggle("open", i);
|
|
94
|
+
}), p(F, "change", () => e.setSwapEyes(F.checked)), p(w, "input", () => {
|
|
95
|
+
const i = Number(w.value);
|
|
96
|
+
T.textContent = String(i), e.setFov(i);
|
|
97
|
+
}), p(R, "input", () => {
|
|
98
|
+
const i = Number(R.value);
|
|
99
|
+
I.textContent = String(i), e.setSupersampling(i);
|
|
83
100
|
});
|
|
84
|
-
const
|
|
85
|
-
|
|
101
|
+
const z = () => e.setProxy({ url: V.value.trim(), apiPassword: N.value, enabled: L.checked });
|
|
102
|
+
p(L, "change", z), p(V, "change", z), p(N, "change", z), p(e.surface, "wheel", (i) => {
|
|
86
103
|
i.preventDefault();
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
}, { passive: !1 }),
|
|
90
|
-
var
|
|
104
|
+
const r = Math.max(30, Math.min(100, Number(w.value) + Math.sign(i.deltaY) * 3));
|
|
105
|
+
w.value = String(r), T.textContent = String(r), e.setFov(r);
|
|
106
|
+
}, { passive: !1 }), f(A, () => {
|
|
107
|
+
var r, l;
|
|
91
108
|
const i = e.fullscreenTarget;
|
|
92
|
-
document.fullscreenElement ? (
|
|
93
|
-
}),
|
|
94
|
-
const
|
|
95
|
-
[
|
|
109
|
+
document.fullscreenElement ? (l = document.exitFullscreen) == null || l.call(document) : (r = i.requestFullscreen) == null || r.call(i);
|
|
110
|
+
}), p(document, "pointerdown", (i) => {
|
|
111
|
+
const r = i.composedPath(), l = (v) => r.includes(v);
|
|
112
|
+
[g, n, h, k, b, j].some(l) || E();
|
|
96
113
|
});
|
|
97
|
-
let
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
},
|
|
101
|
-
|
|
114
|
+
let P = 0;
|
|
115
|
+
const Q = () => !g.hidden || !h.hidden || b.classList.contains("open"), U = () => {
|
|
116
|
+
Q() || C.classList.add("tvp-hidden");
|
|
117
|
+
}, M = () => {
|
|
118
|
+
C.classList.remove("tvp-hidden"), clearTimeout(P), P = window.setTimeout(U, 5e3);
|
|
102
119
|
};
|
|
103
|
-
|
|
104
|
-
clearTimeout(
|
|
105
|
-
}), this.disposers.push(() => clearTimeout(
|
|
106
|
-
|
|
120
|
+
p(e.fullscreenTarget, "pointermove", M), p(e.fullscreenTarget, "pointerdown", M), p(e.fullscreenTarget, "pointerleave", () => {
|
|
121
|
+
clearTimeout(P), U();
|
|
122
|
+
}), this.disposers.push(() => clearTimeout(P)), M(), e.vrSupported().then((i) => {
|
|
123
|
+
y.hidden = !i;
|
|
124
|
+
}), f(y, () => {
|
|
125
|
+
if (e.isPresenting()) {
|
|
126
|
+
e.exitVR();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
e.enterVR().catch((i) => K(i instanceof Error ? i.message : "Could not enter VR."));
|
|
130
|
+
}), e.onVrChange((i) => {
|
|
131
|
+
y.classList.toggle("active", i), y.title = i ? "Exit VR" : "Enter VR";
|
|
107
132
|
});
|
|
108
133
|
}
|
|
109
134
|
dispose() {
|
|
@@ -111,82 +136,89 @@ class X {
|
|
|
111
136
|
for (const t of this.nodes) t.remove();
|
|
112
137
|
}
|
|
113
138
|
}
|
|
114
|
-
function
|
|
139
|
+
function W(c, t, e) {
|
|
115
140
|
const s = document.createDocumentFragment();
|
|
116
|
-
return s.append(
|
|
141
|
+
return s.append(c, t, e), s;
|
|
117
142
|
}
|
|
118
|
-
const
|
|
119
|
-
class
|
|
143
|
+
const q = ":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-btn.active{color:#4f8cff}.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}", Y = "three-vr-player:settings";
|
|
144
|
+
class nt {
|
|
120
145
|
constructor(t, e = {}) {
|
|
121
|
-
var
|
|
122
|
-
this.source = new
|
|
146
|
+
var d, u;
|
|
147
|
+
this.source = new Z(), this.listeners = /* @__PURE__ */ new Map(), this.readyEmitted = !1, this.native = !1, this.tainted = !1, this.loading = !1, this.useProxy = !1, this.opts = e, this.proxyConfig = e.proxy, this.useProxy = !!e.proxy;
|
|
123
148
|
const s = e.persistSettings ? this.loadSettings() : null;
|
|
124
149
|
this.view = {
|
|
125
150
|
projection: e.projection ?? (s == null ? void 0 : s.projection) ?? "180-sbs",
|
|
126
151
|
swapEyes: e.swapEyes ?? (s == null ? void 0 : s.swapEyes) ?? !1,
|
|
127
152
|
fov: e.fov ?? (s == null ? void 0 : s.fov) ?? 70,
|
|
128
153
|
supersampling: e.supersampling ?? (s == null ? void 0 : s.supersampling) ?? 1.5
|
|
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);
|
|
130
|
-
let
|
|
154
|
+
}, this.displayMode = this.view.projection, 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);
|
|
155
|
+
let a;
|
|
131
156
|
if (e.shadowDom !== !1) {
|
|
132
|
-
const
|
|
133
|
-
|
|
157
|
+
const n = this.wrap.attachShadow({ mode: "open" }), m = document.createElement("style");
|
|
158
|
+
m.textContent = q, n.appendChild(m), a = n;
|
|
134
159
|
} else {
|
|
135
160
|
if (!document.getElementById("tvp-styles")) {
|
|
136
|
-
const
|
|
137
|
-
|
|
161
|
+
const n = document.createElement("style");
|
|
162
|
+
n.id = "tvp-styles", n.textContent = q, document.head.appendChild(n);
|
|
138
163
|
}
|
|
139
|
-
|
|
164
|
+
a = this.wrap;
|
|
140
165
|
}
|
|
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"),
|
|
166
|
+
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"), a.append(this.canvas, this.video), this.scene = new tt({
|
|
142
167
|
canvas: this.canvas,
|
|
143
168
|
video: this.video,
|
|
144
169
|
projection: this.view.projection,
|
|
145
170
|
swapEyes: this.view.swapEyes,
|
|
146
171
|
fov: this.view.fov,
|
|
147
172
|
supersampling: this.view.supersampling
|
|
148
|
-
}), this.look = new
|
|
173
|
+
}), this.look = new et(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 ot(a, {
|
|
149
174
|
video: this.video,
|
|
150
175
|
surface: this.canvas,
|
|
151
176
|
fullscreenTarget: this.wrap,
|
|
152
|
-
vrButton: this.scene.vrButton,
|
|
153
177
|
vrSupported: () => this.vrSupported(),
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
178
|
+
enterVR: () => this.enterVR(),
|
|
179
|
+
exitVR: () => this.scene.exitVR(),
|
|
180
|
+
isPresenting: () => this.scene.renderer.xr.isPresenting,
|
|
181
|
+
onVrChange: (n) => {
|
|
182
|
+
this.on("enterxr", () => n(!0)), this.on("exitxr", () => n(!1));
|
|
183
|
+
},
|
|
184
|
+
getProjection: () => this.displayMode,
|
|
185
|
+
setProjection: (n) => this.setProjection(n),
|
|
186
|
+
setSwapEyes: (n) => this.setSwapEyes(n),
|
|
187
|
+
setFov: (n) => this.setFov(n),
|
|
188
|
+
setSupersampling: (n) => this.setSupersampling(n),
|
|
159
189
|
initial: { swapEyes: this.view.swapEyes, fov: this.view.fov, supersampling: this.view.supersampling },
|
|
160
|
-
proxy: { url: ((
|
|
161
|
-
setProxy: (
|
|
190
|
+
proxy: { url: ((d = this.proxyConfig) == null ? void 0 : d.url) ?? "", apiPassword: ((u = this.proxyConfig) == null ? void 0 : u.apiPassword) ?? "", enabled: this.useProxy },
|
|
191
|
+
setProxy: (n) => this.setProxy(n)
|
|
162
192
|
})), 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", () => {
|
|
163
193
|
this.loading || this.emit("error", this.video.error);
|
|
164
194
|
}), this.video.addEventListener("loadedmetadata", () => {
|
|
165
195
|
this.readyEmitted || (this.readyEmitted = !0, this.emit("ready"));
|
|
166
|
-
}), this.scene.renderer.xr.addEventListener("sessionstart", () => this.emit("enterxr")), this.scene.renderer.xr.addEventListener("sessionend", () => this.emit("exitxr")),
|
|
196
|
+
}), this.scene.renderer.xr.addEventListener("sessionstart", () => this.emit("enterxr")), this.scene.renderer.xr.addEventListener("sessionend", () => this.emit("exitxr")), this.vrSupported().then((n) => {
|
|
197
|
+
n && this.scene.offerVR();
|
|
198
|
+
}), e.src && this.load(e.src, { projection: e.projection });
|
|
167
199
|
}
|
|
168
200
|
vrSupported() {
|
|
169
201
|
return this.opts.vrButton === !1 || !navigator.xr ? Promise.resolve(!1) : navigator.xr.isSessionSupported("immersive-vr").catch(() => !1);
|
|
170
202
|
}
|
|
171
203
|
async load(t, e = {}) {
|
|
172
204
|
this.currentSrc = t;
|
|
173
|
-
const s = e.projection ?? (this.opts.autoDetect !== !1 ?
|
|
174
|
-
s && this.
|
|
175
|
-
const { url:
|
|
205
|
+
const s = e.projection ?? (this.opts.autoDetect !== !1 ? st(t) : null);
|
|
206
|
+
s && this.applyProjectionGeometry(s), this.displayMode !== "off" && (this.displayMode = this.view.projection);
|
|
207
|
+
const { url: a, format: d } = it(t, this.useProxy ? this.proxyConfig : void 0), u = this.opts.crossOrigin === void 0 ? "anonymous" : this.opts.crossOrigin;
|
|
176
208
|
this.loading = !0;
|
|
177
209
|
try {
|
|
178
|
-
await this.source.attach(this.video, { url:
|
|
210
|
+
await this.source.attach(this.video, { url: a, format: d }, { crossOrigin: u }), this.tainted = !1, this.applyDisplay(), await this.video.play().catch(() => {
|
|
179
211
|
});
|
|
180
|
-
} catch (
|
|
181
|
-
if (this.opts.nativeFallback !== !1 &&
|
|
212
|
+
} catch (n) {
|
|
213
|
+
if (this.opts.nativeFallback !== !1 && d === "progressive" && u !== null)
|
|
182
214
|
try {
|
|
183
|
-
this.setNativeFallback(!0), await this.source.attach(this.video, { url:
|
|
215
|
+
this.tainted = !0, this.setNativeFallback(!0), await this.source.attach(this.video, { url: a, format: d }, { crossOrigin: null }), await this.video.play().catch(() => {
|
|
184
216
|
}), this.emit("fallback");
|
|
185
217
|
return;
|
|
186
|
-
} catch (
|
|
187
|
-
throw this.setNativeFallback(!1), this.emit("error",
|
|
218
|
+
} catch (m) {
|
|
219
|
+
throw this.tainted = !1, this.setNativeFallback(!1), this.emit("error", m), m;
|
|
188
220
|
}
|
|
189
|
-
throw this.setNativeFallback(!1), this.emit("error",
|
|
221
|
+
throw this.setNativeFallback(!1), this.emit("error", n), n;
|
|
190
222
|
} finally {
|
|
191
223
|
this.loading = !1;
|
|
192
224
|
}
|
|
@@ -210,8 +242,19 @@ class Z {
|
|
|
210
242
|
pause() {
|
|
211
243
|
this.video.pause();
|
|
212
244
|
}
|
|
245
|
+
/** Set the display mode: a geometry projection (WebGL 3D) or 'off' for plain 2D `<video>`. */
|
|
213
246
|
setProjection(t) {
|
|
214
|
-
|
|
247
|
+
if (t === "off") {
|
|
248
|
+
this.displayMode = "off", this.setNativeFallback(!0), this.emit("projectionchange", t);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this.displayMode = t, this.applyProjectionGeometry(t), this.tainted && this.currentSrc ? this.load(this.currentSrc) : this.setNativeFallback(!1), this.emit("projectionchange", t);
|
|
252
|
+
}
|
|
253
|
+
applyProjectionGeometry(t) {
|
|
254
|
+
this.scene.setProjection(t), this.look.setEnabled(!this.scene.isFlat()), this.look.reset(), this.view.projection = t, this.persist();
|
|
255
|
+
}
|
|
256
|
+
applyDisplay() {
|
|
257
|
+
this.setNativeFallback(this.displayMode === "off");
|
|
215
258
|
}
|
|
216
259
|
setSwapEyes(t) {
|
|
217
260
|
this.scene.setSwapEyes(t), this.view.swapEyes = t, this.persist();
|
|
@@ -226,10 +269,13 @@ class Z {
|
|
|
226
269
|
setProxy(t) {
|
|
227
270
|
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
271
|
}
|
|
272
|
+
/** Enter immersive VR. Rejects if the WebXR session request fails (e.g. no headset,
|
|
273
|
+
* or a non-secure origin) — the built-in controls surface the reason as a toast. */
|
|
229
274
|
async enterVR() {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
275
|
+
await this.scene.enterVR();
|
|
276
|
+
}
|
|
277
|
+
exitVR() {
|
|
278
|
+
this.scene.exitVR();
|
|
233
279
|
}
|
|
234
280
|
get three() {
|
|
235
281
|
return { renderer: this.scene.renderer, scene: this.scene.scene, camera: this.scene.camera };
|
|
@@ -244,18 +290,18 @@ class Z {
|
|
|
244
290
|
}
|
|
245
291
|
emit(t, e) {
|
|
246
292
|
var s;
|
|
247
|
-
(s = this.listeners.get(t)) == null || s.forEach((
|
|
293
|
+
(s = this.listeners.get(t)) == null || s.forEach((a) => a(e));
|
|
248
294
|
}
|
|
249
295
|
persist() {
|
|
250
296
|
if (this.opts.persistSettings)
|
|
251
297
|
try {
|
|
252
|
-
localStorage.setItem(
|
|
298
|
+
localStorage.setItem(Y, JSON.stringify(this.view));
|
|
253
299
|
} catch {
|
|
254
300
|
}
|
|
255
301
|
}
|
|
256
302
|
loadSettings() {
|
|
257
303
|
try {
|
|
258
|
-
const t = localStorage.getItem(
|
|
304
|
+
const t = localStorage.getItem(Y);
|
|
259
305
|
return t ? JSON.parse(t) : null;
|
|
260
306
|
} catch {
|
|
261
307
|
return null;
|
|
@@ -266,12 +312,12 @@ class Z {
|
|
|
266
312
|
(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();
|
|
267
313
|
}
|
|
268
314
|
}
|
|
269
|
-
class
|
|
315
|
+
class rt extends HTMLElement {
|
|
270
316
|
static get observedAttributes() {
|
|
271
317
|
return ["src", "projection"];
|
|
272
318
|
}
|
|
273
319
|
connectedCallback() {
|
|
274
|
-
this.player || (this.style.display || (this.style.display = "block"), this.player = new
|
|
320
|
+
this.player || (this.style.display || (this.style.display = "block"), this.player = new nt(this, {
|
|
275
321
|
src: this.getAttribute("src") ?? void 0,
|
|
276
322
|
projection: this.getAttribute("projection") ?? void 0,
|
|
277
323
|
controls: this.hasAttribute("controls"),
|
|
@@ -298,23 +344,23 @@ class tt extends HTMLElement {
|
|
|
298
344
|
return this.player;
|
|
299
345
|
}
|
|
300
346
|
}
|
|
301
|
-
function
|
|
302
|
-
typeof customElements < "u" && !customElements.get(
|
|
347
|
+
function at(c = "three-video") {
|
|
348
|
+
typeof customElements < "u" && !customElements.get(c) && customElements.define(c, rt);
|
|
303
349
|
}
|
|
304
|
-
|
|
350
|
+
at();
|
|
305
351
|
export {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
352
|
+
et as LookControls,
|
|
353
|
+
dt as MODES,
|
|
354
|
+
X as PROJECTIONS,
|
|
355
|
+
nt as Player,
|
|
356
|
+
tt as StereoScene,
|
|
357
|
+
rt as ThreeVideoElement,
|
|
358
|
+
Z as VideoSource,
|
|
359
|
+
it as buildProxyUrl,
|
|
360
|
+
ht as clampAngles,
|
|
361
|
+
ut as detectFormat,
|
|
362
|
+
st as detectProjection,
|
|
363
|
+
vt as isFlatMode,
|
|
364
|
+
at as registerWebComponent
|
|
319
365
|
};
|
|
320
366
|
//# sourceMappingURL=three-vr-player.js.map
|