@vosjs/studio-core 0.41.0 → 0.41.2
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.d.ts +10 -0
- package/dist/index.js +34 -25
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1800,6 +1800,16 @@ interface ProjectDoc {
|
|
|
1800
1800
|
frameW: number;
|
|
1801
1801
|
frameH: number;
|
|
1802
1802
|
};
|
|
1803
|
+
/**
|
|
1804
|
+
* The actions.json that recorded this take, as written (the resolved
|
|
1805
|
+
* url, every step with its id). It rides the document so the take can
|
|
1806
|
+
* be recorded again from wherever the document is: `vos push` embeds
|
|
1807
|
+
* it and `vos fetch --media` writes it back beside the recording. A
|
|
1808
|
+
* script never holds a secret by construction (a typed secret is an
|
|
1809
|
+
* env reference, a literal in a password field is refused), so it
|
|
1810
|
+
* travels as the cut does. Absent on a human recording.
|
|
1811
|
+
*/
|
|
1812
|
+
script?: Record<string, unknown>;
|
|
1803
1813
|
};
|
|
1804
1814
|
/**
|
|
1805
1815
|
* Kept SOURCE-time spans (@vosjs/timeline `Segment`s); the output timeline is
|
package/dist/index.js
CHANGED
|
@@ -1523,27 +1523,30 @@ function placeFreezes(rated, freezes) {
|
|
|
1523
1523
|
acc += Math.max(0, p.out - p.in) / (p.rate ?? 1);
|
|
1524
1524
|
};
|
|
1525
1525
|
for (let i = 0; i < rated.length; i++) {
|
|
1526
|
-
|
|
1526
|
+
const piece = rated[i];
|
|
1527
1527
|
const next = rated[i + 1];
|
|
1528
1528
|
const continues = !!next && sameMedia(next.media, piece.media) && Math.abs(next.in - piece.out) < 1e-9 && next.out > piece.out;
|
|
1529
1529
|
const mine = freezes.filter(
|
|
1530
1530
|
(f) => f.seconds > 0 && !placed.has(f.id) && sameMedia(f.media, piece.media) && f.at >= piece.in - 1e-9 && (continues ? f.at < piece.out - 1e-9 : f.at <= piece.out + 1e-9)
|
|
1531
1531
|
).sort((a, b) => a.at - b.at);
|
|
1532
|
+
const media = piece.media;
|
|
1533
|
+
let rest = piece;
|
|
1532
1534
|
for (const f of mine) {
|
|
1533
|
-
if (
|
|
1534
|
-
freezePiece(f,
|
|
1535
|
-
} else if (f.at
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1535
|
+
if (!rest) {
|
|
1536
|
+
freezePiece(f, media);
|
|
1537
|
+
} else if (f.at <= rest.in + 1e-9) {
|
|
1538
|
+
freezePiece(f, media);
|
|
1539
|
+
} else if (f.at < rest.out - 1e-9) {
|
|
1540
|
+
push2({ ...rest, out: f.at });
|
|
1541
|
+
freezePiece(f, media);
|
|
1542
|
+
rest = { ...rest, in: f.at };
|
|
1539
1543
|
} else {
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
piece = null;
|
|
1544
|
+
push2(rest);
|
|
1545
|
+
rest = null;
|
|
1543
1546
|
freezePiece(f, media);
|
|
1544
1547
|
}
|
|
1545
1548
|
}
|
|
1546
|
-
if (
|
|
1549
|
+
if (rest) push2(rest);
|
|
1547
1550
|
}
|
|
1548
1551
|
return { pieces, marks };
|
|
1549
1552
|
}
|
|
@@ -5061,26 +5064,32 @@ var STUDIO_SETUP = `async (ctx) => {
|
|
|
5061
5064
|
fontCache.set(oc.asset.url, font)
|
|
5062
5065
|
} catch (e) { console.warn('[voila] typeface failed to load', oc.asset.url, e) }
|
|
5063
5066
|
}
|
|
5064
|
-
// Audio clips (music/SFX):
|
|
5065
|
-
//
|
|
5066
|
-
//
|
|
5067
|
+
// Audio clips (music/SFX): start decoding into the shared cache now, but
|
|
5068
|
+
// never hold the first frame for it. Playback starts on a press, so the
|
|
5069
|
+
// decodes almost always land first; one that lands later clears the
|
|
5070
|
+
// scheduler's signature and the next playing frame schedules it at the
|
|
5071
|
+
// right offset (the onFrame path does the same for clips added later).
|
|
5072
|
+
// Exports never read this cache: they mix offline. The AudioContext starts
|
|
5073
|
+
// suspended (autoplay policy); onFrame resumes it on the first play.
|
|
5074
|
+
// Failures degrade to a silent clip.
|
|
5067
5075
|
const clips = ctx.data.audio || []
|
|
5068
5076
|
if (clips.length && window.AudioContext) {
|
|
5069
5077
|
const actx = ns.audioCtx || (ns.audioCtx = new window.AudioContext())
|
|
5070
5078
|
const bufs = ns.audioBuffers || (ns.audioBuffers = new Map())
|
|
5071
5079
|
const pend = ns.audioPending || (ns.audioPending = new Set())
|
|
5072
|
-
|
|
5073
|
-
if (bufs.has(c.key) || pend.has(c.key))
|
|
5080
|
+
for (const c of clips) {
|
|
5081
|
+
if (bufs.has(c.key) || pend.has(c.key)) continue
|
|
5074
5082
|
pend.add(c.key)
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5083
|
+
fetch(c.key)
|
|
5084
|
+
.then((res) => res.arrayBuffer())
|
|
5085
|
+
.then((ab) => actx.decodeAudioData(ab))
|
|
5086
|
+
.then((b) => {
|
|
5087
|
+
bufs.set(c.key, b)
|
|
5088
|
+
if (ns.audioSched) ns.audioSched.sig = ''
|
|
5089
|
+
})
|
|
5090
|
+
.catch((e) => console.warn('[voila] audio decode failed', c.key, e))
|
|
5091
|
+
.then(() => pend.delete(c.key))
|
|
5092
|
+
}
|
|
5084
5093
|
}
|
|
5085
5094
|
}`;
|
|
5086
5095
|
var STUDIO_CONTENT = `(ctx) => {
|