@cueframe/kernel 0.2.1 → 0.2.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/dist/_members/animate/index.d.ts +8 -2
- package/dist/_members/animate/layout/FlexLayout.d.ts +69 -0
- package/dist/_members/animate/layout/fit.d.ts +44 -0
- package/dist/_members/animate/layout/index.d.ts +3 -0
- package/dist/_members/animate/layout/solveFlex.d.ts +70 -0
- package/dist/_members/animate/media/MediaTileScene.d.ts +65 -0
- package/dist/_members/animate/media/recipes.d.ts +61 -0
- package/dist/_members/animate/scene/FocusPass.d.ts +76 -0
- package/dist/_members/animate/scene/UnlitPlane.d.ts +45 -0
- package/dist/_members/animate/scene/__oracle__/cssProjection.d.ts +24 -0
- package/dist/_members/animate/scene/assets.d.ts +21 -0
- package/dist/_members/animate/scene/backdrop.d.ts +7 -0
- package/dist/_members/animate/scene/coordinates.d.ts +58 -0
- package/dist/_members/animate/scene/deviceOpacity.d.ts +18 -0
- package/dist/_members/animate/scene/errors.d.ts +14 -0
- package/dist/_members/animate/scene/finishing.d.ts +69 -0
- package/dist/_members/animate/scene/finishingMath.d.ts +60 -0
- package/dist/_members/animate/scene/finishingPass.d.ts +35 -0
- package/dist/_members/animate/scene/focusBlur.d.ts +56 -0
- package/dist/_members/animate/scene/focusResources.d.ts +190 -0
- package/dist/_members/animate/scene/focusShaders.d.ts +68 -0
- package/dist/_members/animate/scene/fontReadiness.d.ts +27 -0
- package/dist/_members/animate/scene/grainNoise.d.ts +118 -0
- package/dist/_members/animate/scene/index.d.ts +19 -0
- package/dist/_members/animate/scene/internal.d.ts +29 -0
- package/dist/_members/animate/scene/planeFit.d.ts +46 -0
- package/dist/_members/animate/scene/preparedWorldText.d.ts +25 -0
- package/dist/_members/animate/scene/rasterCache.d.ts +30 -0
- package/dist/_members/animate/scene/rasterReadiness.d.ts +33 -0
- package/dist/_members/animate/scene/readiness.d.ts +69 -0
- package/dist/_members/animate/scene/redraw.d.ts +10 -0
- package/dist/_members/animate/scene/render.d.ts +9 -0
- package/dist/_members/animate/scene/scaling.d.ts +13 -0
- package/dist/_members/animate/scene/text.d.ts +40 -0
- package/dist/_members/animate/scene/textLayout.d.ts +78 -0
- package/dist/_members/animate/scene/textureImageSize.d.ts +4 -0
- package/dist/_members/animate/scene/useSceneImageTexture.d.ts +21 -0
- package/dist/_members/animate/scene/useWorldTextTexture.d.ts +21 -0
- package/dist/_members/animate/scene/v2/MeasuredPlaneGeometry.d.ts +7 -0
- package/dist/_members/animate/scene/v2/PhotographicStudioRig.d.ts +11 -0
- package/dist/_members/animate/scene/v2/PreparedSceneShotV1.d.ts +12 -0
- package/dist/_members/animate/scene/v2/SceneShotV2.d.ts +59 -0
- package/dist/_members/animate/scene/v2/builders.d.ts +170 -0
- package/dist/_members/animate/scene/v2/finishes.d.ts +152 -0
- package/dist/_members/animate/scene/v2/lighting.d.ts +119 -0
- package/dist/_members/animate/scene/v2/observePmremTargets.d.ts +4 -0
- package/dist/_members/animate/scene/v2/preparationFacts.d.ts +32 -0
- package/dist/_members/animate/scene/v2/preparedSurface.d.ts +17 -0
- package/dist/_members/animate/scene/v2/projectedResolution.d.ts +2 -0
- package/dist/_members/animate/scene/v2/renderTargetObserver.d.ts +5 -0
- package/dist/_members/animate/scene/v2/runtimeAllocations.d.ts +55 -0
- package/dist/_members/animate/scene/v2/shadow.d.ts +23 -0
- package/dist/_members/animate/scene/v2/slabGeometry.d.ts +134 -0
- package/dist/_members/animate/scene/v2/slots.d.ts +73 -0
- package/dist/_members/animate/scene/v2/videoBinding.d.ts +39 -0
- package/dist/_members/animate/scene/worldBounds.d.ts +19 -0
- package/dist/_members/animate/scene/worldTextRaster.d.ts +87 -0
- package/dist/_members/animate/scene/worldTextTexture.d.ts +32 -0
- package/dist/_members/animate/stage/PerspectiveStage.d.ts +73 -0
- package/dist/_members/animate/stage/camera.d.ts +143 -0
- package/dist/_members/animate/stage/dof.d.ts +9 -0
- package/dist/_members/animate/stage/index.d.ts +6 -0
- package/dist/_members/animate/stage/presets.d.ts +17 -0
- package/dist/_members/animate/three/DeviceMesh.d.ts +256 -0
- package/dist/_members/animate/three/SceneCameraRig.d.ts +12 -0
- package/dist/_members/animate/three/StageCameraRig.d.ts +7 -0
- package/dist/_members/animate/three/StudioRig.d.ts +228 -0
- package/dist/_members/animate/three/ThreeCanvas.d.ts +22 -0
- package/dist/_members/animate/three/defaultScreen.d.ts +23 -0
- package/dist/_members/animate/three/index.d.ts +7 -1
- package/dist/_members/animate/three/textureLifecycle.d.ts +29 -0
- package/dist/_members/animate/three/toneMapping.d.ts +113 -0
- package/dist/_members/animate/three/useImageTexture.d.ts +17 -0
- package/dist/_members/authoring/index.d.ts +2 -0
- package/dist/_members/authoring/scene/index.d.ts +6 -0
- package/dist/_members/authoring/scene/materialize.d.ts +47 -0
- package/dist/_members/authoring/scene/validate.d.ts +80 -0
- package/dist/_members/authoring/scene/wrapper.d.ts +41 -0
- package/dist/_members/component-runtime/allowedImports.d.ts +3 -0
- package/dist/_members/component-runtime/allowedImports.d.ts.map +1 -0
- package/dist/_members/component-runtime/bake.d.ts +8 -0
- package/dist/_members/component-runtime/bake.d.ts.map +1 -1
- package/dist/_members/component-runtime/browserFirewall.d.ts +7 -1
- package/dist/_members/component-runtime/browserFirewall.d.ts.map +1 -1
- package/dist/_members/component-runtime/browserOptions.d.ts +59 -3
- package/dist/_members/component-runtime/browserOptions.d.ts.map +1 -1
- package/dist/_members/component-runtime/canonicalIdentity.d.ts +14 -0
- package/dist/_members/component-runtime/canonicalIdentity.d.ts.map +1 -1
- package/dist/_members/component-runtime/contracts.d.ts +341 -1
- package/dist/_members/component-runtime/contracts.d.ts.map +1 -1
- package/dist/_members/component-runtime/fixtures/imageTileDriftWall.d.ts +5 -0
- package/dist/_members/component-runtime/fixtures/imageTileDriftWall.d.ts.map +1 -0
- package/dist/_members/component-runtime/fixtures/mediaTileMixed.d.ts +5 -0
- package/dist/_members/component-runtime/fixtures/mediaTileMixed.d.ts.map +1 -0
- package/dist/_members/component-runtime/fixtures/mediaTileVideo.d.ts +8 -0
- package/dist/_members/component-runtime/fixtures/mediaTileVideo.d.ts.map +1 -0
- package/dist/_members/component-runtime/importPolicy.d.ts +3 -2
- package/dist/_members/component-runtime/importPolicy.d.ts.map +1 -1
- package/dist/_members/component-runtime/index.d.ts +3 -0
- package/dist/_members/component-runtime/index.d.ts.map +1 -1
- package/dist/_members/component-runtime/livePreviewProxy.d.ts +7 -0
- package/dist/_members/component-runtime/livePreviewProxy.d.ts.map +1 -0
- package/dist/_members/component-runtime/localRoot.d.ts +37 -0
- package/dist/_members/component-runtime/localRoot.d.ts.map +1 -0
- package/dist/_members/component-runtime/mediaResolution.d.ts +25 -0
- package/dist/_members/component-runtime/mediaResolution.d.ts.map +1 -0
- package/dist/_members/component-runtime/render.d.ts +151 -13
- package/dist/_members/component-runtime/render.d.ts.map +1 -1
- package/dist/_members/component-runtime/renderDiagnostics.d.ts +14 -0
- package/dist/_members/component-runtime/renderDiagnostics.d.ts.map +1 -0
- package/dist/_members/component-runtime/sceneAdmission.d.ts +47 -0
- package/dist/_members/component-runtime/sceneAdmission.d.ts.map +1 -0
- package/dist/_members/component-runtime/sourceWorkspace.d.ts +8 -0
- package/dist/_members/component-runtime/sourceWorkspace.d.ts.map +1 -1
- package/dist/_members/component-runtime/webglProbe.d.ts +191 -0
- package/dist/_members/component-runtime/webglProbe.d.ts.map +1 -0
- package/dist/_members/composition/fonts/bundledFaces.d.ts +150 -0
- package/dist/_members/composition/fonts/captionFaces.d.ts +268 -0
- package/dist/_members/composition/fonts.d.ts +11 -4
- package/dist/_members/composition/graphics-plan/schemas.d.ts +4 -4
- package/dist/_members/composition/ops/types.d.ts +1 -1
- package/dist/_members/composition/primitive-catalog/types.d.ts +1 -0
- package/dist/_members/composition/projection/behind-readiness.d.ts +3 -0
- package/dist/_members/composition/projection/brandKit.d.ts +6 -0
- package/dist/_members/composition/projection/composition-floor.d.ts +2 -1
- package/dist/_members/composition/scene/animation.d.ts +25 -0
- package/dist/_members/composition/scene/budget.d.ts +29 -0
- package/dist/_members/composition/scene/budgetPolicy.d.mts +13 -0
- package/dist/_members/composition/scene/clipRules.d.ts +119 -0
- package/dist/_members/composition/scene/constraints.d.ts +61 -0
- package/dist/_members/composition/scene/device.d.ts +21 -0
- package/dist/_members/composition/scene/examples.d.ts +11 -0
- package/dist/_members/composition/scene/index.d.ts +11 -0
- package/dist/_members/composition/scene/photographicRig.d.ts +242 -0
- package/dist/_members/composition/scene/preparedRender.d.ts +239 -0
- package/dist/_members/composition/scene/resolution.d.ts +178 -0
- package/dist/_members/composition/scene/schema.d.ts +351 -0
- package/dist/_members/composition/scene/videoSchedule.d.ts +43 -0
- package/dist/_members/composition/validators/brandKit.d.ts +1 -0
- package/dist/_members/composition/validators/render.d.ts +2 -0
- package/dist/_members/composition-ops/index.d.ts +45 -0
- package/dist/_members/composition-ops/opRecorder.d.ts +1 -1
- package/dist/_members/core/render/compositionRender.d.ts +41 -9
- package/dist/_members/core/render/index.d.ts +9 -2
- package/dist/_members/core/render/sceneCaptureIdentity.d.ts +14 -0
- package/dist/_members/core/render/sceneShotPlan.d.ts +142 -0
- package/dist/_members/core/render/sceneShotPreparation.d.ts +57 -0
- package/dist/_members/core/render/slabDescriptor.d.ts +21 -0
- package/dist/_members/core/render/trackProjection.d.ts +33 -0
- package/dist/_members/core/render/types.d.ts +142 -0
- package/dist/_members/errors/registry.d.ts +6 -0
- package/dist/_members/mcp/adapter.d.ts +5 -0
- package/dist/_members/mcp/generated/sceneContract.d.ts +155 -0
- package/dist/_members/mcp/sceneShot.d.ts +38 -0
- package/dist/_members/mcp/sceneShotExample.d.ts +22 -0
- package/dist/_members/media-model/api.d.ts +1 -0
- package/dist/_members/media-model/media-kind.d.ts +1 -1
- package/dist/_members/media-model/testing/mediaStoreContract.d.ts +1 -1
- package/dist/_members/primitives/effects/index.d.ts +1 -0
- package/dist/_members/primitives/effects/stage-camera/config.d.ts +50 -0
- package/dist/_members/primitives/effects/stage-camera/index.d.ts +31 -0
- package/dist/_members/primitives/layouts/flex-layout/config.d.ts +73 -0
- package/dist/_members/primitives/layouts/flex-layout/index.d.ts +4 -0
- package/dist/_members/primitives/layouts/index.d.ts +1 -0
- package/dist/_members/primitives/layouts/picture-in-picture/config.d.ts +1 -1
- package/dist/_members/primitives/lib/frameScale.d.ts +4 -0
- package/dist/_members/primitives/lib/index.d.ts +1 -0
- package/dist/_members/primitives/lib/palette.d.ts +30 -30
- package/dist/_members/primitives/lib/text/contrast.d.ts +2 -1
- package/dist/_members/primitives/lib/text/spec.d.ts +0 -8
- package/dist/_members/primitives/lib/types.d.ts +2 -0
- package/dist/_members/primitives/scenes/device-showcase/config.d.ts +41 -0
- package/dist/_members/primitives/scenes/device-showcase/index.d.ts +36 -0
- package/dist/_members/primitives/scenes/hero-device-assemble/config.d.ts +1 -0
- package/dist/_members/primitives/scenes/hero-device-assemble/index.d.ts +2 -1
- package/dist/_members/primitives/scenes/index.d.ts +1 -0
- package/dist/_members/primitives/ui-blocks/badge-pop/config.d.ts +1 -1
- package/dist/_members/primitives/ui-blocks/device-mockup-zoom/config.d.ts +1 -0
- package/dist/_members/primitives/ui-blocks/device-mockup-zoom/index.d.ts +2 -1
- package/dist/_members/primitives/ui-blocks/terminal-simulator/config.d.ts +1 -1
- package/dist/_members/primitives/ui-blocks/toast-notification/config.d.ts +1 -1
- package/dist/_members/render-harness/cardAssetAdmission.d.ts.map +1 -1
- package/dist/_members/render-harness/cardRender.d.ts.map +1 -1
- package/dist/_members/render-harness/css-tree-subpaths.d.ts +11 -0
- package/dist/_members/render-harness/extractSegments.d.ts +1 -0
- package/dist/_members/render-harness/extractSegments.d.ts.map +1 -1
- package/dist/_members/render-harness/imageHeader.d.ts +14 -0
- package/dist/_members/render-harness/imageHeader.d.ts.map +1 -0
- package/dist/_members/render-harness/index.d.ts +6 -0
- package/dist/_members/render-harness/index.d.ts.map +1 -1
- package/dist/_members/render-harness/materializeSources.d.ts +46 -2
- package/dist/_members/render-harness/materializeSources.d.ts.map +1 -1
- package/dist/_members/render-harness/nodeScenePreparation.d.ts +97 -0
- package/dist/_members/render-harness/nodeScenePreparation.d.ts.map +1 -0
- package/dist/_members/render-harness/remotion-runtime.d.ts +16 -2
- package/dist/_members/render-harness/renderInputAssets.d.ts +1 -1
- package/dist/_members/render-harness/renderInputAssets.d.ts.map +1 -1
- package/dist/_members/render-harness/resolveAssets.d.ts +2 -2
- package/dist/_members/render-harness/resolveAssets.d.ts.map +1 -1
- package/dist/_members/render-harness/sceneShotAssets.d.ts +17 -0
- package/dist/_members/render-harness/sceneShotAssets.d.ts.map +1 -0
- package/dist/animate/preparation-facts.d.ts +1 -0
- package/dist/animate/preparation-facts.js +22 -0
- package/dist/animate.js +336 -1005
- package/dist/authoring/build-tools.js +7 -6
- package/dist/authoring/context.js +5 -4
- package/dist/authoring/prompts.js +1 -1
- package/dist/authoring/scene.d.ts +1 -0
- package/dist/authoring/scene.js +50 -0
- package/dist/authoring/tools.js +6 -5
- package/dist/authoring.js +49 -29
- package/dist/chunk-2L7PYYJK.js +23 -0
- package/dist/{chunk-ZN6P3KOJ.js → chunk-32TH76H3.js} +2 -2
- package/dist/chunk-5DJ3IEJR.js +4424 -0
- package/dist/chunk-6BVVCRRD.js +26488 -0
- package/dist/{chunk-DQKSCHFC.js → chunk-6EWRIAZA.js} +187 -66
- package/dist/{chunk-YQ7FFW3G.js → chunk-6VWICHOZ.js} +26 -5
- package/dist/{chunk-2PGLNTB7.js → chunk-A74FZCPY.js} +45 -5
- package/dist/{chunk-C5SEPOWD.js → chunk-AS5EXBNS.js} +1792 -707
- package/dist/{chunk-BKHGL4MB.js → chunk-B3GSTQLR.js} +341 -274
- package/dist/chunk-BVA3537Z.js +63 -0
- package/dist/{chunk-DHKQ47Q6.js → chunk-DAARYRNT.js} +6 -1
- package/dist/chunk-DQLYWNLC.js +2063 -0
- package/dist/chunk-E6WHXIDF.js +3619 -0
- package/dist/{chunk-NOEBAV2G.js → chunk-E7GIZEPS.js} +1 -1
- package/dist/{chunk-M2TLRXEO.js → chunk-EXY4JJPH.js} +1 -1
- package/dist/{chunk-GEGRJKKO.js → chunk-F2DJL7P7.js} +1 -1
- package/dist/{chunk-AWT3P5ZN.js → chunk-FVDFPJHT.js} +1 -1
- package/dist/{chunk-EMGFZ3PR.js → chunk-FWSJLHSV.js} +5 -1
- package/dist/{chunk-TMIBBD5E.js → chunk-I5QWBM3M.js} +280 -113
- package/dist/{chunk-IBMJ33EL.js → chunk-I5RX2QZT.js} +1 -1
- package/dist/{chunk-4FOOBSEE.js → chunk-J3DIUG24.js} +1 -0
- package/dist/{chunk-AD5HWBCE.js → chunk-JX53CVJV.js} +14 -5
- package/dist/{chunk-LNBVTDFR.js → chunk-L2AHS3AW.js} +1 -1
- package/dist/{chunk-BDMTUEEZ.js → chunk-LT4PWSR2.js} +2 -2
- package/dist/chunk-MH3UPKWR.js +3415 -0
- package/dist/{chunk-RFXR7ATW.js → chunk-NUKDEOK6.js} +13 -1
- package/dist/{chunk-IJ7PVJTK.js → chunk-ODUWCQI3.js} +3 -2
- package/dist/chunk-QAGGJHAF.js +16 -0
- package/dist/chunk-QS36DMFG.js +332 -0
- package/dist/{chunk-G5BFI32U.js → chunk-RAXHCRVV.js} +1 -1
- package/dist/{chunk-BIBYZJL3.js → chunk-RL5SO653.js} +3 -3
- package/dist/{chunk-ZSZABOE5.js → chunk-S5H6GH6M.js} +1 -1
- package/dist/{chunk-EEXCDFY5.js → chunk-SD25VQDE.js} +1 -1
- package/dist/{chunk-Y3QGYASW.js → chunk-SX523NDS.js} +14 -14
- package/dist/chunk-TARKDVP6.js +430 -0
- package/dist/{chunk-IHFREGFA.js → chunk-TCHPRGC5.js} +18 -2
- package/dist/{chunk-ZCAQHNPI.js → chunk-UKGNHZS4.js} +1 -1
- package/dist/{chunk-KU376ELE.js → chunk-UY77TMKD.js} +31 -44
- package/dist/chunk-VKATKWWR.js +1462 -0
- package/dist/{chunk-CX2IIQ4R.js → chunk-W2245F6G.js} +29 -29
- package/dist/{chunk-XHUYWVYK.js → chunk-WBNFSG6T.js} +1 -1
- package/dist/chunk-WIHXXF3X.js +221 -0
- package/dist/{chunk-XVBOSPZI.js → chunk-X74EEFXV.js} +6 -6
- package/dist/{chunk-7KEUL3FI.js → chunk-XF2QMKRG.js} +9 -1
- package/dist/{chunk-HFC3MKXA.js → chunk-Y4HPN4BC.js} +1 -0
- package/dist/{chunk-6XI57FZZ.js → chunk-YFSBFCXO.js} +1022 -46
- package/dist/{chunk-6ID2J64H.js → chunk-YHC3RXS7.js} +162 -25
- package/dist/{chunk-KKEY5MIW.js → chunk-ZS3A3QUM.js} +16 -16
- package/dist/{chunk-LQUWKBST.js → chunk-ZVG446DJ.js} +139 -10
- package/dist/component-runtime/browserOptions.js +14 -3
- package/dist/component-runtime/contracts.js +35 -3
- package/dist/component-runtime/identity/browser.js +1 -1
- package/dist/component-runtime/identity.js +2 -2
- package/dist/component-runtime/importPolicy.js +2 -2
- package/dist/component-runtime/mediaResolution.d.ts +1 -0
- package/dist/component-runtime/mediaResolution.js +11 -0
- package/dist/component-runtime/render.js +38 -5
- package/dist/component-runtime.js +118 -14
- package/dist/compose.js +27 -21
- package/dist/composition/fonts.js +64 -67
- package/dist/composition/graphics-plan.js +3 -2
- package/dist/composition/ops.js +4 -3
- package/dist/composition/primitive-catalog.js +1 -1
- package/dist/composition/projection.js +10 -3
- package/dist/composition/scene/budget-policy.d.ts +1 -0
- package/dist/composition/scene/budget-policy.js +17 -0
- package/dist/composition/scene/schema.json +2757 -0
- package/dist/composition/scene.d.ts +1 -0
- package/dist/composition/scene.js +275 -0
- package/dist/composition/validators.js +3 -2
- package/dist/composition-ops.js +103 -13
- package/dist/composition.js +12 -5
- package/dist/{context-4GSDBFT3.js → context-IUPQ54V4.js} +5 -4
- package/dist/core/render.js +54 -3
- package/dist/core/select.js +2 -2
- package/dist/core.js +6 -3
- package/dist/director/ai-sdk.js +3 -3
- package/dist/director/domain.js +2 -2
- package/dist/director.js +3 -3
- package/dist/errors.js +1 -1
- package/dist/mcp/adapter.js +4 -4
- package/dist/mcp/core.js +1 -1
- package/dist/mcp/curation.js +1 -1
- package/dist/mcp/server.js +4 -4
- package/dist/mcp.js +4 -4
- package/dist/media-model/media-kind.js +2 -0
- package/dist/media-model/testing.js +16 -11
- package/dist/media-model.js +1 -1
- package/dist/nle-export.js +27 -21
- package/dist/primitives/backgrounds.js +2 -2
- package/dist/primitives/captions.js +21 -11
- package/dist/primitives/effects.js +14 -4
- package/dist/primitives/graphics.json +3 -0
- package/dist/primitives/hero-text.js +4 -3
- package/dist/primitives/layouts.js +9 -2
- package/dist/primitives/lib/frameScale.d.ts +1 -0
- package/dist/primitives/lib/frameScale.js +11 -0
- package/dist/primitives/lib/index.js +18 -10
- package/dist/primitives/lib/palette.js +1 -1
- package/dist/primitives/lib/text/contrast.js +2 -1
- package/dist/primitives/lib/text/typeface.js +1 -1
- package/dist/primitives/lib.js +18 -10
- package/dist/primitives/params-required.json +3 -0
- package/dist/primitives/scenes.js +12 -3
- package/dist/primitives/text.js +5 -5
- package/dist/primitives/transitions.js +2 -2
- package/dist/primitives/ui-blocks.js +7 -6
- package/dist/primitives/version-map.json +5 -2
- package/dist/primitives.js +27 -20
- package/dist/render-harness/cardAssetAdmission.js +2 -2
- package/dist/render-harness/renderInputAssets.js +2 -2
- package/dist/render-harness.js +876 -126
- package/package.json +51 -17
- package/dist/_members/animate/three/drei.d.ts +0 -6
- package/dist/_members/component-runtime/fixtures/webgpuTiledRefraction.d.ts +0 -9
- package/dist/_members/component-runtime/fixtures/webgpuTiledRefraction.d.ts.map +0 -1
- package/dist/chunk-4JRUGT2Y.js +0 -544
- package/dist/chunk-5OTQ7M43.js +0 -718
- package/dist/chunk-CGHTMZNC.js +0 -6
- package/dist/chunk-QBKDEO7J.js +0 -9521
- /package/dist/{chunk-H5LMJKZU.js → chunk-JVDUSOYG.js} +0 -0
package/dist/render-harness.js
CHANGED
|
@@ -1,36 +1,74 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertCardHtmlAssetFree
|
|
3
|
-
} from "./chunk-IJ7PVJTK.js";
|
|
4
1
|
import {
|
|
5
2
|
assertNoRemoteRefs,
|
|
6
3
|
assetSlots,
|
|
7
4
|
assetUrlKey,
|
|
8
5
|
isRemoteUrl,
|
|
9
6
|
renderInputAssets
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-KU376ELE.js";
|
|
7
|
+
} from "./chunk-NUKDEOK6.js";
|
|
12
8
|
import {
|
|
9
|
+
assertCardHtmlAssetFree
|
|
10
|
+
} from "./chunk-ODUWCQI3.js";
|
|
11
|
+
import "./chunk-UY77TMKD.js";
|
|
12
|
+
import "./chunk-BVA3537Z.js";
|
|
13
|
+
import {
|
|
14
|
+
COMPONENT_STILL_RUNTIME_IDENTITY,
|
|
15
|
+
componentStillDependencyIdentity,
|
|
16
|
+
componentStillRasterAffectingFlags,
|
|
17
|
+
createComponentStillSession,
|
|
13
18
|
importFromRenderEntry,
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
readMaterializedComponentSource,
|
|
20
|
+
resolveRenderEntryRoot,
|
|
21
|
+
verifyLocalStagedBrowser
|
|
22
|
+
} from "./chunk-DQLYWNLC.js";
|
|
16
23
|
import "./chunk-WB2VFDQZ.js";
|
|
17
24
|
import {
|
|
18
|
-
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
sourceVersionId
|
|
26
|
+
} from "./chunk-EXY4JJPH.js";
|
|
27
|
+
import "./chunk-DAARYRNT.js";
|
|
28
|
+
import "./chunk-A74FZCPY.js";
|
|
29
|
+
import {
|
|
30
|
+
componentBrowserBackend
|
|
31
|
+
} from "./chunk-WIHXXF3X.js";
|
|
32
|
+
import "./chunk-ZVG446DJ.js";
|
|
33
|
+
import {
|
|
34
|
+
generatedStudioPreparationFactsV1,
|
|
35
|
+
scenePresetBuilderDescriptorV1
|
|
36
|
+
} from "./chunk-VKATKWWR.js";
|
|
37
|
+
import "./chunk-AS5EXBNS.js";
|
|
38
|
+
import {
|
|
39
|
+
SCENE_SHOT_PREPARATION_STAGE,
|
|
40
|
+
createSceneBuilderDescriptorRegistryV1,
|
|
41
|
+
parseSceneComponentCaptureIntentV1,
|
|
42
|
+
prepareSceneShotRenderInput,
|
|
43
|
+
readSceneShotManifest
|
|
44
|
+
} from "./chunk-YFSBFCXO.js";
|
|
45
|
+
import "./chunk-QH3YI3ND.js";
|
|
46
|
+
import "./chunk-QISFYLBB.js";
|
|
47
|
+
import "./chunk-L2AHS3AW.js";
|
|
48
|
+
import "./chunk-VZ7TYX6Z.js";
|
|
49
|
+
import "./chunk-DENF4TPI.js";
|
|
50
|
+
import "./chunk-KYRDKK2D.js";
|
|
51
|
+
import "./chunk-WREYUH2E.js";
|
|
25
52
|
import "./chunk-7PA7FGLD.js";
|
|
26
|
-
import
|
|
53
|
+
import {
|
|
54
|
+
CueframeError
|
|
55
|
+
} from "./chunk-J3DIUG24.js";
|
|
56
|
+
import "./chunk-TARKDVP6.js";
|
|
57
|
+
import {
|
|
58
|
+
evaluateScene,
|
|
59
|
+
parseSceneShotSpecV2,
|
|
60
|
+
photographicSceneRigFactsV1,
|
|
61
|
+
sceneCameraPlanesV2
|
|
62
|
+
} from "./chunk-MH3UPKWR.js";
|
|
63
|
+
import "./chunk-2L7PYYJK.js";
|
|
27
64
|
import "./chunk-2ESYSVXG.js";
|
|
28
65
|
|
|
29
66
|
// ../execution/render-harness/src/materializeSources.ts
|
|
30
|
-
import { join as
|
|
31
|
-
import {
|
|
67
|
+
import { join as join5, basename } from "path";
|
|
68
|
+
import { createHash as createHash4 } from "crypto";
|
|
69
|
+
import { mkdir, copyFile, readFile as readFile3 } from "fs/promises";
|
|
32
70
|
import { createWriteStream, existsSync as existsSync4 } from "fs";
|
|
33
|
-
import { fileURLToPath } from "url";
|
|
71
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
34
72
|
import { Readable } from "stream";
|
|
35
73
|
import { pipeline } from "stream/promises";
|
|
36
74
|
|
|
@@ -117,6 +155,7 @@ import { tmpdir } from "os";
|
|
|
117
155
|
import { rm } from "fs/promises";
|
|
118
156
|
var exec = promisify(execFile);
|
|
119
157
|
async function extractSegments(clips, sourceFiles, opts) {
|
|
158
|
+
opts?.signal?.throwIfAborted();
|
|
120
159
|
const padding = opts?.padding ?? 1;
|
|
121
160
|
const dir = mkdtempSync(join2(tmpdir(), "cueframe-segments-"));
|
|
122
161
|
const segments = {};
|
|
@@ -129,6 +168,10 @@ async function extractSegments(clips, sourceFiles, opts) {
|
|
|
129
168
|
clipsBySource.set(clip.poolItemId, list);
|
|
130
169
|
}
|
|
131
170
|
for (const [poolItemId, sourceClips] of clipsBySource) {
|
|
171
|
+
if (opts?.signal?.aborted) {
|
|
172
|
+
await rm(dir, { recursive: true, force: true });
|
|
173
|
+
opts.signal.throwIfAborted();
|
|
174
|
+
}
|
|
132
175
|
const sourcePath = sourceFiles[poolItemId];
|
|
133
176
|
const remote = /^https?:\/\//i.test(sourcePath);
|
|
134
177
|
if (!remote && !existsSync2(sourcePath)) {
|
|
@@ -153,11 +196,15 @@ async function extractSegments(clips, sourceFiles, opts) {
|
|
|
153
196
|
"-movflags",
|
|
154
197
|
"+faststart",
|
|
155
198
|
segmentPath
|
|
156
|
-
], { timeout: remote ? 12e4 : 6e4 });
|
|
199
|
+
], { timeout: remote ? 12e4 : 6e4, signal: opts?.signal });
|
|
157
200
|
segments[poolItemId] = segmentPath;
|
|
158
201
|
origins[poolItemId] = minStart;
|
|
159
202
|
console.log(`[extractSegments] ${poolItemId}: ${minStart.toFixed(1)}s-${maxEnd.toFixed(1)}s \u2192 ${segmentPath}`);
|
|
160
203
|
} catch (err) {
|
|
204
|
+
if (opts?.signal?.aborted) {
|
|
205
|
+
await rm(dir, { recursive: true, force: true });
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
161
208
|
console.error(`[extractSegments] Failed for ${poolItemId}:`, err);
|
|
162
209
|
if (!remote) {
|
|
163
210
|
segments[poolItemId] = sourcePath;
|
|
@@ -180,26 +227,37 @@ async function extractSegments(clips, sourceFiles, opts) {
|
|
|
180
227
|
import { existsSync as existsSync3 } from "fs";
|
|
181
228
|
import { join as join3, extname as extname2 } from "path";
|
|
182
229
|
import { createHash } from "crypto";
|
|
183
|
-
async function resolveAssets(renderInput, tempDir, mediaServerUrl, download) {
|
|
230
|
+
async function resolveAssets(renderInput, tempDir, mediaServerUrl, download, signal) {
|
|
184
231
|
const urlMap = {};
|
|
185
232
|
const seen = /* @__PURE__ */ new Set();
|
|
186
233
|
async function resolve(url) {
|
|
234
|
+
signal?.throwIfAborted();
|
|
187
235
|
if (!url) return url;
|
|
188
|
-
|
|
236
|
+
const embedded = /^data:([^;,]+);base64,/.exec(url);
|
|
237
|
+
if (!isRemoteUrl(url) && !embedded) return url;
|
|
189
238
|
if (seen.has(url)) return urlMap[url] ?? url;
|
|
190
239
|
seen.add(url);
|
|
191
240
|
const hash = createHash("md5").update(url).digest("hex").slice(0, 12);
|
|
192
|
-
const
|
|
241
|
+
const embeddedExtension = {
|
|
242
|
+
"audio/mp4": ".m4a",
|
|
243
|
+
"audio/mpeg": ".mp3",
|
|
244
|
+
"audio/wav": ".wav",
|
|
245
|
+
"image/png": ".png",
|
|
246
|
+
"image/jpeg": ".jpg",
|
|
247
|
+
"image/webp": ".webp",
|
|
248
|
+
"image/svg+xml": ".svg"
|
|
249
|
+
};
|
|
250
|
+
const ext = embedded ? embeddedExtension[embedded[1]] : extname2(new URL(url).pathname);
|
|
251
|
+
if (!ext) throw new Error(`Unsupported embedded render asset MIME '${embedded?.[1] ?? "unknown"}'.`);
|
|
193
252
|
const filename = `asset_${hash}${ext}`;
|
|
194
|
-
const
|
|
195
|
-
if (!existsSync3(
|
|
253
|
+
const localPath2 = join3(tempDir, filename);
|
|
254
|
+
if (!existsSync3(localPath2)) {
|
|
196
255
|
try {
|
|
197
|
-
await download(url,
|
|
256
|
+
await download(url, localPath2, signal);
|
|
198
257
|
} catch (err) {
|
|
199
|
-
throw
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
258
|
+
if (signal?.aborted) throw err;
|
|
259
|
+
const label = embedded ? `embedded ${embedded[1]} asset` : `${new URL(url).origin}${new URL(url).pathname}`;
|
|
260
|
+
throw new Error(`Failed to materialize required render asset ${label}`, { cause: err });
|
|
203
261
|
}
|
|
204
262
|
}
|
|
205
263
|
const localUrl = `${mediaServerUrl}/${filename}`;
|
|
@@ -232,11 +290,616 @@ async function resolveAssets(renderInput, tempDir, mediaServerUrl, download) {
|
|
|
232
290
|
}
|
|
233
291
|
|
|
234
292
|
// ../execution/render-harness/src/materializeSources.ts
|
|
293
|
+
import sharp2 from "sharp";
|
|
294
|
+
|
|
295
|
+
// ../execution/render-harness/src/sceneShotAssets.ts
|
|
296
|
+
import { readFile } from "fs/promises";
|
|
297
|
+
import { createHash as createHash2 } from "crypto";
|
|
298
|
+
import { join as join4 } from "path";
|
|
299
|
+
import { fileURLToPath } from "url";
|
|
300
|
+
|
|
301
|
+
// ../execution/render-harness/src/imageHeader.ts
|
|
302
|
+
var PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
303
|
+
function ascii(bytes, offset, length) {
|
|
304
|
+
let out = "";
|
|
305
|
+
for (let i = 0; i < length; i++) out += String.fromCharCode(bytes[offset + i]);
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
308
|
+
function u16be(bytes, offset) {
|
|
309
|
+
return bytes[offset] << 8 | bytes[offset + 1];
|
|
310
|
+
}
|
|
311
|
+
function u32be(bytes, offset) {
|
|
312
|
+
return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
|
|
313
|
+
}
|
|
314
|
+
function u16le(bytes, offset) {
|
|
315
|
+
return bytes[offset] | bytes[offset + 1] << 8;
|
|
316
|
+
}
|
|
317
|
+
function u24le(bytes, offset) {
|
|
318
|
+
return bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16;
|
|
319
|
+
}
|
|
320
|
+
function u32le(bytes, offset) {
|
|
321
|
+
return (bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16 | bytes[offset + 3] << 24) >>> 0;
|
|
322
|
+
}
|
|
323
|
+
function png(bytes) {
|
|
324
|
+
if (bytes.length < 24) return null;
|
|
325
|
+
for (let i = 0; i < PNG_SIGNATURE.length; i++) if (bytes[i] !== PNG_SIGNATURE[i]) return null;
|
|
326
|
+
if (u32be(bytes, 8) !== 13 || ascii(bytes, 12, 4) !== "IHDR") return null;
|
|
327
|
+
const width = u32be(bytes, 16);
|
|
328
|
+
const height = u32be(bytes, 20);
|
|
329
|
+
if (width === 0 || height === 0) return null;
|
|
330
|
+
return { mimeType: "image/png", width, height };
|
|
331
|
+
}
|
|
332
|
+
function isStartOfFrame(code) {
|
|
333
|
+
return code >= 192 && code <= 195 || code >= 197 && code <= 199 || code >= 201 && code <= 203 || code >= 205 && code <= 207;
|
|
334
|
+
}
|
|
335
|
+
function jpeg(bytes) {
|
|
336
|
+
if (bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) return null;
|
|
337
|
+
let offset = 2;
|
|
338
|
+
while (offset + 4 <= bytes.length) {
|
|
339
|
+
if (bytes[offset] !== 255) return null;
|
|
340
|
+
let code = bytes[offset + 1];
|
|
341
|
+
while (code === 255 && offset + 2 < bytes.length) {
|
|
342
|
+
offset += 1;
|
|
343
|
+
code = bytes[offset + 1];
|
|
344
|
+
}
|
|
345
|
+
offset += 2;
|
|
346
|
+
if (code === 216 || code >= 208 && code <= 215 || code === 1) continue;
|
|
347
|
+
if (code === 217 || code === 218) return null;
|
|
348
|
+
if (offset + 2 > bytes.length) return null;
|
|
349
|
+
const length = u16be(bytes, offset);
|
|
350
|
+
if (length < 2) return null;
|
|
351
|
+
if (isStartOfFrame(code)) {
|
|
352
|
+
if (offset + 7 > bytes.length) return null;
|
|
353
|
+
const height = u16be(bytes, offset + 3);
|
|
354
|
+
const width = u16be(bytes, offset + 5);
|
|
355
|
+
if (width === 0 || height === 0) return null;
|
|
356
|
+
return { mimeType: "image/jpeg", width, height };
|
|
357
|
+
}
|
|
358
|
+
offset += length;
|
|
359
|
+
}
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
function webp(bytes) {
|
|
363
|
+
if (bytes.length < 30 || ascii(bytes, 0, 4) !== "RIFF" || ascii(bytes, 8, 4) !== "WEBP") return null;
|
|
364
|
+
const chunk = ascii(bytes, 12, 4);
|
|
365
|
+
const size = u32le(bytes, 16);
|
|
366
|
+
const data = 20;
|
|
367
|
+
if (chunk === "VP8 ") {
|
|
368
|
+
if (size < 10 || data + 10 > bytes.length) return null;
|
|
369
|
+
if (bytes[data + 3] !== 157 || bytes[data + 4] !== 1 || bytes[data + 5] !== 42) return null;
|
|
370
|
+
const width = u16le(bytes, data + 6) & 16383;
|
|
371
|
+
const height = u16le(bytes, data + 8) & 16383;
|
|
372
|
+
if (width === 0 || height === 0) return null;
|
|
373
|
+
return { mimeType: "image/webp", width, height };
|
|
374
|
+
}
|
|
375
|
+
if (chunk === "VP8L") {
|
|
376
|
+
if (size < 5 || data + 5 > bytes.length || bytes[data] !== 47) return null;
|
|
377
|
+
const bits = u32le(bytes, data + 1);
|
|
378
|
+
return { mimeType: "image/webp", width: (bits & 16383) + 1, height: (bits >>> 14 & 16383) + 1 };
|
|
379
|
+
}
|
|
380
|
+
if (chunk === "VP8X") {
|
|
381
|
+
if (size < 10 || data + 10 > bytes.length) return null;
|
|
382
|
+
return { mimeType: "image/webp", width: u24le(bytes, data + 4) + 1, height: u24le(bytes, data + 7) + 1 };
|
|
383
|
+
}
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
function readImageHeader(bytes) {
|
|
387
|
+
return png(bytes) ?? jpeg(bytes) ?? webp(bytes);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ../execution/render-harness/src/sceneShotAssets.ts
|
|
391
|
+
function localHandleReader(opts) {
|
|
392
|
+
return async (handle) => {
|
|
393
|
+
if (opts.baseUrl && opts.workDir && handle.startsWith(`${opts.baseUrl}/`)) {
|
|
394
|
+
const name = decodeURIComponent(handle.slice(opts.baseUrl.length + 1).split("?")[0]);
|
|
395
|
+
return readFile(join4(opts.workDir, name));
|
|
396
|
+
}
|
|
397
|
+
if (handle.startsWith("file://")) return readFile(fileURLToPath(handle));
|
|
398
|
+
if (handle.startsWith("/")) return readFile(handle);
|
|
399
|
+
let url;
|
|
400
|
+
try {
|
|
401
|
+
url = new URL(handle);
|
|
402
|
+
} catch {
|
|
403
|
+
throw new Error(`handle "${handle}" is not a readable local asset`);
|
|
404
|
+
}
|
|
405
|
+
if ((url.protocol === "http:" || url.protocol === "https:") && ["127.0.0.1", "localhost", "[::1]"].includes(url.hostname)) {
|
|
406
|
+
const response = await fetch(handle);
|
|
407
|
+
if (!response.ok) throw new Error(`loopback fetch ${response.status} for ${handle}`);
|
|
408
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
409
|
+
}
|
|
410
|
+
throw new Error(`handle "${handle}" is not a readable local asset`);
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
async function verifySceneShotAssetBytes(renderInput, read) {
|
|
414
|
+
for (const overlay of renderInput.overlays ?? []) {
|
|
415
|
+
if (overlay.template !== "component" || !overlay.sceneShot) continue;
|
|
416
|
+
const context = { stage: SCENE_SHOT_PREPARATION_STAGE, clipId: overlay.id, componentId: overlay.componentId };
|
|
417
|
+
for (const surface of overlay.sceneShot.plan.surfaces) {
|
|
418
|
+
if (surface.realized.source === "color") continue;
|
|
419
|
+
const slot = surface.slot;
|
|
420
|
+
const binding = surface.realized.source === "video" ? surface.realized.video : surface.realized.image;
|
|
421
|
+
const path = surface.path;
|
|
422
|
+
const handle = binding.handle;
|
|
423
|
+
if (typeof handle !== "string" || handle.length === 0) {
|
|
424
|
+
throw new CueframeError(
|
|
425
|
+
"component_asset_unavailable",
|
|
426
|
+
`Scene-shot preparation refused for clip '${overlay.id}': slot "${slot}" (at ${path}) has no bound screenshot handle after materialization.`,
|
|
427
|
+
void 0,
|
|
428
|
+
{ ...context, path, slot }
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
let bytes;
|
|
432
|
+
try {
|
|
433
|
+
bytes = await read(handle);
|
|
434
|
+
} catch (error) {
|
|
435
|
+
throw new CueframeError(
|
|
436
|
+
"component_asset_unavailable",
|
|
437
|
+
`Scene-shot preparation refused for clip '${overlay.id}': slot "${slot}" (at ${path}) could not be read for verification: ${error instanceof Error ? error.message : String(error)}.`,
|
|
438
|
+
void 0,
|
|
439
|
+
{ ...context, path, slot }
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
if (surface.realized.source === "video") {
|
|
443
|
+
const digest2 = createHash2("sha256").update(bytes).digest("hex");
|
|
444
|
+
if (bytes.byteLength !== surface.realized.video.byteLength || digest2 !== surface.realized.video.encodedSha256) throw new CueframeError("component_asset_integrity_failed", `Scene-shot preparation refused for clip '${overlay.id}': video slot "${slot}" (at ${path}) changed after PTS admission.`, void 0, { ...context, path, slot });
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
const header = readImageHeader(bytes);
|
|
448
|
+
if (!header) {
|
|
449
|
+
throw new CueframeError(
|
|
450
|
+
"component_asset_integrity_failed",
|
|
451
|
+
`Scene-shot preparation refused for clip '${overlay.id}': slot "${slot}" (at ${path}) is not an admitted image format; the bytes are not PNG, JPEG or WebP. GIF, SVG and video need an explicit conversion.`,
|
|
452
|
+
void 0,
|
|
453
|
+
{ ...context, path, slot }
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
if (header.mimeType !== binding.mimeType) {
|
|
457
|
+
throw new CueframeError(
|
|
458
|
+
"component_asset_integrity_failed",
|
|
459
|
+
`Scene-shot preparation refused for clip '${overlay.id}': slot "${slot}" (at ${path}) was admitted as ${binding.mimeType} but its bytes are ${header.mimeType}.`,
|
|
460
|
+
void 0,
|
|
461
|
+
{ ...context, path, slot, admitted: binding.mimeType, actual: header.mimeType }
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
if (header.width !== binding.width || header.height !== binding.height) {
|
|
465
|
+
throw new CueframeError(
|
|
466
|
+
"component_asset_integrity_failed",
|
|
467
|
+
`Scene-shot preparation refused for clip '${overlay.id}': slot "${slot}" (at ${path}) was admitted at ${binding.width}x${binding.height} but decodes to ${header.width}x${header.height}.`,
|
|
468
|
+
void 0,
|
|
469
|
+
{ ...context, path, slot, admitted: `${binding.width}x${binding.height}`, actual: `${header.width}x${header.height}` }
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// ../execution/render-harness/src/nodeScenePreparation.ts
|
|
477
|
+
import { createHash as createHash3 } from "crypto";
|
|
478
|
+
import { execFile as execFile2 } from "child_process";
|
|
479
|
+
import { promisify as promisify2 } from "util";
|
|
480
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
481
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
482
|
+
import sharp from "sharp";
|
|
483
|
+
function localPath(handle) {
|
|
484
|
+
if (handle.startsWith("file://")) return fileURLToPath2(handle);
|
|
485
|
+
if (handle.startsWith("/")) return handle;
|
|
486
|
+
throw new Error(`scene_component_asset_not_localized: ${handle}`);
|
|
487
|
+
}
|
|
488
|
+
async function digest(handle) {
|
|
489
|
+
let bytes;
|
|
490
|
+
if (/^http:\/\/(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?\//.test(handle)) {
|
|
491
|
+
const response = await fetch(handle);
|
|
492
|
+
if (!response.ok) throw new Error(`scene_component_asset_not_localized: loopback handle returned ${response.status}.`);
|
|
493
|
+
bytes = Buffer.from(await response.arrayBuffer());
|
|
494
|
+
} else {
|
|
495
|
+
bytes = await readFile2(localPath(handle));
|
|
496
|
+
}
|
|
497
|
+
return { bytes, sha256: createHash3("sha256").update(bytes).digest("hex") };
|
|
498
|
+
}
|
|
499
|
+
function matchingRow(input, componentId, sourceVersionId2) {
|
|
500
|
+
const rows = Object.values(input.componentSources ?? {}).filter(
|
|
501
|
+
(row) => row.source.componentId === componentId && row.sourceVersionId === sourceVersionId2
|
|
502
|
+
);
|
|
503
|
+
if (rows.length === 0) throw new Error(`scene_component_facts_missing: expected a pinned row for ${componentId}@${sourceVersionId2}.`);
|
|
504
|
+
const canonical = (row) => JSON.stringify({ source: row.source, assets: row.assets });
|
|
505
|
+
if (rows.some((row) => canonical(row) !== canonical(rows[0]))) {
|
|
506
|
+
throw new Error(`scene_component_facts_conflict: conflicting pinned rows for ${componentId}@${sourceVersionId2}.`);
|
|
507
|
+
}
|
|
508
|
+
return rows[0];
|
|
509
|
+
}
|
|
510
|
+
function selectNestedComponentRowV1(input, overlayId, path, componentId, sourceVersionId2, selections) {
|
|
511
|
+
const selectedKey = selections?.[overlayId]?.[path];
|
|
512
|
+
if (selectedKey) {
|
|
513
|
+
const selected = input.componentSources?.[selectedKey];
|
|
514
|
+
if (!selected || selected.source.componentId !== componentId || selected.sourceVersionId !== sourceVersionId2) throw new Error(`scene_component_facts_missing: selected row ${selectedKey} does not pin ${componentId}@${sourceVersionId2} for ${overlayId}:${path}.`);
|
|
515
|
+
return selected;
|
|
516
|
+
}
|
|
517
|
+
const candidates = Object.values(input.componentSources ?? {}).filter((row) => row.source.componentId === componentId && row.sourceVersionId === sourceVersionId2);
|
|
518
|
+
if (!candidates.length) throw new Error(`scene_component_facts_missing: no pinned row for ${componentId}@${sourceVersionId2} at ${overlayId}:${path}.`);
|
|
519
|
+
const assetless = candidates.every((row) => Object.keys(row.assets).length === 0 && Object.keys(row.source.manifest?.assets ?? {}).length === 0);
|
|
520
|
+
if (!assetless) throw new Error(`scene_component_asset_binding_required: ${overlayId}:${path} requires an explicit nested component row selection.`);
|
|
521
|
+
return matchingRow(input, componentId, sourceVersionId2);
|
|
522
|
+
}
|
|
523
|
+
async function stableAssetFacts(row) {
|
|
524
|
+
return Object.fromEntries(await Promise.all(Object.entries(row.assets).sort(([a], [b]) => a.localeCompare(b)).map(async ([slot, asset]) => {
|
|
525
|
+
const content = await digest(asset.handle);
|
|
526
|
+
if (asset.kind === "image") {
|
|
527
|
+
const metadata = await sharp(content.bytes).metadata();
|
|
528
|
+
const mime = metadata.format === "png" ? "image/png" : metadata.format === "jpeg" ? "image/jpeg" : metadata.format === "webp" ? "image/webp" : null;
|
|
529
|
+
if (mime !== asset.mimeType || metadata.width !== asset.width || metadata.height !== asset.height) {
|
|
530
|
+
throw new Error(`scene_component_asset_integrity_failed: pinned image ${slot} disagrees with decoded bytes.`);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return [slot, {
|
|
534
|
+
kind: asset.kind,
|
|
535
|
+
mimeType: asset.mimeType,
|
|
536
|
+
width: asset.width ?? null,
|
|
537
|
+
height: asset.height ?? null,
|
|
538
|
+
durationSec: asset.durationSec ?? null,
|
|
539
|
+
byteLength: content.bytes.byteLength,
|
|
540
|
+
encodedSha256: content.sha256
|
|
541
|
+
}];
|
|
542
|
+
})));
|
|
543
|
+
}
|
|
544
|
+
function componentBindings(objects, prefix = "layers") {
|
|
545
|
+
const found = [];
|
|
546
|
+
objects.forEach((object, index) => {
|
|
547
|
+
const path = `${prefix}.${index}`;
|
|
548
|
+
if (object.kind === "group") found.push(...componentBindings(object.children, `${path}.children`));
|
|
549
|
+
for (const [slot, binding] of Object.entries("surfaces" in object ? object.surfaces ?? {} : {})) {
|
|
550
|
+
if (binding.source === "component") found.push({ path: `${path}.surfaces.${slot}`, binding });
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
return found;
|
|
554
|
+
}
|
|
555
|
+
var execFileAsync = promisify2(execFile2);
|
|
556
|
+
async function nodeVideoPresentationFactsV1(handle, ffprobeExecutable = "ffprobe", signal) {
|
|
557
|
+
let raw;
|
|
558
|
+
try {
|
|
559
|
+
const source = /^http:\/\/(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?\//.test(handle) ? handle : localPath(handle);
|
|
560
|
+
raw = (await execFileAsync(ffprobeExecutable, ["-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width,height,time_base:frame=best_effort_timestamp", "-show_frames", "-of", "json", source], { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, timeout: 3e4, signal })).stdout;
|
|
561
|
+
} catch (error) {
|
|
562
|
+
throw new Error(`video_presentation_index_missing: ffprobe could not verify presentation timestamps. Render or transcode this asset to CFR with the existing media tools, then prepare the scene again.`, { cause: error });
|
|
563
|
+
}
|
|
564
|
+
const probe = JSON.parse(raw);
|
|
565
|
+
const stream = probe.streams?.[0];
|
|
566
|
+
const parts = stream?.time_base?.split("/").map(Number);
|
|
567
|
+
const pts = probe.frames?.map((frame) => Number(frame.best_effort_timestamp));
|
|
568
|
+
if (!stream || !parts || parts.length !== 2 || !pts || pts.some((value) => !Number.isSafeInteger(value))) throw new Error("video_presentation_index_missing: ffprobe returned no exact presentation-frame index. Render or transcode this asset to CFR with the existing media tools, then prepare the scene again.");
|
|
569
|
+
return { pts, timeBase: { num: parts[0], den: parts[1] }, width: stream.width, height: stream.height };
|
|
570
|
+
}
|
|
571
|
+
function nodePhotographicRigFactsV1(scene, width, height) {
|
|
572
|
+
if (scene.environment.kind !== "photographic-studio-v1") return null;
|
|
573
|
+
const facts = photographicSceneRigFactsV1(height / scene.referenceSize.height, width, height);
|
|
574
|
+
return { identity: JSON.parse(JSON.stringify(facts.identity)), allocations: facts.allocations.map((row) => ({ ...row })) };
|
|
575
|
+
}
|
|
576
|
+
function nodeCameraClipPlanesV1(scene, frame, durationInFrames, outputHeight) {
|
|
577
|
+
const scale = outputHeight / scene.referenceSize.height;
|
|
578
|
+
return sceneCameraPlanesV2(scene.referenceSize.height, evaluateScene(scene, frame, durationInFrames).camera.fov, scale);
|
|
579
|
+
}
|
|
580
|
+
function createNodeScenePreparationV1(options) {
|
|
581
|
+
const canonical = (value) => JSON.parse(JSON.stringify(value ?? {}));
|
|
582
|
+
const provider = createMaterializedSceneCaptureProvider({
|
|
583
|
+
workspace: options.workspace,
|
|
584
|
+
workspaceForSource: options.workspaceForSource,
|
|
585
|
+
renderEntryRoot: options.renderEntryRoot,
|
|
586
|
+
allowedAssetOrigins: options.allowedAssetOrigins,
|
|
587
|
+
publishVerifiedPng: options.publishVerifiedPng,
|
|
588
|
+
async resolveAssets(intent) {
|
|
589
|
+
const candidates = Object.values(options.input.componentSources ?? {}).filter((row2) => row2.source.componentId === intent.componentId && row2.sourceVersionId === intent.sourceVersionId);
|
|
590
|
+
const matching = [];
|
|
591
|
+
for (const candidate of candidates) if (JSON.stringify(await stableAssetFacts(candidate)) === JSON.stringify(intent.assetBindings)) matching.push(candidate);
|
|
592
|
+
if (!matching.length) throw new Error(`scene_component_asset_integrity_failed: no localized row matches the sealed asset facts for ${intent.componentId}@${intent.sourceVersionId}.`);
|
|
593
|
+
const row = matching[0];
|
|
594
|
+
return Object.fromEntries(Object.entries(row.assets).map(([slot, asset]) => [slot, asset.handle]));
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
const outputHeight = options.input.outputHeight ?? options.input.height;
|
|
598
|
+
const descriptors = createSceneBuilderDescriptorRegistryV1((object, context) => {
|
|
599
|
+
if (object.kind === "group" || object.kind === "text" && object.space === "screen") return null;
|
|
600
|
+
return scenePresetBuilderDescriptorV1(object, context);
|
|
601
|
+
});
|
|
602
|
+
const dependencies = {
|
|
603
|
+
descriptors,
|
|
604
|
+
async resolveComponentFacts(scene, { overlay }) {
|
|
605
|
+
const facts = {};
|
|
606
|
+
for (const { path, binding } of componentBindings(scene.layers)) {
|
|
607
|
+
const row = selectNestedComponentRowV1(options.input, overlay.id, path, binding.component.componentId, binding.component.sourceVersionId, options.nestedComponentRowKeys);
|
|
608
|
+
const execution = await provider.resolveExecutionFacts(binding.component);
|
|
609
|
+
const assets = await stableAssetFacts(row);
|
|
610
|
+
facts[path] = {
|
|
611
|
+
durationInFrames: overlay.durationInFrames,
|
|
612
|
+
seed: `${binding.component.componentId}:${binding.component.sourceVersionId}`,
|
|
613
|
+
params: binding.params ?? {},
|
|
614
|
+
assetBindings: assets,
|
|
615
|
+
brandFacts: canonical(options.input.brandKit),
|
|
616
|
+
fontFacts: canonical(options.input.brandKit?.fontAssets ?? []),
|
|
617
|
+
mediaFacts: assets,
|
|
618
|
+
...execution
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
return facts;
|
|
622
|
+
},
|
|
623
|
+
resolveRigFacts(scene, bounds) {
|
|
624
|
+
const width = options.input.outputWidth ?? options.input.width;
|
|
625
|
+
if (scene.environment.kind !== "photographic-studio-v1") return generatedStudioPreparationFactsV1(scene.environment, outputHeight / scene.referenceSize.height, bounds, width, outputHeight);
|
|
626
|
+
return nodePhotographicRigFactsV1(scene, width, outputHeight);
|
|
627
|
+
},
|
|
628
|
+
resolveCameraClipPlanes(scene, frame, durationInFrames) {
|
|
629
|
+
return nodeCameraClipPlanesV1(scene, frame, durationInFrames, outputHeight);
|
|
630
|
+
},
|
|
631
|
+
realization: {
|
|
632
|
+
capture: provider,
|
|
633
|
+
async sha256(value) {
|
|
634
|
+
return createHash3("sha256").update(value).digest("hex");
|
|
635
|
+
},
|
|
636
|
+
async resolveImage() {
|
|
637
|
+
return null;
|
|
638
|
+
},
|
|
639
|
+
async resolveVideo() {
|
|
640
|
+
return null;
|
|
641
|
+
},
|
|
642
|
+
signal: options.signal
|
|
643
|
+
},
|
|
644
|
+
realizationForOverlay({ input, overlay }) {
|
|
645
|
+
const row = input.componentSources?.[overlay.id];
|
|
646
|
+
if (!row) throw new Error(`scene_component_facts_missing: no pinned row for clip ${overlay.id}.`);
|
|
647
|
+
return {
|
|
648
|
+
capture: provider,
|
|
649
|
+
async sha256(value) {
|
|
650
|
+
return createHash3("sha256").update(value).digest("hex");
|
|
651
|
+
},
|
|
652
|
+
async resolveImage(binding) {
|
|
653
|
+
const asset = row.assets[binding.assetSlot];
|
|
654
|
+
if (!asset || !["image/png", "image/jpeg", "image/webp"].includes(asset.mimeType)) return null;
|
|
655
|
+
const encoded = await digest(asset.handle);
|
|
656
|
+
const image = sharp(encoded.bytes);
|
|
657
|
+
const metadata = await image.metadata();
|
|
658
|
+
const actualMime = metadata.format === "png" ? "image/png" : metadata.format === "jpeg" ? "image/jpeg" : metadata.format === "webp" ? "image/webp" : null;
|
|
659
|
+
if (actualMime !== asset.mimeType || metadata.width !== asset.width || metadata.height !== asset.height) {
|
|
660
|
+
throw new Error(`scene_image_facts_missing: clip ${overlay.id} slot ${binding.assetSlot} disagrees with decoded bytes.`);
|
|
661
|
+
}
|
|
662
|
+
const decoded = await image.ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
663
|
+
return { image: {
|
|
664
|
+
handle: asset.handle,
|
|
665
|
+
mimeType: actualMime,
|
|
666
|
+
byteLength: encoded.bytes.byteLength,
|
|
667
|
+
width: decoded.info.width,
|
|
668
|
+
height: decoded.info.height,
|
|
669
|
+
decodedSha256: createHash3("sha256").update(decoded.data).digest("hex")
|
|
670
|
+
}, release: async () => {
|
|
671
|
+
} };
|
|
672
|
+
},
|
|
673
|
+
signal: options.signal,
|
|
674
|
+
async resolveVideo(binding, _path, signal) {
|
|
675
|
+
const asset = row.assets[binding.mediaId];
|
|
676
|
+
if (!asset || asset.kind !== "video" || !["video/mp4", "video/webm"].includes(asset.mimeType)) return null;
|
|
677
|
+
const encoded = await digest(asset.handle);
|
|
678
|
+
const probe = await nodeVideoPresentationFactsV1(asset.handle, options.ffprobeExecutable, signal);
|
|
679
|
+
if (probe.width !== asset.width || probe.height !== asset.height) throw new Error(`scene_video_facts_missing: clip ${overlay.id} media ${binding.mediaId} disagrees with decoded dimensions.`);
|
|
680
|
+
return { video: { handle: asset.handle, mimeType: asset.mimeType, byteLength: encoded.bytes.byteLength, width: probe.width, height: probe.height, encodedSha256: encoded.sha256, presentationIndex: { pts: probe.pts, timeBase: probe.timeBase } }, release: async () => {
|
|
681
|
+
} };
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
return { dependencies, close: () => provider.close() };
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// ../execution/render-harness/src/materializeSources.ts
|
|
690
|
+
function materializedCaptureFilename(png2, encoded) {
|
|
691
|
+
const encodedSha256 = createHash4("sha256").update(encoded).digest("hex");
|
|
692
|
+
return `scene-capture-${png2.decodedSha256}-${encodedSha256}.png`;
|
|
693
|
+
}
|
|
694
|
+
async function verifyDecodedComponentStill(png2, expected) {
|
|
695
|
+
const bytes = await localHandleReader({})(png2.handle);
|
|
696
|
+
const encodedSha256 = createHash4("sha256").update(bytes).digest("hex");
|
|
697
|
+
if (bytes.byteLength !== png2.byteLength || encodedSha256 !== png2.encodedSha256) {
|
|
698
|
+
throw new Error("scene_component_capture_integrity_failed: captured PNG bytes changed before decode.");
|
|
699
|
+
}
|
|
700
|
+
let decoded;
|
|
701
|
+
try {
|
|
702
|
+
decoded = await sharp2(bytes).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
703
|
+
} catch (error) {
|
|
704
|
+
throw new Error(
|
|
705
|
+
`scene_component_capture_decode_failed: ${error instanceof Error ? error.message : String(error)}`
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
const { width, height } = decoded.info;
|
|
709
|
+
if (width !== png2.width || height !== png2.height || width !== expected.width || height !== expected.height) {
|
|
710
|
+
throw new Error(
|
|
711
|
+
`scene_component_capture_dimensions_mismatch: expected ${expected.width}x${expected.height}, runtime reported ${png2.width}x${png2.height}, decoded ${width}x${height}.`
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
return {
|
|
715
|
+
handle: png2.handle,
|
|
716
|
+
mimeType: "image/png",
|
|
717
|
+
byteLength: bytes.byteLength,
|
|
718
|
+
width,
|
|
719
|
+
height,
|
|
720
|
+
decodedSha256: createHash4("sha256").update(decoded.data).digest("hex")
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
function abortError() {
|
|
724
|
+
const error = new Error("scene_component_capture_cancelled");
|
|
725
|
+
error.name = "AbortError";
|
|
726
|
+
return error;
|
|
727
|
+
}
|
|
728
|
+
function throwIfAborted(signal) {
|
|
729
|
+
if (signal?.aborted) throw abortError();
|
|
730
|
+
}
|
|
731
|
+
function captureSessionKey(intent) {
|
|
732
|
+
return JSON.stringify({
|
|
733
|
+
componentId: intent.componentId,
|
|
734
|
+
sourceVersionId: intent.sourceVersionId,
|
|
735
|
+
layoutWidth: intent.layoutWidth,
|
|
736
|
+
layoutHeight: intent.layoutHeight,
|
|
737
|
+
bakeScale: intent.bakeScale,
|
|
738
|
+
durationInFrames: intent.durationInFrames,
|
|
739
|
+
fps: intent.fps,
|
|
740
|
+
requestedGlBackend: intent.requestedGlBackend,
|
|
741
|
+
runtimeIdentity: intent.runtimeIdentity,
|
|
742
|
+
dependencyIdentity: intent.dependencyIdentity,
|
|
743
|
+
rasterAffectingFlags: intent.rasterAffectingFlags
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
function stableJson(value) {
|
|
747
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
748
|
+
if (value !== null && typeof value === "object") {
|
|
749
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
|
|
750
|
+
}
|
|
751
|
+
return JSON.stringify(value);
|
|
752
|
+
}
|
|
753
|
+
function createMaterializedSceneCaptureProvider(options) {
|
|
754
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
755
|
+
const captures = /* @__PURE__ */ new Map();
|
|
756
|
+
const createSession = options.createSession ?? createComponentStillSession;
|
|
757
|
+
const resolveDependencyIdentity = options.resolveDependencyIdentity ?? componentStillDependencyIdentity;
|
|
758
|
+
let closed = false;
|
|
759
|
+
let closePromise = null;
|
|
760
|
+
const source = (componentId, expectedSourceVersionId) => {
|
|
761
|
+
const workspace = options.workspaceForSource?.(componentId, expectedSourceVersionId) ?? options.workspace;
|
|
762
|
+
const materialized = readMaterializedComponentSource(workspace, componentId);
|
|
763
|
+
if (!materialized) throw new Error(`scene_component_source_unavailable: ${componentId}`);
|
|
764
|
+
const actualSourceVersionId = sourceVersionId(materialized);
|
|
765
|
+
if (expectedSourceVersionId !== actualSourceVersionId) {
|
|
766
|
+
throw new Error(
|
|
767
|
+
`scene_component_source_pin_mismatch: ${componentId} expected ${expectedSourceVersionId}, actual ${actualSourceVersionId}`
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
return { materialized, actualSourceVersionId, workspace };
|
|
771
|
+
};
|
|
772
|
+
const resolveExecutionFacts = async (request, signal) => {
|
|
773
|
+
throwIfAborted(signal);
|
|
774
|
+
const { materialized } = source(request.componentId, request.sourceVersionId);
|
|
775
|
+
const graphics = materialized.manifest.graphics;
|
|
776
|
+
const renderEntryRoot = resolveRenderEntryRoot(options.renderEntryRoot);
|
|
777
|
+
const dependencyIdentity = await resolveDependencyIdentity(
|
|
778
|
+
renderEntryRoot
|
|
779
|
+
);
|
|
780
|
+
throwIfAborted(signal);
|
|
781
|
+
return {
|
|
782
|
+
runtimeIdentity: COMPONENT_STILL_RUNTIME_IDENTITY,
|
|
783
|
+
dependencyIdentity,
|
|
784
|
+
requestedGlBackend: componentBrowserBackend(graphics).chromiumOptions.gl,
|
|
785
|
+
rasterAffectingFlags: componentStillRasterAffectingFlags(graphics)
|
|
786
|
+
};
|
|
787
|
+
};
|
|
788
|
+
const provider = {
|
|
789
|
+
resolveExecutionFacts,
|
|
790
|
+
async openSession(rawIntent, signal) {
|
|
791
|
+
if (closed) throw new Error("scene_component_capture_provider_closed");
|
|
792
|
+
throwIfAborted(signal);
|
|
793
|
+
const intent = parseSceneComponentCaptureIntentV1(rawIntent);
|
|
794
|
+
if (intent.params === null || Array.isArray(intent.params) || typeof intent.params !== "object") {
|
|
795
|
+
throw new Error("scene_component_params_invalid: params must be an object.");
|
|
796
|
+
}
|
|
797
|
+
const execution = await resolveExecutionFacts(intent, signal);
|
|
798
|
+
if (closed) throw new Error("scene_component_capture_provider_closed");
|
|
799
|
+
for (const field of ["runtimeIdentity", "dependencyIdentity", "requestedGlBackend", "rasterAffectingFlags"]) {
|
|
800
|
+
if (stableJson(intent[field]) !== stableJson(execution[field])) {
|
|
801
|
+
throw new Error(`scene_component_execution_fact_mismatch: ${field}`);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
const { materialized, workspace } = source(intent.componentId, intent.sourceVersionId);
|
|
805
|
+
const key = captureSessionKey(intent);
|
|
806
|
+
let opened = sessions.get(key);
|
|
807
|
+
if (!opened) {
|
|
808
|
+
opened = (async () => {
|
|
809
|
+
const session = await createSession({
|
|
810
|
+
ws: workspace,
|
|
811
|
+
id: intent.componentId,
|
|
812
|
+
params: intent.params,
|
|
813
|
+
assets: await options.resolveAssets(intent),
|
|
814
|
+
seed: intent.seed,
|
|
815
|
+
graphics: materialized.manifest.graphics,
|
|
816
|
+
width: intent.layoutWidth,
|
|
817
|
+
height: intent.layoutHeight,
|
|
818
|
+
scale: intent.bakeScale,
|
|
819
|
+
fps: intent.fps.num / intent.fps.den,
|
|
820
|
+
durationInFrames: intent.durationInFrames,
|
|
821
|
+
revision: intent.sourceVersionId,
|
|
822
|
+
renderEntryRoot: options.renderEntryRoot,
|
|
823
|
+
allowedAssetOrigins: options.allowedAssetOrigins,
|
|
824
|
+
captureAttestation: true
|
|
825
|
+
});
|
|
826
|
+
return session;
|
|
827
|
+
})();
|
|
828
|
+
sessions.set(key, opened);
|
|
829
|
+
void opened.catch(() => sessions.delete(key));
|
|
830
|
+
}
|
|
831
|
+
const runtimeSession = await opened;
|
|
832
|
+
throwIfAborted(signal);
|
|
833
|
+
return {
|
|
834
|
+
async capture(nextRaw, captureSignal) {
|
|
835
|
+
if (closed) throw new Error("scene_component_capture_provider_closed");
|
|
836
|
+
throwIfAborted(captureSignal);
|
|
837
|
+
const next = parseSceneComponentCaptureIntentV1(nextRaw);
|
|
838
|
+
if (captureSessionKey(next) !== key) {
|
|
839
|
+
throw new Error("scene_component_capture_session_mismatch");
|
|
840
|
+
}
|
|
841
|
+
const captureKey = stableJson(next);
|
|
842
|
+
let pending = captures.get(captureKey);
|
|
843
|
+
if (!pending) {
|
|
844
|
+
pending = (async () => {
|
|
845
|
+
const rendered = await runtimeSession.renderVerifiedFrame({
|
|
846
|
+
frame: next.captureFrame,
|
|
847
|
+
params: next.params,
|
|
848
|
+
assets: await options.resolveAssets(next),
|
|
849
|
+
seed: next.seed,
|
|
850
|
+
expectedRevision: next.sourceVersionId
|
|
851
|
+
});
|
|
852
|
+
let png2 = await verifyDecodedComponentStill(rendered.png, {
|
|
853
|
+
width: next.rasterWidth,
|
|
854
|
+
height: next.rasterHeight
|
|
855
|
+
});
|
|
856
|
+
if (options.publishVerifiedPng) png2 = await options.publishVerifiedPng(png2);
|
|
857
|
+
return { attestation: rendered.attestation, png: png2, cacheScope: "session" };
|
|
858
|
+
})();
|
|
859
|
+
captures.set(captureKey, pending);
|
|
860
|
+
void pending.catch(() => captures.delete(captureKey));
|
|
861
|
+
}
|
|
862
|
+
const result = await pending;
|
|
863
|
+
throwIfAborted(captureSignal);
|
|
864
|
+
return result;
|
|
865
|
+
},
|
|
866
|
+
// The provider owns this shared browser across preparation leases. Consumer cleanup calls
|
|
867
|
+
// provider.close after every plan using its retained handles has finished.
|
|
868
|
+
async close() {
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
},
|
|
872
|
+
async close() {
|
|
873
|
+
if (closePromise) return closePromise;
|
|
874
|
+
closed = true;
|
|
875
|
+
closePromise = (async () => {
|
|
876
|
+
const opened = await Promise.allSettled(sessions.values());
|
|
877
|
+
const cancellation = Promise.allSettled(
|
|
878
|
+
opened.flatMap((result) => result.status === "fulfilled" ? [result.value.cancel()] : [])
|
|
879
|
+
);
|
|
880
|
+
const [completedCaptures, cleanup] = await Promise.all([
|
|
881
|
+
Promise.allSettled(captures.values()),
|
|
882
|
+
cancellation
|
|
883
|
+
]);
|
|
884
|
+
sessions.clear();
|
|
885
|
+
captures.clear();
|
|
886
|
+
const failures = [
|
|
887
|
+
...completedCaptures.flatMap((result) => result.status === "rejected" ? [result.reason] : []),
|
|
888
|
+
...opened.flatMap((result) => result.status === "rejected" ? [result.reason] : []),
|
|
889
|
+
...cleanup.flatMap((result) => result.status === "rejected" && result.reason?.code !== "ENOENT" ? [result.reason] : [])
|
|
890
|
+
];
|
|
891
|
+
if (failures.length) throw new AggregateError(failures, "scene_component_capture_cleanup_failed");
|
|
892
|
+
})();
|
|
893
|
+
return closePromise;
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
return provider;
|
|
897
|
+
}
|
|
235
898
|
function localFilePath(u) {
|
|
236
899
|
if (typeof u !== "string" || u.length === 0) return null;
|
|
237
900
|
if (/^https?:\/\//i.test(u)) return null;
|
|
238
901
|
let p;
|
|
239
|
-
if (u.startsWith("file://")) p =
|
|
902
|
+
if (u.startsWith("file://")) p = fileURLToPath3(u);
|
|
240
903
|
else if (u.startsWith("/")) p = u;
|
|
241
904
|
else return null;
|
|
242
905
|
return existsSync4(p) ? p : null;
|
|
@@ -247,122 +910,200 @@ function hasLocalFileRefs(input) {
|
|
|
247
910
|
}
|
|
248
911
|
return false;
|
|
249
912
|
}
|
|
250
|
-
async function httpDownload(url, destPath) {
|
|
251
|
-
const r = await fetch(url);
|
|
913
|
+
async function httpDownload(url, destPath, signal) {
|
|
914
|
+
const r = await fetch(url, { signal });
|
|
252
915
|
if (!r.ok) throw new Error(`download ${r.status} for ${assetUrlKey(url)}`);
|
|
253
916
|
if (!r.body) throw new Error(`download empty body for ${assetUrlKey(url)}`);
|
|
254
917
|
await pipeline(
|
|
255
918
|
Readable.fromWeb(r.body),
|
|
256
|
-
createWriteStream(destPath)
|
|
919
|
+
createWriteStream(destPath),
|
|
920
|
+
{ signal }
|
|
257
921
|
);
|
|
258
922
|
}
|
|
923
|
+
function admitSceneMaterializationInput(renderInput) {
|
|
924
|
+
let found = false;
|
|
925
|
+
for (const overlay of renderInput.overlays ?? []) {
|
|
926
|
+
const row = renderInput.componentSources?.[overlay.id];
|
|
927
|
+
const authoredVersion = overlay.params?.scene?.version;
|
|
928
|
+
const declaredVersion = row?.source.manifest?.sceneShot?.version;
|
|
929
|
+
if (authoredVersion !== 2 && declaredVersion === void 0) continue;
|
|
930
|
+
found = true;
|
|
931
|
+
if (!overlay.componentId || !overlay.sourceVersionId || !row || row.source.componentId !== overlay.componentId || row.sourceVersionId !== overlay.sourceVersionId) {
|
|
932
|
+
throw new Error(`scene_component_facts_missing: pinned source facts do not match scene candidate ${overlay.id}.`);
|
|
933
|
+
}
|
|
934
|
+
if (!readSceneShotManifest(row.source.manifest, { clipId: overlay.id, componentId: overlay.componentId })) {
|
|
935
|
+
throw new Error(`scene_component_facts_missing: ${overlay.id} does not declare a scene source.`);
|
|
936
|
+
}
|
|
937
|
+
parseSceneShotSpecV2(overlay.params.scene);
|
|
938
|
+
}
|
|
939
|
+
return found;
|
|
940
|
+
}
|
|
259
941
|
async function materializeSources(renderInput, workDir, log = () => {
|
|
260
|
-
}) {
|
|
942
|
+
}, options = {}) {
|
|
943
|
+
throwIfAborted(options.signal);
|
|
261
944
|
assertCardHtmlAssetFree(renderInput);
|
|
262
|
-
|
|
945
|
+
const needsScenePreparation = admitSceneMaterializationInput(renderInput);
|
|
946
|
+
if (!needsScenePreparation && renderInputAssets(renderInput).length === 0 && !hasLocalFileRefs(renderInput)) {
|
|
947
|
+
await verifySceneShotAssetBytes(renderInput, localHandleReader({}));
|
|
263
948
|
return { renderInput, close: async () => {
|
|
264
949
|
} };
|
|
265
950
|
}
|
|
266
951
|
await mkdir(workDir, { recursive: true });
|
|
267
952
|
const server = startMediaServer(workDir);
|
|
268
953
|
const fps = Number(renderInput.fps) || 30;
|
|
269
|
-
const cleanups = [
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
padding: PADDING
|
|
294
|
-
});
|
|
295
|
-
cleanups.push(cleanup);
|
|
296
|
-
log(`[materialize] range-read-trimmed ${Object.keys(segments).length} source(s)`);
|
|
297
|
-
const servedById = {};
|
|
298
|
-
for (const [id, segPath] of Object.entries(segments)) {
|
|
299
|
-
const fname = `${id}.seg.mp4`;
|
|
300
|
-
await copyFile(segPath, join4(workDir, fname));
|
|
301
|
-
servedById[id] = fname;
|
|
302
|
-
}
|
|
303
|
-
for (const clip of remoteClips) {
|
|
304
|
-
const id = idByKey.get(assetUrlKey(clip.src));
|
|
305
|
-
if (!id || !servedById[id]) {
|
|
306
|
-
throw new Error(
|
|
307
|
-
`source trim failed for ${assetUrlKey(clip.src)} \u2014 video source not range-readable`
|
|
308
|
-
);
|
|
954
|
+
const cleanups = [async () => {
|
|
955
|
+
server.close();
|
|
956
|
+
}];
|
|
957
|
+
let closePromise = null;
|
|
958
|
+
const cleanupAll = () => closePromise ??= Promise.allSettled([...cleanups].reverse().map((cleanup) => cleanup())).then((results) => {
|
|
959
|
+
const failures = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
960
|
+
if (failures.length) throw new AggregateError(failures, "materialize_sources_cleanup_failed");
|
|
961
|
+
});
|
|
962
|
+
try {
|
|
963
|
+
const clips = renderInput.clips ?? [];
|
|
964
|
+
const remoteClips = clips.filter(
|
|
965
|
+
(c) => isRemoteUrl(c.src) && (c.mediaType === void 0 || c.mediaType === "video")
|
|
966
|
+
);
|
|
967
|
+
if (remoteClips.length > 0) {
|
|
968
|
+
const PADDING = 1;
|
|
969
|
+
const sourceUrls = {};
|
|
970
|
+
const idByKey = /* @__PURE__ */ new Map();
|
|
971
|
+
let i = 0;
|
|
972
|
+
for (const clip of remoteClips) {
|
|
973
|
+
const key = assetUrlKey(clip.src);
|
|
974
|
+
if (idByKey.has(key)) continue;
|
|
975
|
+
const id = `src${i++}`;
|
|
976
|
+
sourceUrls[id] = clip.src;
|
|
977
|
+
idByKey.set(key, id);
|
|
309
978
|
}
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
979
|
+
const ranges = remoteClips.map((c) => {
|
|
980
|
+
const id = idByKey.get(assetUrlKey(c.src));
|
|
981
|
+
const sourceInSec = (Number(c.sourceInFrames) || 0) / fps;
|
|
982
|
+
const durSec = (Number(c.durationInFrames) || 0) / fps;
|
|
983
|
+
return { poolItemId: id, sourceIn: sourceInSec, sourceOut: sourceInSec + durSec };
|
|
984
|
+
});
|
|
985
|
+
const { segments, origins, cleanup } = await extractSegments(ranges, sourceUrls, {
|
|
986
|
+
padding: PADDING,
|
|
987
|
+
signal: options.signal
|
|
988
|
+
});
|
|
989
|
+
cleanups.push(cleanup);
|
|
990
|
+
log(`[materialize] range-read-trimmed ${Object.keys(segments).length} source(s)`);
|
|
991
|
+
const servedById = {};
|
|
992
|
+
for (const [id, segPath] of Object.entries(segments)) {
|
|
993
|
+
throwIfAborted(options.signal);
|
|
994
|
+
const fname = `${id}.seg.mp4`;
|
|
995
|
+
await copyFile(segPath, join5(workDir, fname));
|
|
996
|
+
throwIfAborted(options.signal);
|
|
997
|
+
servedById[id] = fname;
|
|
998
|
+
}
|
|
999
|
+
for (const clip of remoteClips) {
|
|
1000
|
+
const id = idByKey.get(assetUrlKey(clip.src));
|
|
1001
|
+
if (!id || !servedById[id]) {
|
|
1002
|
+
throw new Error(
|
|
1003
|
+
`source trim failed for ${assetUrlKey(clip.src)} \u2014 video source not range-readable`
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
const shiftFrames = Math.round((origins[id] ?? 0) * fps);
|
|
1007
|
+
if (shiftFrames !== 0) {
|
|
1008
|
+
clip.sourceInFrames = (Number(clip.sourceInFrames) || 0) - shiftFrames;
|
|
1009
|
+
clip.trimStartFrames = (Number(clip.trimStartFrames) || 0) - shiftFrames;
|
|
1010
|
+
if (typeof clip.sourceOutFrames === "number") {
|
|
1011
|
+
clip.sourceOutFrames -= shiftFrames;
|
|
1012
|
+
}
|
|
316
1013
|
}
|
|
1014
|
+
clip.src = `${server.baseUrl}/${servedById[id]}`;
|
|
317
1015
|
}
|
|
318
|
-
clip.src = `${server.baseUrl}/${servedById[id]}`;
|
|
319
1016
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
1017
|
+
const assets = await resolveAssets(renderInput, workDir, server.baseUrl, httpDownload, options.signal);
|
|
1018
|
+
if (assets.count > 0) log(`[materialize] resolved ${assets.count} overlay/audio asset(s)`);
|
|
1019
|
+
const remaining = renderInputAssets(renderInput);
|
|
1020
|
+
if (remaining.length > 0) {
|
|
1021
|
+
const localByKey = /* @__PURE__ */ new Map();
|
|
1022
|
+
for (const ref of remaining) {
|
|
1023
|
+
await httpDownload(ref.url, join5(workDir, ref.filename), options.signal);
|
|
1024
|
+
localByKey.set(assetUrlKey(ref.url), `${server.baseUrl}/${ref.filename}`);
|
|
1025
|
+
}
|
|
1026
|
+
for (const slot of assetSlots(renderInput)) {
|
|
1027
|
+
const url = slot.get();
|
|
1028
|
+
if (typeof url !== "string" || !isRemoteUrl(url)) continue;
|
|
1029
|
+
const local = localByKey.get(assetUrlKey(url));
|
|
1030
|
+
if (local) slot.set(local);
|
|
1031
|
+
}
|
|
1032
|
+
log(`[materialize] downloaded ${remaining.length} matte/trajectory/other asset(s)`);
|
|
329
1033
|
}
|
|
1034
|
+
const bundledFonts = {
|
|
1035
|
+
"/fonts/zodiak.woff2": "81bf124d17416df8fb656393c46fb34bb74e5d472f07cec9ab295269f372098a",
|
|
1036
|
+
"/fonts/dm-sans.woff2": "468d56b6b25b05b70190b6c233d773f6f1770e8579827ce022a57f03fa8002fb"
|
|
1037
|
+
};
|
|
1038
|
+
const admittedRenderEntryRoot = options.renderEntryRoot ?? process.env.RENDER_ENTRY_ROOT;
|
|
1039
|
+
const renderEntryPublic = admittedRenderEntryRoot ? join5(admittedRenderEntryRoot, "public") : null;
|
|
330
1040
|
for (const slot of assetSlots(renderInput)) {
|
|
331
1041
|
const url = slot.get();
|
|
332
|
-
if (typeof url !== "string" || !
|
|
333
|
-
|
|
334
|
-
|
|
1042
|
+
if (slot.role !== "font" || typeof url !== "string" || !(url in bundledFonts)) continue;
|
|
1043
|
+
if (!renderEntryPublic) throw new Error(`font_not_reproducible: App font '${url}' has no packaged render-entry root.`);
|
|
1044
|
+
const source = join5(renderEntryPublic, url.slice(1));
|
|
1045
|
+
const bytes = await readFile3(source);
|
|
1046
|
+
const observed = createHash4("sha256").update(bytes).digest("hex");
|
|
1047
|
+
if (observed !== bundledFonts[url]) {
|
|
1048
|
+
throw new Error(`font_not_reproducible: App font '${url}' digest mismatch (${observed}).`);
|
|
1049
|
+
}
|
|
1050
|
+
const filename = `app-font-${basename(url)}`;
|
|
1051
|
+
await copyFile(source, join5(workDir, filename));
|
|
1052
|
+
throwIfAborted(options.signal);
|
|
1053
|
+
slot.set(`${server.baseUrl}/${filename}`);
|
|
335
1054
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
1055
|
+
const localByPath = /* @__PURE__ */ new Map();
|
|
1056
|
+
for (const slot of assetSlots(renderInput)) {
|
|
1057
|
+
throwIfAborted(options.signal);
|
|
1058
|
+
const p = localFilePath(slot.get());
|
|
1059
|
+
if (!p) continue;
|
|
1060
|
+
let served = localByPath.get(p);
|
|
1061
|
+
if (!served) {
|
|
1062
|
+
const fname = `local-${localByPath.size}-${basename(p)}`;
|
|
1063
|
+
await copyFile(p, join5(workDir, fname));
|
|
1064
|
+
throwIfAborted(options.signal);
|
|
1065
|
+
served = `${server.baseUrl}/${fname}`;
|
|
1066
|
+
localByPath.set(p, served);
|
|
1067
|
+
}
|
|
1068
|
+
slot.set(served);
|
|
348
1069
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
1070
|
+
if (localByPath.size > 0) log(`[materialize] served ${localByPath.size} local-file asset(s) over loopback`);
|
|
1071
|
+
if (needsScenePreparation) {
|
|
1072
|
+
throwIfAborted(options.signal);
|
|
1073
|
+
if (!options.workspace) throw new Error("scene_prepared_plan_required: a workspace is required for V2 scene materialization.");
|
|
1074
|
+
const host = createNodeScenePreparationV1({
|
|
1075
|
+
...options,
|
|
1076
|
+
input: renderInput,
|
|
1077
|
+
workspace: options.workspace,
|
|
1078
|
+
async publishVerifiedPng(png2) {
|
|
1079
|
+
throwIfAborted(options.signal);
|
|
1080
|
+
const encoded = await readFile3(png2.handle);
|
|
1081
|
+
throwIfAborted(options.signal);
|
|
1082
|
+
const filename = materializedCaptureFilename(png2, encoded);
|
|
1083
|
+
await copyFile(png2.handle, join5(workDir, filename));
|
|
1084
|
+
throwIfAborted(options.signal);
|
|
1085
|
+
return { ...png2, handle: `${server.baseUrl}/${filename}` };
|
|
1086
|
+
}
|
|
358
1087
|
});
|
|
1088
|
+
cleanups.push(host.close);
|
|
1089
|
+
const prepared = await prepareSceneShotRenderInput(renderInput, host.dependencies);
|
|
1090
|
+
cleanups.push(prepared.cleanup);
|
|
1091
|
+
renderInput = prepared.input;
|
|
359
1092
|
}
|
|
360
|
-
|
|
1093
|
+
await verifySceneShotAssetBytes(renderInput, localHandleReader({ workDir, baseUrl: server.baseUrl }));
|
|
1094
|
+
assertNoRemoteRefs(renderInput);
|
|
1095
|
+
return { renderInput, close: cleanupAll };
|
|
1096
|
+
} catch (error) {
|
|
1097
|
+
await cleanupAll().catch((cleanupError) => {
|
|
1098
|
+
if (error instanceof Error && error.cause === void 0) error.cause = cleanupError;
|
|
1099
|
+
});
|
|
1100
|
+
throw error;
|
|
1101
|
+
}
|
|
361
1102
|
}
|
|
362
1103
|
|
|
363
1104
|
// ../execution/render-harness/src/cardRender.ts
|
|
364
1105
|
import { mkdirSync, writeFileSync } from "fs";
|
|
365
|
-
import { join as
|
|
1106
|
+
import { join as join6 } from "path";
|
|
366
1107
|
var CARD_COMPOSITION_ID = "CueFrameCardStill";
|
|
367
1108
|
var CARD_ROOT_FILENAME = "card.Root.local.tsx";
|
|
368
1109
|
var CARD_ENTRY_FILENAME = "card.entry.local.tsx";
|
|
@@ -408,7 +1149,7 @@ function buildCardWebpackOverride(renderEntryRoot) {
|
|
|
408
1149
|
...config,
|
|
409
1150
|
resolve: {
|
|
410
1151
|
...config.resolve,
|
|
411
|
-
modules: [
|
|
1152
|
+
modules: [join6(renderEntryRoot, "node_modules"), ...config.resolve?.modules ?? ["node_modules"]]
|
|
412
1153
|
}
|
|
413
1154
|
});
|
|
414
1155
|
}
|
|
@@ -418,29 +1159,34 @@ async function renderCardStill(opts) {
|
|
|
418
1159
|
const fps = opts.fps ?? 30;
|
|
419
1160
|
const frame = opts.frame ?? 0;
|
|
420
1161
|
const renderEntryRoot = resolveRenderEntryRoot(opts.renderEntryRoot);
|
|
421
|
-
const browserExecutable =
|
|
1162
|
+
const browserExecutable = (await verifyLocalStagedBrowser(renderEntryRoot)).path;
|
|
422
1163
|
mkdirSync(opts.outDir, { recursive: true });
|
|
423
|
-
writeFileSync(
|
|
424
|
-
const entryPoint =
|
|
1164
|
+
writeFileSync(join6(opts.outDir, CARD_ROOT_FILENAME), generateCardRootSource({ width, height, fps }));
|
|
1165
|
+
const entryPoint = join6(opts.outDir, CARD_ENTRY_FILENAME);
|
|
425
1166
|
writeFileSync(entryPoint, generateCardEntrySource());
|
|
426
1167
|
const { bundle } = await importFromRenderEntry(
|
|
427
1168
|
renderEntryRoot,
|
|
428
1169
|
"@remotion/bundler"
|
|
429
1170
|
);
|
|
430
|
-
const serveUrl = await bundle({
|
|
1171
|
+
const serveUrl = await bundle({
|
|
1172
|
+
entryPoint,
|
|
1173
|
+
outDir: join6(opts.outDir, "remotion-bundle"),
|
|
1174
|
+
webpackOverride: buildCardWebpackOverride(renderEntryRoot)
|
|
1175
|
+
});
|
|
431
1176
|
const { selectComposition, renderStill } = await importFromRenderEntry(
|
|
432
1177
|
renderEntryRoot,
|
|
433
1178
|
"@remotion/renderer"
|
|
434
1179
|
);
|
|
435
1180
|
const inputProps = { html: opts.html, cssVars: opts.cssVars ?? {} };
|
|
1181
|
+
const { chromiumOptions } = componentBrowserBackend({ api: "canvas2d", required: true, accelerationPreference: "software-allowed" });
|
|
436
1182
|
const composition = await selectComposition({
|
|
437
1183
|
serveUrl,
|
|
438
1184
|
id: CARD_COMPOSITION_ID,
|
|
439
1185
|
inputProps,
|
|
440
1186
|
browserExecutable,
|
|
441
|
-
chromiumOptions
|
|
1187
|
+
chromiumOptions
|
|
442
1188
|
});
|
|
443
|
-
const pngPath =
|
|
1189
|
+
const pngPath = join6(opts.outDir, "card-still.png");
|
|
444
1190
|
await renderStill({
|
|
445
1191
|
composition,
|
|
446
1192
|
serveUrl,
|
|
@@ -448,7 +1194,7 @@ async function renderCardStill(opts) {
|
|
|
448
1194
|
output: pngPath,
|
|
449
1195
|
frame,
|
|
450
1196
|
browserExecutable,
|
|
451
|
-
chromiumOptions
|
|
1197
|
+
chromiumOptions,
|
|
452
1198
|
timeoutInMilliseconds: 12e4
|
|
453
1199
|
});
|
|
454
1200
|
return { pngPath };
|
|
@@ -462,13 +1208,17 @@ export {
|
|
|
462
1208
|
assetSlots,
|
|
463
1209
|
assetUrlKey,
|
|
464
1210
|
buildCardWebpackOverride,
|
|
1211
|
+
createNodeScenePreparationV1,
|
|
465
1212
|
extractSegments,
|
|
466
1213
|
generateCardEntrySource,
|
|
467
1214
|
generateCardRootSource,
|
|
468
1215
|
isRemoteUrl,
|
|
1216
|
+
localHandleReader,
|
|
469
1217
|
materializeSources,
|
|
1218
|
+
readImageHeader,
|
|
470
1219
|
renderCardStill,
|
|
471
1220
|
renderInputAssets,
|
|
472
1221
|
resolveAssets,
|
|
473
|
-
startMediaServer
|
|
1222
|
+
startMediaServer,
|
|
1223
|
+
verifySceneShotAssetBytes
|
|
474
1224
|
};
|