@vosjs/studio-core 0.35.4 → 0.36.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/dist/index.js +64 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -6396,6 +6396,21 @@ var FRAME_STEP_SRC = `
|
|
|
6396
6396
|
}
|
|
6397
6397
|
function stepBg(bgEl, bgT) {
|
|
6398
6398
|
if (!bgEl.paused) bgEl.pause()
|
|
6399
|
+
// Capture pages: the loop's frame by PTS from its own provider, like the
|
|
6400
|
+
// footage. The loop clock only moves forward between wraps, so the walk
|
|
6401
|
+
// stays sequential and a wrap is one re-seek to the keyframe at 0.
|
|
6402
|
+
var bwc = bgEl.__voilaWc
|
|
6403
|
+
if (bwc) {
|
|
6404
|
+
var bwT = Math.min(bgT, bwc.duration || bgT)
|
|
6405
|
+
if (bwc.req !== bwT) {
|
|
6406
|
+
var bwp = bwc.seek(bwT)
|
|
6407
|
+
if (ns.pendingDecodes) {
|
|
6408
|
+
ns.pendingDecodes.add(bwp)
|
|
6409
|
+
bwp.finally(function () { ns.pendingDecodes.delete(bwp) })
|
|
6410
|
+
}
|
|
6411
|
+
}
|
|
6412
|
+
return
|
|
6413
|
+
}
|
|
6399
6414
|
var bgTarget = Math.min(bgT, bgEl.duration || bgT)
|
|
6400
6415
|
if (bgEl.readyState >= 1 && !bgEl.seeking && Math.abs(bgEl.currentTime - bgTarget) > 0.02) {
|
|
6401
6416
|
if (ns.pendingDecodes) {
|
|
@@ -6479,6 +6494,7 @@ var SETUP = `async (ctx) => {
|
|
|
6479
6494
|
// page has a memory budget) and FAIL-OPEN: any fetch trouble degrades to
|
|
6480
6495
|
// the plain network element, never a dead LOAD.
|
|
6481
6496
|
const BLOB_FETCH_MAX = 400 * 1024 * 1024
|
|
6497
|
+
const BG_BLOB_MAX = 64 * 1024 * 1024
|
|
6482
6498
|
const toBlobUrl = async (src) => {
|
|
6483
6499
|
const resp = await fetch(src)
|
|
6484
6500
|
if (!resp.ok) throw new Error('[voila] blob fetch HTTP ' + resp.status)
|
|
@@ -6679,9 +6695,48 @@ var SETUP = `async (ctx) => {
|
|
|
6679
6695
|
if (bgm && bgm.key) {
|
|
6680
6696
|
try {
|
|
6681
6697
|
if (bgm.kind === 'image') await loadImage(bgm.key)
|
|
6682
|
-
else
|
|
6698
|
+
else {
|
|
6699
|
+
const bgV = await load(bgm.key, true)
|
|
6700
|
+
bgV.loop = true
|
|
6701
|
+
// Capture pages: the loop gets its own provider. An element seek
|
|
6702
|
+
// decodes from the previous keyframe on EVERY frame (a baked loop
|
|
6703
|
+
// has one every few seconds), and the capture waits for it; the
|
|
6704
|
+
// sequential walk decodes each packet once. The whole loop is read
|
|
6705
|
+
// into a Blob first when it is small enough (one request instead
|
|
6706
|
+
// of ranged reads against a CDN). FAIL-OPEN to the element at
|
|
6707
|
+
// every step, like the footage.
|
|
6708
|
+
if (ctx.data.videoDecodeMode === 'webcodecs' && !bgV.__voilaWc) {
|
|
6709
|
+
try {
|
|
6710
|
+
if (!(ns.videoBlobs && ns.videoBlobs.get(bgm.key)) && bgm.key.indexOf('blob:') !== 0 && bgm.key.indexOf('data:') !== 0) {
|
|
6711
|
+
try {
|
|
6712
|
+
const bgResp = await fetch(bgm.key)
|
|
6713
|
+
const bgLen = Number(bgResp.headers.get('content-length') || 0)
|
|
6714
|
+
if (bgResp.ok && bgLen <= BG_BLOB_MAX) {
|
|
6715
|
+
;(ns.videoBlobs || (ns.videoBlobs = new Map())).set(bgm.key, await bgResp.blob())
|
|
6716
|
+
} else {
|
|
6717
|
+
try { if (bgResp.body) await bgResp.body.cancel() } catch (e) { void e }
|
|
6718
|
+
}
|
|
6719
|
+
} catch (e) { void e }
|
|
6720
|
+
}
|
|
6721
|
+
const bgWc = await makeWcProvider(bgm.key)
|
|
6722
|
+
if (bgWc && (!bgV.videoWidth || (bgWc.width === bgV.videoWidth && bgWc.height === bgV.videoHeight))) bgV.__voilaWc = bgWc
|
|
6723
|
+
} catch (e) {
|
|
6724
|
+
console.warn('[voila] webcodecs provider unavailable for the background, seeks stay html5', e)
|
|
6725
|
+
}
|
|
6726
|
+
}
|
|
6727
|
+
}
|
|
6683
6728
|
} catch (e) { console.warn('[voila] background media failed to load', e) }
|
|
6684
6729
|
}
|
|
6730
|
+
// Which path decodes what, for a host's telemetry: 'provider' is the
|
|
6731
|
+
// sequential WebCodecs walk, 'element' an HTMLVideoElement seek per frame.
|
|
6732
|
+
ns.voilaDecode = {
|
|
6733
|
+
recording: ctx.data.isImage ? 'none' : video.__voilaWc ? 'provider' : 'element',
|
|
6734
|
+
backdrop: (function () {
|
|
6735
|
+
if (!bgm || !bgm.key || bgm.kind === 'image') return 'none'
|
|
6736
|
+
const bgHit = cache.get(bgm.key)
|
|
6737
|
+
return bgHit && bgHit.__voilaWc ? 'provider' : 'element'
|
|
6738
|
+
})(),
|
|
6739
|
+
}
|
|
6685
6740
|
// Frame prep: a capture harness calls every ns.framePrep hook right after
|
|
6686
6741
|
// seeking the timeline and before the first paint, then awaits
|
|
6687
6742
|
// waitForVideosReady. The footage for the frame is requested HERE, so the
|
|
@@ -7310,7 +7365,14 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
7310
7365
|
// Blur: softens the media behind the card (design px \xD7 s).
|
|
7311
7366
|
var bgBlur = bgm.blur || 0
|
|
7312
7367
|
if (bgBlur > 0 && bgC.filter !== undefined) bgC.filter = 'blur(' + bgBlur * s + 'px)'
|
|
7313
|
-
|
|
7368
|
+
// The loop's provider draws its current sample (paused capture
|
|
7369
|
+
// pages); false \u21D2 the element (playback, or before the first ask).
|
|
7370
|
+
try {
|
|
7371
|
+
var bgWcp = !bgIsImg && !playing ? bgEl.__voilaWc : null
|
|
7372
|
+
if (!(bgWcp && bgWcp.draw(bgC, null, (W - bgDw) / 2 + bgOx, (H - bgDh) / 2 + bgOy, bgDw, bgDh))) {
|
|
7373
|
+
bgC.drawImage(bgEl, (W - bgDw) / 2 + bgOx, (H - bgDh) / 2 + bgOy, bgDw, bgDh)
|
|
7374
|
+
}
|
|
7375
|
+
} catch (e) {}
|
|
7314
7376
|
if (bgBlur > 0 && bgC.filter !== undefined) bgC.filter = 'none'
|
|
7315
7377
|
var bgDim = bgm.dim || 0
|
|
7316
7378
|
if (bgDim > 0) {
|