@sangwonl/pocato-core 0.4.10 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +47 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2028,6 +2028,9 @@ var FaceRenderer = class {
|
|
|
2028
2028
|
this.loadedLayers = [];
|
|
2029
2029
|
this.layerLoadVersion = 0;
|
|
2030
2030
|
this.layerLoadAbort = null;
|
|
2031
|
+
this.videoActivationVersion = 0;
|
|
2032
|
+
this.videoActivationAbort = null;
|
|
2033
|
+
this.destroyed = false;
|
|
2031
2034
|
bootstrapShaders();
|
|
2032
2035
|
this.scene = new THREE3.Scene();
|
|
2033
2036
|
this.camera = new THREE3.Camera();
|
|
@@ -2078,6 +2081,9 @@ var FaceRenderer = class {
|
|
|
2078
2081
|
}
|
|
2079
2082
|
async loadLayers(layers, onError) {
|
|
2080
2083
|
const version = ++this.layerLoadVersion;
|
|
2084
|
+
this.videoActivationVersion++;
|
|
2085
|
+
this.videoActivationAbort?.abort();
|
|
2086
|
+
this.videoActivationAbort = null;
|
|
2081
2087
|
this.layerLoadAbort?.abort();
|
|
2082
2088
|
const abort = new AbortController();
|
|
2083
2089
|
this.layerLoadAbort = abort;
|
|
@@ -2117,16 +2123,25 @@ var FaceRenderer = class {
|
|
|
2117
2123
|
this.material.uniforms.uResolution.value.set(width, height);
|
|
2118
2124
|
}
|
|
2119
2125
|
async playLoadedVideos() {
|
|
2126
|
+
const activationVersion = ++this.videoActivationVersion;
|
|
2127
|
+
this.videoActivationAbort?.abort();
|
|
2128
|
+
const activationAbort = new AbortController();
|
|
2129
|
+
this.videoActivationAbort = activationAbort;
|
|
2120
2130
|
await Promise.all(this.loadedLayers.map(async (loaded, i) => {
|
|
2131
|
+
if (this.destroyed || activationAbort.signal.aborted || activationVersion !== this.videoActivationVersion) return;
|
|
2121
2132
|
if (!loaded.liveTexture) {
|
|
2122
2133
|
loaded.play?.();
|
|
2123
2134
|
return;
|
|
2124
2135
|
}
|
|
2125
2136
|
loaded.play?.();
|
|
2126
|
-
|
|
2137
|
+
const hasFrame = await waitForVideoFrame(loaded.videoEl, activationAbort.signal);
|
|
2138
|
+
if (hasFrame && !this.destroyed && !activationAbort.signal.aborted && activationVersion === this.videoActivationVersion) {
|
|
2127
2139
|
this.material.uniforms[`uLayer${i}`].value = loaded.liveTexture;
|
|
2128
2140
|
}
|
|
2129
2141
|
}));
|
|
2142
|
+
if (this.videoActivationAbort === activationAbort) {
|
|
2143
|
+
this.videoActivationAbort = null;
|
|
2144
|
+
}
|
|
2130
2145
|
}
|
|
2131
2146
|
updateShader(fragmentShader) {
|
|
2132
2147
|
this.material.fragmentShader = resolveIncludes(fragmentShader);
|
|
@@ -2144,7 +2159,11 @@ var FaceRenderer = class {
|
|
|
2144
2159
|
this.material.uniforms.uLayerCount.value = 0;
|
|
2145
2160
|
}
|
|
2146
2161
|
destroy() {
|
|
2162
|
+
this.destroyed = true;
|
|
2147
2163
|
this.layerLoadVersion++;
|
|
2164
|
+
this.videoActivationVersion++;
|
|
2165
|
+
this.videoActivationAbort?.abort();
|
|
2166
|
+
this.videoActivationAbort = null;
|
|
2148
2167
|
this.layerLoadAbort?.abort();
|
|
2149
2168
|
this.layerLoadAbort = null;
|
|
2150
2169
|
this.disposeLayers();
|
|
@@ -2152,17 +2171,37 @@ var FaceRenderer = class {
|
|
|
2152
2171
|
this.material.dispose();
|
|
2153
2172
|
}
|
|
2154
2173
|
};
|
|
2155
|
-
function waitForVideoFrame(video) {
|
|
2174
|
+
function waitForVideoFrame(video, signal) {
|
|
2156
2175
|
return new Promise((resolve) => {
|
|
2176
|
+
if (signal?.aborted) {
|
|
2177
|
+
resolve(false);
|
|
2178
|
+
return;
|
|
2179
|
+
}
|
|
2180
|
+
let settled = false;
|
|
2181
|
+
let timeoutId = null;
|
|
2182
|
+
let videoFrameId = null;
|
|
2183
|
+
const finish = (hasFrame) => {
|
|
2184
|
+
if (settled) return;
|
|
2185
|
+
settled = true;
|
|
2186
|
+
if (timeoutId != null) globalThis.clearTimeout(timeoutId);
|
|
2187
|
+
if (video && videoFrameId != null && "cancelVideoFrameCallback" in video) {
|
|
2188
|
+
video.cancelVideoFrameCallback(videoFrameId);
|
|
2189
|
+
}
|
|
2190
|
+
signal?.removeEventListener("abort", abort);
|
|
2191
|
+
resolve(hasFrame);
|
|
2192
|
+
};
|
|
2193
|
+
const abort = () => finish(false);
|
|
2157
2194
|
if (video && "requestVideoFrameCallback" in video) {
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
resolve(true);
|
|
2162
|
-
});
|
|
2195
|
+
timeoutId = globalThis.setTimeout(() => finish(false), VIDEO_FRAME_WAIT_TIMEOUT_MS);
|
|
2196
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
2197
|
+
videoFrameId = video.requestVideoFrameCallback(() => finish(true));
|
|
2163
2198
|
return;
|
|
2164
2199
|
}
|
|
2165
|
-
requestAnimationFrame(() =>
|
|
2200
|
+
const rafId2 = requestAnimationFrame(() => finish(true));
|
|
2201
|
+
signal?.addEventListener("abort", () => {
|
|
2202
|
+
cancelAnimationFrame(rafId2);
|
|
2203
|
+
finish(false);
|
|
2204
|
+
}, { once: true });
|
|
2166
2205
|
});
|
|
2167
2206
|
}
|
|
2168
2207
|
function toThreeUniformValue(value) {
|