pixi-effects 0.26.2 → 0.26.3
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/CHANGELOG.md +12 -0
- package/README.md +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/render.mjs +16 -11
- package/dist/Composition-3O7L2VL5.js +7 -0
- package/dist/{Composition-H4QA24MV.js.map → Composition-3O7L2VL5.js.map} +1 -1
- package/dist/Composition-EE3KEE2L.cjs +16 -0
- package/dist/{Composition-HM4YT5L7.cjs.map → Composition-EE3KEE2L.cjs.map} +1 -1
- package/dist/Controller.d.cts +1 -1
- package/dist/Controller.d.ts +1 -1
- package/dist/{Movie-i05Oh9mJ.d.cts → Movie-BWLLWRRe.d.cts} +10 -3
- package/dist/{Movie-DVeDTdnc.d.ts → Movie-BkP82KXS.d.ts} +10 -3
- package/dist/Presenter.d.cts +1 -1
- package/dist/Presenter.d.ts +1 -1
- package/dist/{chunk-WPXDRSGN.cjs → chunk-A225HYSY.cjs} +205 -27
- package/dist/chunk-A225HYSY.cjs.map +1 -0
- package/dist/{chunk-X3HB4DSR.js → chunk-FXAHNPBP.js} +205 -27
- package/dist/chunk-FXAHNPBP.js.map +1 -0
- package/dist/{chunk-555URQHQ.cjs → chunk-IIDBEYQH.cjs} +59 -59
- package/dist/{chunk-555URQHQ.cjs.map → chunk-IIDBEYQH.cjs.map} +1 -1
- package/dist/{chunk-GBUM7X2S.js → chunk-WMMZDPWK.js} +3 -3
- package/dist/{chunk-GBUM7X2S.js.map → chunk-WMMZDPWK.js.map} +1 -1
- package/dist/index.cjs +142 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +119 -25
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/three.cjs +5 -5
- package/dist/three.js +1 -1
- package/docs/api.md +11 -5
- package/docs/dsl.md +2 -0
- package/llms-full.txt +17 -9
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +1 -1
- package/skills/pixi-effects/reference/cheatsheet.md +3 -3
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Composition-H4QA24MV.js +0 -7
- package/dist/Composition-HM4YT5L7.cjs +0 -16
- package/dist/chunk-WPXDRSGN.cjs.map +0 -1
- package/dist/chunk-X3HB4DSR.js.map +0 -1
|
@@ -394,19 +394,29 @@ function evaluateExpr(source, scope) {
|
|
|
394
394
|
// src/expr/normalizeProps.ts
|
|
395
395
|
function normalizeProps(input, scope, options = {}) {
|
|
396
396
|
const skip = new Set(options.skipKeys ?? []);
|
|
397
|
-
return walk(input, scope, skip, null);
|
|
397
|
+
return walk(input, scope, skip, null, options);
|
|
398
398
|
}
|
|
399
|
-
|
|
399
|
+
var RELATIVE = /^\s*([+-])=([\s\S]*)$/;
|
|
400
|
+
function walk(value, scope, skip, currentKey, options) {
|
|
400
401
|
if (Array.isArray(value)) {
|
|
401
|
-
return value.map((v) => walk(v, scope, skip, currentKey));
|
|
402
|
+
return value.map((v) => walk(v, scope, skip, currentKey, options));
|
|
402
403
|
}
|
|
403
404
|
if (value !== null && typeof value === "object") {
|
|
404
405
|
const out = {};
|
|
405
406
|
for (const k of Object.keys(value)) {
|
|
406
|
-
out[k] = walk(value[k], scope, skip, k);
|
|
407
|
+
out[k] = walk(value[k], scope, skip, k, options);
|
|
407
408
|
}
|
|
408
409
|
return out;
|
|
409
410
|
}
|
|
411
|
+
if (typeof value === "string" && !(currentKey !== null && skip.has(currentKey))) {
|
|
412
|
+
const rel = RELATIVE.exec(value);
|
|
413
|
+
if (rel) {
|
|
414
|
+
const n = evaluateExpr(rel[2].trim(), scope);
|
|
415
|
+
if (options.relative === "allow") return `${rel[1]}=${n}`;
|
|
416
|
+
console.warn(`pixi-effects: "${value.trim()}"${currentKey ? ` (${currentKey})` : ""} is a relative value (measured from where the layer is): it works in a keyframe's to / from / set, not in ${options.where ?? "an initial or a style"}; it is read as the number ${rel[1] === "-" ? -n : n}`);
|
|
417
|
+
return rel[1] === "-" ? -n : n;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
410
420
|
if (isExpr(value) && !(currentKey !== null && skip.has(currentKey))) {
|
|
411
421
|
if (looksLikeColorString(value)) return value;
|
|
412
422
|
return evaluateExpr(value, scope);
|
|
@@ -637,7 +647,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
637
647
|
const kf = normalizeKeyframe(raw, parentDuration);
|
|
638
648
|
const at = offset + kf.at;
|
|
639
649
|
if (kf.kind === "set") {
|
|
640
|
-
const resolved = normalizeProps(kf.set, scope, { skipKeys });
|
|
650
|
+
const resolved = normalizeProps(kf.set, scope, { skipKeys, relative: "allow" });
|
|
641
651
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
642
652
|
for (const r of routed) timeline.set(r.target, { [r.prop]: r.value }, at);
|
|
643
653
|
const { ownProps, filterProps } = partitionProps(rest);
|
|
@@ -648,7 +658,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
648
658
|
timeline.set(f, props, at);
|
|
649
659
|
}
|
|
650
660
|
} else if (kf.kind === "to") {
|
|
651
|
-
const resolved = normalizeProps(kf.to, scope, { skipKeys });
|
|
661
|
+
const resolved = normalizeProps(kf.to, scope, { skipKeys, relative: "allow" });
|
|
652
662
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
653
663
|
for (const r of routed)
|
|
654
664
|
timeline.to(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
@@ -661,7 +671,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
661
671
|
timeline.to(f, { ...props, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
662
672
|
}
|
|
663
673
|
} else if (kf.kind === "from") {
|
|
664
|
-
const resolved = normalizeProps(kf.from, scope, { skipKeys });
|
|
674
|
+
const resolved = normalizeProps(kf.from, scope, { skipKeys, relative: "allow" });
|
|
665
675
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
666
676
|
for (const r of routed)
|
|
667
677
|
timeline.from(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
@@ -674,8 +684,8 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
674
684
|
timeline.from(f, { ...props, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
675
685
|
}
|
|
676
686
|
} else {
|
|
677
|
-
const fromResolved = normalizeProps(kf.from, scope, { skipKeys });
|
|
678
|
-
const toResolved = normalizeProps(kf.to, scope, { skipKeys });
|
|
687
|
+
const fromResolved = normalizeProps(kf.from, scope, { skipKeys, where: "the from side of a from + to keyframe" });
|
|
688
|
+
const toResolved = normalizeProps(kf.to, scope, { skipKeys, relative: "allow" });
|
|
679
689
|
const fromRouted = splitRouted(fromResolved, routers);
|
|
680
690
|
const toRouted = splitRouted(toResolved, routers);
|
|
681
691
|
const fromByKey = new Map(fromRouted.routed.map((r) => [r.key, r]));
|
|
@@ -725,7 +735,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
725
735
|
}
|
|
726
736
|
function applyInitial(target, initial, scope, skipKeys = [], routers) {
|
|
727
737
|
if (!initial) return;
|
|
728
|
-
const resolved = normalizeProps(initial, scope, { skipKeys });
|
|
738
|
+
const resolved = normalizeProps(initial, scope, { skipKeys, where: "initial" });
|
|
729
739
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
730
740
|
for (const r of routed) gsap.gsap.set(r.target, { [r.prop]: r.value });
|
|
731
741
|
const { ownProps, filterProps } = partitionProps(rest);
|
|
@@ -3067,6 +3077,9 @@ var BUDGET_BYTES = 96 * 1024 * 1024;
|
|
|
3067
3077
|
var MIN_HELD = 3;
|
|
3068
3078
|
var JUMP_SECONDS = 1;
|
|
3069
3079
|
var EPS = 1e-6;
|
|
3080
|
+
var LOW_BEHIND = 14;
|
|
3081
|
+
var MIN_HELD_TO_READ_BACK = 20;
|
|
3082
|
+
var MIN_HELD_TO_READ_START = 9;
|
|
3070
3083
|
function reportDecodeError(err, time) {
|
|
3071
3084
|
const isTransient = err instanceof DOMException && (err.name === "EncodingError" || err.name === "NotSupportedError");
|
|
3072
3085
|
if (isTransient) console.debug("pixi-effects: transient video decode failure at", time, "s \u2014", err.name);
|
|
@@ -3085,9 +3098,22 @@ var FrameCache = class {
|
|
|
3085
3098
|
_held = 0;
|
|
3086
3099
|
_lock = Promise.resolve();
|
|
3087
3100
|
_lastTime = null;
|
|
3101
|
+
_dir = 0;
|
|
3102
|
+
_gen = 0;
|
|
3103
|
+
_backBusy = false;
|
|
3104
|
+
_backGen = 0;
|
|
3105
|
+
_standbyBusy = false;
|
|
3106
|
+
/** A second pass at the start of the file, ready for the moment a looping video comes round. */
|
|
3107
|
+
_standby = null;
|
|
3108
|
+
_duration;
|
|
3109
|
+
_loop;
|
|
3110
|
+
/** How often it had to wait for a decoder (`restarts`, `singles`) and how many reads ahead it made: for tests and for `check`. */
|
|
3111
|
+
stats = { restarts: 0, singles: 0, prefetches: 0 };
|
|
3088
3112
|
constructor(sink, options = {}) {
|
|
3089
3113
|
this.sink = sink;
|
|
3090
3114
|
this.capacity = options.capacity ?? 30;
|
|
3115
|
+
this._duration = options.duration ?? null;
|
|
3116
|
+
this._loop = !!options.loop;
|
|
3091
3117
|
}
|
|
3092
3118
|
/** How many decoded frames are held right now (the sequential reader's own list, plus the exact-time cache of the old path). */
|
|
3093
3119
|
get heldFrames() {
|
|
@@ -3157,24 +3183,157 @@ var FrameCache = class {
|
|
|
3157
3183
|
return null;
|
|
3158
3184
|
}
|
|
3159
3185
|
async _sequentialAt(time) {
|
|
3186
|
+
const last = this._lastTime;
|
|
3187
|
+
this._lastTime = time;
|
|
3188
|
+
if (last !== null && Math.abs(time - last) <= JUMP_SECONDS) this._dir = time > last + EPS ? 1 : time < last - EPS ? -1 : this._dir;
|
|
3189
|
+
let frame;
|
|
3160
3190
|
try {
|
|
3161
|
-
|
|
3162
|
-
this._lastTime = time;
|
|
3163
|
-
const hit = this._covering(time);
|
|
3164
|
-
if (hit) return hit.frame;
|
|
3165
|
-
if (last === null || Math.abs(time - last) > JUMP_SECONDS) return await this._single(time);
|
|
3166
|
-
const cur = this._cur;
|
|
3167
|
-
if (this._iter && cur && time >= cur.ts && time - cur.ts <= JUMP_SECONDS) return await this._advance(time);
|
|
3168
|
-
const backwards = !!cur && time < cur.ts;
|
|
3169
|
-
return await this._restart(time, backwards ? Math.max(0, time - this._held / 30) : time);
|
|
3191
|
+
frame = await this._serve(time, last);
|
|
3170
3192
|
} catch (err) {
|
|
3171
3193
|
reportDecodeError(err, time);
|
|
3172
3194
|
await this._closeIter();
|
|
3173
3195
|
return null;
|
|
3174
3196
|
}
|
|
3197
|
+
this._maybeReadAhead(time);
|
|
3198
|
+
return frame;
|
|
3199
|
+
}
|
|
3200
|
+
async _serve(time, last) {
|
|
3201
|
+
const hit = this._covering(time);
|
|
3202
|
+
if (hit) return hit.frame;
|
|
3203
|
+
const sb = this._standby;
|
|
3204
|
+
if (sb && time >= sb.cur.ts - EPS && time - sb.cur.ts <= JUMP_SECONDS && (!this._iter || !this._cur || this._cur.ts > time + JUMP_SECONDS)) return await this._adoptStandby(time);
|
|
3205
|
+
if (last === null || Math.abs(time - last) > JUMP_SECONDS) return await this._single(time);
|
|
3206
|
+
const cur = this._cur;
|
|
3207
|
+
if (this._iter && cur && time >= cur.ts && time - cur.ts <= JUMP_SECONDS) return await this._advance(time);
|
|
3208
|
+
const backwards = !!cur && time < cur.ts;
|
|
3209
|
+
return await this._restart(time, backwards ? Math.max(0, time - Math.max(1, this._held - 1) / 30) : time);
|
|
3210
|
+
}
|
|
3211
|
+
// ── reading ahead ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
3212
|
+
_maybeReadAhead(time) {
|
|
3213
|
+
if (this._held === 0) return;
|
|
3214
|
+
if (this._dir === -1) {
|
|
3215
|
+
this._dropStandby();
|
|
3216
|
+
let behind = 0, passed = 0, earliest = Infinity;
|
|
3217
|
+
for (const e of this._frames) {
|
|
3218
|
+
if (e.ts < time - EPS) behind++;
|
|
3219
|
+
else if (e.ts > time + EPS) passed++;
|
|
3220
|
+
if (e.ts < earliest) earliest = e.ts;
|
|
3221
|
+
}
|
|
3222
|
+
if (this._held >= MIN_HELD_TO_READ_BACK && behind < LOW_BEHIND && passed >= 3 && earliest > EPS && !this._backBusy) void this._readBack(earliest, passed);
|
|
3223
|
+
} else if (this._held >= MIN_HELD_TO_READ_START && this._dir === 1 && this._loop && this._duration !== null && time >= this._duration - JUMP_SECONDS && !this._standby && !this._standbyBusy) {
|
|
3224
|
+
void this._readStart();
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
/** In the background: the window of frames before the earliest one held (reverse play comes to it next). */
|
|
3228
|
+
async _readBack(earliest, room) {
|
|
3229
|
+
this._backBusy = true;
|
|
3230
|
+
this.stats.prefetches++;
|
|
3231
|
+
const gen = this._gen, bg = this._backGen;
|
|
3232
|
+
const want = Math.max(3, Math.min(Math.floor(this._held * 0.6), room));
|
|
3233
|
+
let iter = null;
|
|
3234
|
+
const got = [];
|
|
3235
|
+
try {
|
|
3236
|
+
iter = this.sink.samples(Math.max(0, earliest - want / 30));
|
|
3237
|
+
for (; ; ) {
|
|
3238
|
+
const r = await iter.next();
|
|
3239
|
+
if (r.done) break;
|
|
3240
|
+
if (gen !== this._gen || r.value.timestamp >= earliest - EPS) {
|
|
3241
|
+
r.value.close?.();
|
|
3242
|
+
break;
|
|
3243
|
+
}
|
|
3244
|
+
got.push(r.value);
|
|
3245
|
+
if (bg !== this._backGen) break;
|
|
3246
|
+
}
|
|
3247
|
+
if (gen === this._gen && bg === this._backGen) {
|
|
3248
|
+
for (let k = 0; k < got.length; k++) {
|
|
3249
|
+
const s = got[k];
|
|
3250
|
+
const frame = s.toVideoFrame();
|
|
3251
|
+
this._keep({ ts: s.timestamp, end: got[k + 1]?.timestamp ?? earliest, frame }, frame);
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
} catch (err) {
|
|
3255
|
+
reportDecodeError(err, earliest);
|
|
3256
|
+
} finally {
|
|
3257
|
+
for (const s of got) s.close?.();
|
|
3258
|
+
this._backBusy = false;
|
|
3259
|
+
try {
|
|
3260
|
+
await iter?.return?.(void 0);
|
|
3261
|
+
} catch {
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
/** In the background: the first frames of the file and a pass that stands behind them; held (pinned) until the loop comes round. */
|
|
3266
|
+
async _readStart() {
|
|
3267
|
+
this._standbyBusy = true;
|
|
3268
|
+
this.stats.prefetches++;
|
|
3269
|
+
const gen = this._gen;
|
|
3270
|
+
const want = Math.max(3, Math.min(10, Math.floor(this._held / 3)));
|
|
3271
|
+
let iter = null;
|
|
3272
|
+
const got = [];
|
|
3273
|
+
let keep = false;
|
|
3274
|
+
try {
|
|
3275
|
+
iter = this.sink.samples(0);
|
|
3276
|
+
for (; got.length < want + 1; ) {
|
|
3277
|
+
const r = await iter.next();
|
|
3278
|
+
if (r.done) break;
|
|
3279
|
+
if (gen !== this._gen) {
|
|
3280
|
+
r.value.close?.();
|
|
3281
|
+
break;
|
|
3282
|
+
}
|
|
3283
|
+
got.push(r.value);
|
|
3284
|
+
}
|
|
3285
|
+
if (gen === this._gen && got.length >= 2) {
|
|
3286
|
+
const next = got.pop();
|
|
3287
|
+
let cur = null;
|
|
3288
|
+
got.forEach((s, k) => {
|
|
3289
|
+
const frame = s.toVideoFrame();
|
|
3290
|
+
s.close?.();
|
|
3291
|
+
const entry = { ts: s.timestamp, end: (got[k + 1] ?? next).timestamp, frame, pinned: true };
|
|
3292
|
+
this._keep(entry, frame);
|
|
3293
|
+
cur = entry;
|
|
3294
|
+
});
|
|
3295
|
+
got.length = 0;
|
|
3296
|
+
if (cur) {
|
|
3297
|
+
this._standby = { iter, cur, next };
|
|
3298
|
+
keep = true;
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
} catch (err) {
|
|
3302
|
+
reportDecodeError(err, 0);
|
|
3303
|
+
} finally {
|
|
3304
|
+
for (const s of got) s.close?.();
|
|
3305
|
+
this._standbyBusy = false;
|
|
3306
|
+
if (!keep) {
|
|
3307
|
+
try {
|
|
3308
|
+
await iter?.return?.(void 0);
|
|
3309
|
+
} catch {
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
async _adoptStandby(time) {
|
|
3315
|
+
const sb = this._standby;
|
|
3316
|
+
this._standby = null;
|
|
3317
|
+
await this._closeIter();
|
|
3318
|
+
for (const e of this._frames) e.pinned = false;
|
|
3319
|
+
this._iter = sb.iter;
|
|
3320
|
+
this._next = sb.next;
|
|
3321
|
+
this._cur = sb.cur;
|
|
3322
|
+
return this._advance(time);
|
|
3323
|
+
}
|
|
3324
|
+
_dropStandby() {
|
|
3325
|
+
const sb = this._standby;
|
|
3326
|
+
if (!sb) return;
|
|
3327
|
+
this._standby = null;
|
|
3328
|
+
sb.next?.close?.();
|
|
3329
|
+
for (const e of this._frames.filter((x) => x.pinned)) {
|
|
3330
|
+
e.pinned = false;
|
|
3331
|
+
}
|
|
3332
|
+
void sb.iter.return?.(void 0);
|
|
3175
3333
|
}
|
|
3176
3334
|
/** One frame by itself (a seek): getSample, kept so that asking again for the same time costs nothing. The running pass, if any, is closed: it no longer follows the playhead. */
|
|
3177
3335
|
async _single(time) {
|
|
3336
|
+
this.stats.singles++;
|
|
3178
3337
|
await this._closeIter();
|
|
3179
3338
|
this._cur = null;
|
|
3180
3339
|
const sample = await this.sink.getSample(time);
|
|
@@ -3186,6 +3345,8 @@ var FrameCache = class {
|
|
|
3186
3345
|
}
|
|
3187
3346
|
/** Start a pass at `time` (a seek and the frames of one group of pictures), keeping what is still held for a step back. */
|
|
3188
3347
|
async _restart(time, from = time) {
|
|
3348
|
+
this.stats.restarts++;
|
|
3349
|
+
this._backGen++;
|
|
3189
3350
|
await this._closeIter();
|
|
3190
3351
|
this._cur = null;
|
|
3191
3352
|
const iter = this.sink.samples(from);
|
|
@@ -3249,12 +3410,27 @@ var FrameCache = class {
|
|
|
3249
3410
|
}
|
|
3250
3411
|
this._frames.push(entry);
|
|
3251
3412
|
while (this._frames.length > this._held) {
|
|
3252
|
-
const
|
|
3253
|
-
if (!
|
|
3254
|
-
this._frames.splice(this._frames.indexOf(
|
|
3255
|
-
|
|
3413
|
+
const victim = this._victim(entry);
|
|
3414
|
+
if (!victim) break;
|
|
3415
|
+
this._frames.splice(this._frames.indexOf(victim), 1);
|
|
3416
|
+
victim.frame.close?.();
|
|
3256
3417
|
}
|
|
3257
3418
|
}
|
|
3419
|
+
/**
|
|
3420
|
+
* The frame to let go: one the playhead has already passed (going forward those before it, going back those after it), the furthest
|
|
3421
|
+
* behind first; when there is none, the one furthest ahead of the playhead (the last to be needed). Least recently used when the
|
|
3422
|
+
* direction is not known. Frames of the standby (pinned) and the frame the pass stands on are never chosen.
|
|
3423
|
+
*/
|
|
3424
|
+
_victim(except) {
|
|
3425
|
+
const cand = this._frames.filter((e) => e !== this._cur && e !== except && !e.pinned);
|
|
3426
|
+
if (cand.length === 0) return null;
|
|
3427
|
+
if (this._dir === 0) return cand[0];
|
|
3428
|
+
const at = this._lastTime ?? 0;
|
|
3429
|
+
const passed = cand.filter((e) => this._dir === 1 ? e.ts < at - EPS : e.ts > at + EPS);
|
|
3430
|
+
const farthest = (list, sign) => list.reduce((a, b) => sign * (b.ts - a.ts) > 0 ? b : a);
|
|
3431
|
+
if (passed.length) return farthest(passed, this._dir === 1 ? -1 : 1);
|
|
3432
|
+
return farthest(cand, this._dir === 1 ? 1 : -1);
|
|
3433
|
+
}
|
|
3258
3434
|
async _closeIter() {
|
|
3259
3435
|
const iter = this._iter;
|
|
3260
3436
|
this._iter = null;
|
|
@@ -3277,6 +3453,8 @@ var FrameCache = class {
|
|
|
3277
3453
|
}
|
|
3278
3454
|
}
|
|
3279
3455
|
dispose() {
|
|
3456
|
+
this._gen++;
|
|
3457
|
+
this._dropStandby();
|
|
3280
3458
|
for (const f of this.cache.values()) f?.close?.();
|
|
3281
3459
|
this.cache.clear();
|
|
3282
3460
|
this._pending.clear();
|
|
@@ -3318,7 +3496,7 @@ var VideoSequence = class extends Sequence {
|
|
|
3318
3496
|
this._sourceDuration = data.duration;
|
|
3319
3497
|
this._remap = remapOf(this.spec, "currentTime", this._sourceDuration);
|
|
3320
3498
|
this._audioBuffer = this.spec.audio !== false ? data.audioBuffer : null;
|
|
3321
|
-
this._cache = new FrameCache(data.sink, { capacity: 30 });
|
|
3499
|
+
this._cache = new FrameCache(data.sink, { capacity: 30, duration: data.duration, loop: !!this.spec.loop });
|
|
3322
3500
|
const probeFrame = await this._cache.getFrameAt(0);
|
|
3323
3501
|
const w = probeFrame?.displayWidth ?? 1920;
|
|
3324
3502
|
const h = probeFrame?.displayHeight ?? 1080;
|
|
@@ -4518,7 +4696,7 @@ function resolveDim(v, scope) {
|
|
|
4518
4696
|
var _CompositionSequence = null;
|
|
4519
4697
|
async function getCompositionSequence() {
|
|
4520
4698
|
if (!_CompositionSequence) {
|
|
4521
|
-
_CompositionSequence = (await import('./Composition-
|
|
4699
|
+
_CompositionSequence = (await import('./Composition-EE3KEE2L.cjs')).CompositionSequence;
|
|
4522
4700
|
}
|
|
4523
4701
|
return _CompositionSequence;
|
|
4524
4702
|
}
|
|
@@ -4603,5 +4781,5 @@ exports.registerSequenceType = registerSequenceType;
|
|
|
4603
4781
|
exports.remapOf = remapOf;
|
|
4604
4782
|
exports.resolveAt = resolveAt;
|
|
4605
4783
|
exports.timeRemapOf = timeRemapOf;
|
|
4606
|
-
//# sourceMappingURL=chunk-
|
|
4607
|
-
//# sourceMappingURL=chunk-
|
|
4784
|
+
//# sourceMappingURL=chunk-A225HYSY.cjs.map
|
|
4785
|
+
//# sourceMappingURL=chunk-A225HYSY.cjs.map
|