@hyperframes/producer 0.8.193 → 0.8.195
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/distributed.js +86 -25
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +72 -66
- package/dist/index.js +139 -35
- package/dist/public-server.js +139 -35
- package/dist/services/htmlCompiler.d.ts +2 -1
- package/dist/services/render/artifactTransaction.d.ts +3 -1
- package/dist/services/renderOrchestrator.d.ts +4 -2
- package/package.json +7 -7
package/dist/distributed.js
CHANGED
|
@@ -1492,12 +1492,15 @@ import {
|
|
|
1492
1492
|
readMediaStart,
|
|
1493
1493
|
redactTelemetryString as redactTelemetryString2,
|
|
1494
1494
|
resolveNaturalMediaTimelineDurationFromValues,
|
|
1495
|
+
rewriteAssetPath,
|
|
1495
1496
|
rewriteAssetPaths,
|
|
1496
1497
|
rewriteCssAssetUrls,
|
|
1497
1498
|
rewriteInlineStyleAssetUrls
|
|
1498
1499
|
} from "@hyperframes/core";
|
|
1499
1500
|
import { MAX_AUDIO_GAIN } from "@hyperframes/core/audio-gain";
|
|
1500
|
-
import {
|
|
1501
|
+
import { readPlaybackRate } from "@hyperframes/parsers/media-duration";
|
|
1502
|
+
import { resolveRateSpec } from "@hyperframes/core/speed-ramp";
|
|
1503
|
+
import { gsapCdnDist, normalizeGsapBaseUrl } from "@hyperframes/core/gsap-cdn";
|
|
1501
1504
|
import {
|
|
1502
1505
|
assignBundledRuntimeCompositionIds,
|
|
1503
1506
|
assignMediaRenderIds,
|
|
@@ -2530,7 +2533,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, visited = /*
|
|
|
2530
2533
|
const results = await Promise.all(
|
|
2531
2534
|
workItems.map(async (item) => {
|
|
2532
2535
|
const { html: compiledSub } = await compileHtmlFile(
|
|
2533
|
-
item.rawSubHtml,
|
|
2536
|
+
rewriteUnresolvableGsapToCdn(item.rawSubHtml, projectDir, item.srcPath),
|
|
2534
2537
|
dirname4(item.filePath),
|
|
2535
2538
|
downloadDir,
|
|
2536
2539
|
void 0,
|
|
@@ -2704,7 +2707,9 @@ function inlineSubCompositions(html, subCompositions, projectDir, variableOverri
|
|
|
2704
2707
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
2705
2708
|
if (!compHtml) {
|
|
2706
2709
|
const read = readProjectFile(resolve5(projectDir, srcPath));
|
|
2707
|
-
if (read.kind === "file")
|
|
2710
|
+
if (read.kind === "file") {
|
|
2711
|
+
compHtml = rewriteUnresolvableGsapToCdn(read.text, projectDir, srcPath);
|
|
2712
|
+
}
|
|
2708
2713
|
}
|
|
2709
2714
|
return compHtml;
|
|
2710
2715
|
},
|
|
@@ -3247,18 +3252,27 @@ async function embedLocalFontFaces(html, projectDir) {
|
|
|
3247
3252
|
}
|
|
3248
3253
|
return result;
|
|
3249
3254
|
}
|
|
3250
|
-
|
|
3251
|
-
|
|
3255
|
+
function renderGsapDist() {
|
|
3256
|
+
try {
|
|
3257
|
+
return gsapCdnDist(void 0, normalizeGsapBaseUrl(process.env.HYPERFRAMES_GSAP_BASE_URL));
|
|
3258
|
+
} catch (cause) {
|
|
3259
|
+
throw new Error(
|
|
3260
|
+
"Invalid HYPERFRAMES_GSAP_BASE_URL: use an absolute HTTPS npm mirror root (plain HTTP only for localhost) without credentials, query, or fragment",
|
|
3261
|
+
{ cause }
|
|
3262
|
+
);
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
function rewriteUnresolvableGsapToCdn(html, projectDir, compSrcPath) {
|
|
3266
|
+
let gsapDist;
|
|
3267
|
+
const exists = (path) => existsSync6(resolve5(projectDir, path));
|
|
3252
3268
|
return html.replace(
|
|
3253
3269
|
/(<script\b[^>]*\bsrc=["'])([^"']*gsap[^"']*\/dist\/([^"']+))(["'][^>]*>)/gi,
|
|
3254
3270
|
(full, prefix, src, file, suffix) => {
|
|
3255
3271
|
if (/^https?:\/\//i.test(src)) return full;
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
defaultLogger.info(
|
|
3259
|
-
|
|
3260
|
-
);
|
|
3261
|
-
return `${prefix}${GSAP_CDN_BASE}${file}${suffix}`;
|
|
3272
|
+
if (exists(compSrcPath ? rewriteAssetPath(compSrcPath, src, exists) : src)) return full;
|
|
3273
|
+
gsapDist ??= renderGsapDist();
|
|
3274
|
+
defaultLogger.info(`[Compiler] Rewriting missing gsap script: ${src} \u2192 ${gsapDist}${file}`);
|
|
3275
|
+
return `${prefix}${gsapDist}${file}${suffix}`;
|
|
3262
3276
|
}
|
|
3263
3277
|
);
|
|
3264
3278
|
}
|
|
@@ -3472,6 +3486,9 @@ async function discoverMediaFromBrowser(page) {
|
|
|
3472
3486
|
const intrinsicDuration = isImage ? 0 : htmlEl.duration;
|
|
3473
3487
|
const playbackStartRaw = htmlEl.getAttribute("data-playback-start");
|
|
3474
3488
|
const mediaStartRaw = htmlEl.getAttribute("data-media-start");
|
|
3489
|
+
const playbackRateRaw = htmlEl.getAttribute("data-playback-rate");
|
|
3490
|
+
const automationRaw = htmlEl.getAttribute("data-automation");
|
|
3491
|
+
const defaultPlaybackRate = isImage ? 1 : htmlEl.defaultPlaybackRate;
|
|
3475
3492
|
const loop = htmlEl.hasAttribute("loop");
|
|
3476
3493
|
const hasAudio = htmlEl.getAttribute("data-has-audio") === "true";
|
|
3477
3494
|
const volume = parseFloat(htmlEl.getAttribute("data-volume") || "1");
|
|
@@ -3487,6 +3504,9 @@ async function discoverMediaFromBrowser(page) {
|
|
|
3487
3504
|
durationInferred,
|
|
3488
3505
|
playbackStartRaw,
|
|
3489
3506
|
mediaStartRaw,
|
|
3507
|
+
playbackRateRaw,
|
|
3508
|
+
automationRaw,
|
|
3509
|
+
defaultPlaybackRate,
|
|
3490
3510
|
loop,
|
|
3491
3511
|
hasAudio,
|
|
3492
3512
|
volume,
|
|
@@ -3496,7 +3516,17 @@ async function discoverMediaFromBrowser(page) {
|
|
|
3496
3516
|
return results;
|
|
3497
3517
|
});
|
|
3498
3518
|
return elements.map(
|
|
3499
|
-
({
|
|
3519
|
+
({
|
|
3520
|
+
endRaw,
|
|
3521
|
+
durationRaw,
|
|
3522
|
+
intrinsicDuration,
|
|
3523
|
+
playbackStartRaw,
|
|
3524
|
+
mediaStartRaw,
|
|
3525
|
+
playbackRateRaw,
|
|
3526
|
+
automationRaw,
|
|
3527
|
+
defaultPlaybackRate,
|
|
3528
|
+
...element
|
|
3529
|
+
}) => ({
|
|
3500
3530
|
...element,
|
|
3501
3531
|
end: parseStrictFiniteTimingNumber(endRaw) ?? 0,
|
|
3502
3532
|
duration: element.durationInferred && Number.isFinite(intrinsicDuration) && intrinsicDuration > 0 ? intrinsicDuration : parseStrictFiniteTimingNumber(durationRaw) ?? 0,
|
|
@@ -3506,7 +3536,14 @@ async function discoverMediaFromBrowser(page) {
|
|
|
3506
3536
|
if (name === "data-media-start") return mediaStartRaw;
|
|
3507
3537
|
return null;
|
|
3508
3538
|
}
|
|
3509
|
-
})
|
|
3539
|
+
}),
|
|
3540
|
+
playbackRate: resolveRateSpec(
|
|
3541
|
+
automationRaw,
|
|
3542
|
+
readPlaybackRate(
|
|
3543
|
+
(name) => name === "data-playback-rate" ? playbackRateRaw : null,
|
|
3544
|
+
defaultPlaybackRate
|
|
3545
|
+
)
|
|
3546
|
+
)
|
|
3510
3547
|
})
|
|
3511
3548
|
);
|
|
3512
3549
|
}
|
|
@@ -3926,9 +3963,18 @@ import {
|
|
|
3926
3963
|
getCompositionDuration,
|
|
3927
3964
|
initializeSession as initializeSession4,
|
|
3928
3965
|
isTransientBrowserError,
|
|
3929
|
-
probeBeginFrameLiveness
|
|
3966
|
+
probeBeginFrameLiveness,
|
|
3967
|
+
videoAudioId
|
|
3930
3968
|
} from "@hyperframes/engine";
|
|
3931
|
-
import {
|
|
3969
|
+
import {
|
|
3970
|
+
MEDIA_RENDER_ID_ATTR as MEDIA_RENDER_ID_ATTR2,
|
|
3971
|
+
fpsToNumber as fpsToNumber7,
|
|
3972
|
+
normalizeRateSpec as normalizeRateSpec3,
|
|
3973
|
+
readMediaStart as readMediaStart2,
|
|
3974
|
+
shiftRateLane as shiftRateLane2,
|
|
3975
|
+
sourceTimeAt as sourceTimeAt3,
|
|
3976
|
+
timeAtSourceTime
|
|
3977
|
+
} from "@hyperframes/core";
|
|
3932
3978
|
import { extractMediaSrcMutations } from "@hyperframes/parsers";
|
|
3933
3979
|
|
|
3934
3980
|
// src/services/render/stages/probeFailures.ts
|
|
@@ -3987,16 +4033,28 @@ function authoredMediaStarts(html) {
|
|
|
3987
4033
|
}
|
|
3988
4034
|
return starts;
|
|
3989
4035
|
}
|
|
3990
|
-
function
|
|
4036
|
+
function isVideoAudio(audio, videoId) {
|
|
4037
|
+
return audio.type === "video" && audio.id === videoAudioId(videoId);
|
|
4038
|
+
}
|
|
4039
|
+
function adoptRuntimeMediaTiming(composition, el, authored) {
|
|
3991
4040
|
const shift = el.mediaStart - authored;
|
|
3992
|
-
if (el.mediaStart <= 0 || Math.abs(shift) <= BROWSER_MEDIA_EPSILON) return;
|
|
3993
4041
|
const entries = el.tagName === "video" ? [
|
|
3994
4042
|
...composition.videos.filter((video) => video.id === el.id),
|
|
3995
|
-
...composition.audios.filter(
|
|
3996
|
-
(audio) => audio.type === "video" && audio.id === `${el.id}-audio`
|
|
3997
|
-
)
|
|
4043
|
+
...composition.audios.filter((audio) => isVideoAudio(audio, el.id))
|
|
3998
4044
|
] : composition.audios.filter((audio) => audio.type !== "video" && audio.id === el.id);
|
|
3999
|
-
for (const entry of entries)
|
|
4045
|
+
for (const entry of entries) {
|
|
4046
|
+
if (typeof entry.playbackRate !== "object") {
|
|
4047
|
+
if (typeof el.playbackRate === "object") {
|
|
4048
|
+
const consumed = Math.max(0, entry.mediaStart - authored);
|
|
4049
|
+
const head = timeAtSourceTime(normalizeRateSpec3(entry.playbackRate), consumed);
|
|
4050
|
+
entry.mediaStart += sourceTimeAt3(el.playbackRate, head) - consumed;
|
|
4051
|
+
entry.playbackRate = shiftRateLane2(el.playbackRate, head);
|
|
4052
|
+
} else {
|
|
4053
|
+
entry.playbackRate = el.playbackRate;
|
|
4054
|
+
}
|
|
4055
|
+
}
|
|
4056
|
+
if (el.mediaStart > 0 && Math.abs(shift) > BROWSER_MEDIA_EPSILON) entry.mediaStart += shift;
|
|
4057
|
+
}
|
|
4000
4058
|
}
|
|
4001
4059
|
function reconcileBrowserMediaEnd(existingEnd, projectedEnd, sourceChanged, durationInferred) {
|
|
4002
4060
|
if (projectedEnd <= 0) return existingEnd;
|
|
@@ -4280,7 +4338,7 @@ async function runProbeStage(input) {
|
|
|
4280
4338
|
sourceChanged,
|
|
4281
4339
|
el.durationInferred
|
|
4282
4340
|
);
|
|
4283
|
-
|
|
4341
|
+
adoptRuntimeMediaTiming(
|
|
4284
4342
|
composition,
|
|
4285
4343
|
el,
|
|
4286
4344
|
authoredStarts.get(el.id) ?? existing.mediaStart
|
|
@@ -4303,6 +4361,7 @@ async function runProbeStage(input) {
|
|
|
4303
4361
|
start: el.start,
|
|
4304
4362
|
end: resolveBrowserMediaEnd(el.start, el.end, el.duration),
|
|
4305
4363
|
mediaStart: el.mediaStart,
|
|
4364
|
+
playbackRate: el.playbackRate,
|
|
4306
4365
|
loop: el.loop,
|
|
4307
4366
|
hasAudio: el.hasAudio && !el.muted
|
|
4308
4367
|
});
|
|
@@ -4327,7 +4386,7 @@ async function runProbeStage(input) {
|
|
|
4327
4386
|
sourceChanged,
|
|
4328
4387
|
el.durationInferred
|
|
4329
4388
|
);
|
|
4330
|
-
|
|
4389
|
+
adoptRuntimeMediaTiming(
|
|
4331
4390
|
composition,
|
|
4332
4391
|
el,
|
|
4333
4392
|
authoredStarts.get(el.id) ?? existing.mediaStart
|
|
@@ -4345,6 +4404,7 @@ async function runProbeStage(input) {
|
|
|
4345
4404
|
end: resolveBrowserMediaEnd(el.start, el.end, el.duration),
|
|
4346
4405
|
mediaStart: el.mediaStart,
|
|
4347
4406
|
loop: el.loop,
|
|
4407
|
+
playbackRate: el.playbackRate,
|
|
4348
4408
|
layer: 0,
|
|
4349
4409
|
volume: el.volume,
|
|
4350
4410
|
type: "audio"
|
|
@@ -4605,7 +4665,8 @@ import {
|
|
|
4605
4665
|
isHttpUrl as isHttpUrl2,
|
|
4606
4666
|
resolveProjectRelativeSrc as resolveProjectRelativeSrc3,
|
|
4607
4667
|
runVideoExtractionWithRetry,
|
|
4608
|
-
safeVideoExtractionSourceIdentity
|
|
4668
|
+
safeVideoExtractionSourceIdentity,
|
|
4669
|
+
videoAudioId as videoAudioId2
|
|
4609
4670
|
} from "@hyperframes/engine";
|
|
4610
4671
|
|
|
4611
4672
|
// src/services/render/extractionFailureMetadata.ts
|
|
@@ -4963,7 +5024,7 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
|
|
|
4963
5024
|
const video = composition.videos.find((v) => v.id === ext.videoId);
|
|
4964
5025
|
if (!video || !video.hasAudio || video.hidden || existingAudioSrcs.has(video.src)) continue;
|
|
4965
5026
|
composition.audios.push({
|
|
4966
|
-
id:
|
|
5027
|
+
id: videoAudioId2(video.id),
|
|
4967
5028
|
src: video.src,
|
|
4968
5029
|
start: video.start,
|
|
4969
5030
|
end: video.end,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
3
|
"buildId": "dev",
|
|
4
|
-
"sha256": "
|
|
4
|
+
"sha256": "5325b9ad7580263b1e0a9ad0873c5a768b80a8807731148ebfe84ef585184902",
|
|
5
5
|
"artifacts": {
|
|
6
6
|
"iife": "hyperframe.runtime.iife.js",
|
|
7
7
|
"esm": "hyperframe.runtime.mjs"
|