create-aura3d 1.1.2 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
- package/templates/{cartoon-channel → animation-channel}/README.md +11 -11
- package/templates/{cartoon-studio → animation-channel}/index.html +1 -1
- package/templates/{cartoon-channel → animation-channel}/package.json +2 -2
- package/templates/{cartoon-channel → animation-channel}/src/episode.ts +22 -22
- package/templates/{cartoon-channel → animation-channel}/src/experimental/README.md +5 -5
- package/templates/{cartoon-channel → animation-channel}/src/experimental/concept-episode-2-5d.css +3 -3
- package/templates/{cartoon-channel → animation-channel}/src/experimental/concept-episode-2-5d.ts +7 -7
- package/templates/{cartoon-channel → animation-channel}/src/experimental/image-puppet-episode.css +4 -4
- package/templates/{cartoon-channel → animation-channel}/src/experimental/image-puppet-episode.ts +6 -6
- package/templates/{cartoon-channel → animation-channel}/src/experimental/puppet-episode-2d.css +3 -3
- package/templates/{cartoon-channel → animation-channel}/src/experimental/puppet-episode-2d.ts +7 -7
- package/templates/{cartoon-channel → animation-channel}/src/main.ts +32 -32
- package/templates/{cartoon-channel → animation-channel}/src/render-plan.ts +13 -13
- package/templates/{cartoon-channel → animation-channel}/src/sample-episode-visual.css +34 -34
- package/templates/{cartoon-channel → animation-channel}/src/sample-episode-visual.ts +20 -20
- package/templates/{cartoon-channel → animation-channel}/tests/concept-2-5d-animation.spec.ts +3 -3
- package/templates/{cartoon-channel → animation-channel}/tests/concept-2-5d.spec.ts +6 -6
- package/templates/{cartoon-channel → animation-channel}/tests/image-puppet-animation.spec.ts +3 -3
- package/templates/{cartoon-channel → animation-channel}/tests/image-puppet.spec.ts +5 -5
- package/templates/{cartoon-channel → animation-channel}/tests/puppet-2d-animation.spec.ts +3 -3
- package/templates/{cartoon-channel → animation-channel}/tests/puppet-2d.spec.ts +4 -4
- package/templates/{prompt-cartoon-channel → animation-channel}/tests/route-health.spec.ts +1 -1
- package/templates/{cartoon-channel → animation-channel}/tests/sample-episode-visual.spec.ts +5 -5
- package/templates/{cartoon-channel → animation-channel}/tests/storyboard-playback.spec.ts +7 -7
- package/templates/animation-studio/AGENTS.md +71 -0
- package/templates/{cartoon-studio → animation-studio}/ASSET-LICENSES.md +7 -7
- package/templates/{cartoon-studio → animation-studio}/README.md +6 -6
- package/templates/animation-studio/aura.assets.json +669 -0
- package/templates/animation-studio/dist/episodes/scene/episode-3d.webm +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/action.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/dialogue.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/final.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/first.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/mouth-closed.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/frames/mouth-open.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/render-live-summary.json +10284 -0
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/worker-1.png +0 -0
- package/templates/animation-studio/dist/episodes/scene/skeleton-overlays/worker-2.png +0 -0
- package/templates/animation-studio/dist/generated/second-scene.document.json +1210 -0
- package/templates/animation-studio/dist/generated/studio-edited.document.json +1196 -0
- package/templates/animation-studio/dist/scene/inshader-accept.document.json +1 -0
- package/templates/animation-studio/dist/scene/inshader-test.document.json +1 -0
- package/templates/animation-studio/dist/scene/integ.document.json +1 -0
- package/templates/animation-studio/dist/scene/working.document.json +723 -0
- package/templates/animation-studio/dist/scene/working.history.json +1 -0
- package/templates/{cartoon-studio → animation-studio}/live-route.html +1 -1
- package/templates/{cartoon-studio → animation-studio}/package-lock.json +2 -2
- package/templates/animation-studio/package.json +32 -0
- package/templates/animation-studio/public/aura-assets/cast-a.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/cast-b.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/luma.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/luma2.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/miko.catalog.glb +0 -0
- package/templates/{cartoon-studio → animation-studio}/public/aura-assets/moonGarden.gltf +1 -1
- package/templates/animation-studio/public/aura-assets/mushroom.catalog.glb +0 -0
- package/templates/animation-studio/public/aura-assets/rusty.catalog.glb +0 -0
- package/templates/animation-studio/public/cast-library/cast-library.json +71 -0
- package/templates/animation-studio/public/clip-library/gesture.json +173903 -0
- package/templates/animation-studio/public/clip-library/idle.json +23035 -0
- package/templates/animation-studio/public/clip-library/manifest.json +154 -0
- package/templates/animation-studio/public/clip-library/nod.json +173903 -0
- package/templates/animation-studio/public/clip-library/point.json +69879 -0
- package/templates/animation-studio/public/clip-library/react.json +66084 -0
- package/templates/animation-studio/public/clip-library/run.json +9648 -0
- package/templates/animation-studio/public/clip-library/talk.json +69879 -0
- package/templates/animation-studio/public/clip-library/walk.json +8283 -0
- package/templates/animation-studio/public/hifi-cast/BrainStem.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/CesiumMan.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/RiggedFigure.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Barbarian.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Knight.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Mage.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Rogue.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/kaykit/Rogue_Hooded.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/khronos-report.json +295 -0
- package/templates/animation-studio/public/hifi-cast/quaternius-report.json +449 -0
- package/templates/animation-studio/public/hifi-cast/rpm/cesiumman.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/rpm/fox.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/rpm/riggedfigure.glb +0 -0
- package/templates/animation-studio/public/hifi-cast/rpm-report.json +301 -0
- package/templates/animation-studio/scripts/anim.ts +103 -0
- package/templates/animation-studio/scripts/animation-scene.ts +457 -0
- package/templates/animation-studio/scripts/asset-motion-probe.ts +450 -0
- package/templates/animation-studio/scripts/asset-render-probe.ts +152 -0
- package/templates/animation-studio/scripts/author-office-scene.ts +65 -0
- package/templates/animation-studio/scripts/build-cast-library.ts +97 -0
- package/templates/animation-studio/scripts/build-characters.ts +1543 -0
- package/templates/animation-studio/scripts/build-clip-library.ts +972 -0
- package/templates/animation-studio/scripts/clip-decision-cli.ts +51 -0
- package/templates/animation-studio/scripts/determinism-check.ts +48 -0
- package/templates/animation-studio/scripts/generate-scene.ts +95 -0
- package/templates/animation-studio/scripts/hifi-cast-validate.ts +572 -0
- package/templates/animation-studio/scripts/motion-evidence-cli.ts +150 -0
- package/templates/animation-studio/scripts/motion-evidence.ts +362 -0
- package/templates/animation-studio/scripts/preview-server.ts +52 -0
- package/templates/animation-studio/scripts/regen-manifest.ts +156 -0
- package/templates/animation-studio/scripts/render-core.ts +360 -0
- package/templates/animation-studio/scripts/render-live.ts +813 -0
- package/templates/animation-studio/scripts/render-parallel.ts +70 -0
- package/templates/animation-studio/scripts/render-server.ts +119 -0
- package/templates/animation-studio/scripts/resolve-asset.ts +669 -0
- package/templates/animation-studio/scripts/skeleton-overlay-cli.ts +82 -0
- package/templates/animation-studio/scripts/skeleton-overlay.ts +293 -0
- package/templates/animation-studio/scripts/studio-tools-demo.ts +45 -0
- package/templates/animation-studio/scripts/texture-bake.ts +297 -0
- package/templates/{cartoon-studio → animation-studio}/scripts/validate-characters.ts +0 -0
- package/templates/animation-studio/scripts/verify-extracted-overlay-cli.ts +264 -0
- package/templates/animation-studio/src/animation-episode-validator.ts +97 -0
- package/templates/animation-studio/src/animation-performance.ts +556 -0
- package/templates/animation-studio/src/aura-assets.ts +71 -0
- package/templates/animation-studio/src/character.ts +40 -0
- package/templates/animation-studio/src/director/compile-episode-document.ts +45 -0
- package/templates/animation-studio/src/director/director-heuristics.ts +697 -0
- package/templates/animation-studio/src/director/prompt-to-scene.ts +369 -0
- package/templates/animation-studio/src/empty-document.ts +77 -0
- package/templates/animation-studio/src/episode-document.ts +442 -0
- package/templates/animation-studio/src/examples/moon-garden.example.ts +183 -0
- package/templates/animation-studio/src/fidelity.ts +129 -0
- package/templates/animation-studio/src/graph.ts +14 -0
- package/templates/animation-studio/src/procedural-hdri.ts +243 -0
- package/templates/animation-studio/src/profile.ts +97 -0
- package/templates/animation-studio/src/render-live-route.ts +42 -0
- package/templates/animation-studio/src/render-modes.ts +137 -0
- package/templates/animation-studio/src/scene-player.ts +867 -0
- package/templates/animation-studio/src/set-templates.ts +361 -0
- package/templates/animation-studio/src/studio/episode-document-store.ts +72 -0
- package/templates/animation-studio/src/studio/scene-tool-registry.ts +86 -0
- package/templates/animation-studio/src/studio/scene-tools.ts +169 -0
- package/templates/animation-studio/tests/reports/animation-studio/hifi-cast-validation.json +938 -0
- package/templates/animation-studio/tsconfig.json +26 -0
- package/templates/{cartoon-studio → animation-studio}/vite.config.ts +6 -1
- package/templates/character-controller/README.md +33 -0
- package/templates/character-controller/index.html +19 -0
- package/templates/character-controller/package.json +23 -0
- package/templates/character-controller/playwright.config.ts +14 -0
- package/templates/character-controller/src/controller.ts +44 -0
- package/templates/character-controller/src/main.ts +62 -0
- package/templates/character-controller/tests/route-health.spec.ts +26 -0
- package/templates/character-controller/tests/screenshot.spec.ts +9 -0
- package/templates/character-controller/tsconfig.json +15 -0
- package/templates/cinematic-scene/package.json +1 -1
- package/templates/episode-builder/README.md +4 -4
- package/templates/episode-builder/package.json +1 -1
- package/templates/episode-builder/src/aura-assets.ts +1 -1
- package/templates/episode-builder/src/builder.ts +4 -4
- package/templates/episode-builder/src/episode.ts +21 -21
- package/templates/episode-builder/src/main.ts +20 -20
- package/templates/episode-builder/src/render-plan.ts +13 -13
- package/templates/episode-builder/tests/storyboard-playback.spec.ts +7 -7
- package/templates/fighting-game/package.json +1 -1
- package/templates/mini-game/package.json +1 -1
- package/templates/product-viewer/package.json +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/README.md +5 -5
- package/templates/{cartoon-channel → prompt-animation-channel}/index.html +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/package.json +2 -2
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/aura-assets.ts +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/episode.ts +22 -22
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/main.ts +28 -28
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/render-plan.ts +13 -13
- package/templates/{cartoon-channel → prompt-animation-channel}/tests/route-health.spec.ts +1 -1
- package/templates/{prompt-cartoon-channel → prompt-animation-channel}/tests/storyboard-playback.spec.ts +8 -8
- package/templates/cartoon-studio/aura.assets.json +0 -400
- package/templates/cartoon-studio/package.json +0 -33
- package/templates/cartoon-studio/public/aura-assets/luma.authored.glb +0 -0
- package/templates/cartoon-studio/public/aura-assets/miko.authored.glb +0 -0
- package/templates/cartoon-studio/scripts/build-characters.ts +0 -738
- package/templates/cartoon-studio/scripts/build-dialogue-audio.ts +0 -262
- package/templates/cartoon-studio/scripts/episode.ts +0 -323
- package/templates/cartoon-studio/scripts/render-live.ts +0 -873
- package/templates/cartoon-studio/src/aura-assets.ts +0 -64
- package/templates/cartoon-studio/src/characters.ts +0 -65
- package/templates/cartoon-studio/src/episode-renderer.ts +0 -605
- package/templates/cartoon-studio/src/episode.ts +0 -306
- package/templates/cartoon-studio/src/main.ts +0 -400
- package/templates/cartoon-studio/src/render-live-route.ts +0 -913
- package/templates/cartoon-studio/src/render-plan.ts +0 -567
- package/templates/cartoon-studio/src/review.ts +0 -99
- package/templates/cartoon-studio/src/studio.ts +0 -101
- package/templates/cartoon-studio/test-results/.last-run.json +0 -4
- package/templates/cartoon-studio/tests/episode-render.spec.ts +0 -44
- package/templates/cartoon-studio/tests/motion-quality.spec.ts +0 -45
- package/templates/cartoon-studio/tests/route-health.spec.ts +0 -7
- package/templates/cartoon-studio/tests/storyboard-playback.spec.ts +0 -99
- package/templates/cartoon-studio/tests/visual-review.spec.ts +0 -21
- package/templates/cartoon-studio/tsconfig.json +0 -14
- package/templates/prompt-cartoon-channel/index.html +0 -13
- package/templates/prompt-cartoon-channel/src/sets.ts +0 -14
- /package/templates/{cartoon-channel → animation-channel}/aura.assets.json +0 -0
- /package/templates/{cartoon-channel → animation-channel}/playwright.config.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/luma.047f5e5f.glb +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/luma.thumb.svg +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/miko.047f5e5f.glb +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/miko.thumb.svg +0 -0
- /package/templates/{cartoon-channel → animation-channel}/public/aura-assets/moon-garden-feature-frame.png +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/aura-assets.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/characters.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/contract.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/src/sets.ts +0 -0
- /package/templates/{cartoon-channel → animation-channel}/test-results/.last-run.json +0 -0
- /package/templates/{cartoon-channel → animation-channel}/tests/reports/prompt-animation/cartoon-sample-episode.png +0 -0
- /package/templates/{cartoon-channel → animation-channel}/tsconfig.json +0 -0
- /package/templates/{cartoon-studio → animation-studio}/playwright.config.ts +0 -0
- /package/templates/{cartoon-studio → animation-studio}/public/aura-assets/luma.thumb.svg +0 -0
- /package/templates/{cartoon-studio → animation-studio}/public/aura-assets/miko.thumb.svg +0 -0
- /package/templates/{cartoon-studio → animation-studio}/src/contract.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/playwright.config.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/characters.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/src/contract.ts +0 -0
- /package/templates/{cartoon-studio → prompt-animation-channel}/src/sets.ts +0 -0
- /package/templates/{prompt-cartoon-channel → prompt-animation-channel}/tsconfig.json +0 -0
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collectPromptAnimationEvidence,
|
|
3
|
-
createAudioStemManifest,
|
|
4
|
-
createAuraVoiceBridgePackage,
|
|
5
|
-
createAuraVoiceVisemeTrack,
|
|
6
|
-
createCaptionTimingProof,
|
|
7
|
-
createGlbBlendshapeVisemeCue,
|
|
8
|
-
createCartoonPerformanceCoverage,
|
|
9
|
-
createCartoonRenderOutputPackageMetadata,
|
|
10
|
-
createPrimitiveMouthVisemeCues,
|
|
11
|
-
createPromptAnimationDeterministicScreenshotFixtureMetadata,
|
|
12
|
-
evaluatePromptAnimationPublishReadiness,
|
|
13
|
-
defineDubMap,
|
|
14
|
-
glbVisemeBlendshapeExample,
|
|
15
|
-
primitiveMouthVisemeExample,
|
|
16
|
-
sampleAuraVoiceBridgeAtTime,
|
|
17
|
-
sampleVisemeTrack,
|
|
18
|
-
validateAuraVoiceBridgePackage
|
|
19
|
-
} from "@aura3d/engine";
|
|
20
|
-
import {
|
|
21
|
-
episode,
|
|
22
|
-
episodeAudioCues,
|
|
23
|
-
episodeContractId,
|
|
24
|
-
missingCartoonCharacterAssets,
|
|
25
|
-
publicCartoonAssetInstructions,
|
|
26
|
-
requiredCartoonCharacterAssets,
|
|
27
|
-
typedCartoonAssetSummary,
|
|
28
|
-
youtubeDraftMetadata
|
|
29
|
-
} from "./episode";
|
|
30
|
-
|
|
31
|
-
const frameRate = episode.episodePlan.runtime.frameRate;
|
|
32
|
-
|
|
33
|
-
export const renderContractId = episodeContractId;
|
|
34
|
-
|
|
35
|
-
export const renderPlan = episode.renderQueue;
|
|
36
|
-
|
|
37
|
-
export const renderOutputPackage = createCartoonRenderOutputPackageMetadata({
|
|
38
|
-
episodePlan: episode.episodePlan,
|
|
39
|
-
shotTimeline: episode.shotTimeline,
|
|
40
|
-
renderQueue: renderPlan,
|
|
41
|
-
youtube: youtubeDraftMetadata,
|
|
42
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
export const audioStemManifest = createAudioStemManifest({
|
|
46
|
-
episodeId: episode.episodePlan.episodeId,
|
|
47
|
-
duration: episode.dialogueTrack.duration,
|
|
48
|
-
stems: [
|
|
49
|
-
...episode.dialogueTrack.lines.map((line) => ({
|
|
50
|
-
id: `audio:${line.lineId}`,
|
|
51
|
-
role: "dialogue" as const,
|
|
52
|
-
path: line.audioFile ?? `assets/audio/en/${line.lineId}.wav`,
|
|
53
|
-
startTime: line.startTime,
|
|
54
|
-
duration: line.endTime - line.startTime,
|
|
55
|
-
language: line.language
|
|
56
|
-
})),
|
|
57
|
-
...episodeAudioCues
|
|
58
|
-
],
|
|
59
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
export const visemeTrack = createAuraVoiceVisemeTrack({
|
|
63
|
-
episodeId: episode.episodePlan.episodeId,
|
|
64
|
-
language: episode.episodePlan.language,
|
|
65
|
-
frameRate,
|
|
66
|
-
cues: episode.dialogueTrack.lines.flatMap((line) =>
|
|
67
|
-
createPrimitiveMouthVisemeCues({
|
|
68
|
-
characterId: line.speakerId,
|
|
69
|
-
speakerId: line.speakerId,
|
|
70
|
-
lineId: line.lineId,
|
|
71
|
-
startTime: line.startTime,
|
|
72
|
-
endTime: line.endTime
|
|
73
|
-
}).map((cue, cueIndex) => {
|
|
74
|
-
const words = line.text.split(/\s+/).filter(Boolean);
|
|
75
|
-
const wordIndex = Math.min(cueIndex, Math.max(0, words.length - 1));
|
|
76
|
-
return createGlbBlendshapeVisemeCue({
|
|
77
|
-
...cue,
|
|
78
|
-
phoneme: cue.visemeId === "m" ? "M" : "AH",
|
|
79
|
-
phonemeId: `${line.lineId}:phoneme-${cueIndex + 1}`,
|
|
80
|
-
word: words[wordIndex] ?? line.text,
|
|
81
|
-
wordIndex,
|
|
82
|
-
wordStartTime: cue.startTime,
|
|
83
|
-
wordEndTime: cue.endTime
|
|
84
|
-
});
|
|
85
|
-
})
|
|
86
|
-
),
|
|
87
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
export const primitiveMouthRuntimeExample = {
|
|
91
|
-
...primitiveMouthVisemeExample,
|
|
92
|
-
runtimeNodes: {
|
|
93
|
-
miko: "miko:mouth",
|
|
94
|
-
luma: "luma:mouth"
|
|
95
|
-
}
|
|
96
|
-
} as const;
|
|
97
|
-
|
|
98
|
-
export const glbVisemeRuntimeExample = {
|
|
99
|
-
...glbVisemeBlendshapeExample,
|
|
100
|
-
typedAssetExample: "import { assets } from './aura-assets'; model(assets.character)",
|
|
101
|
-
sampleBlendshapeNames: Object.values(glbVisemeBlendshapeExample.blendshapeMap).slice(0, 6)
|
|
102
|
-
} as const;
|
|
103
|
-
|
|
104
|
-
export const captionTimingProof = createCaptionTimingProof(episode.dialogueTrack, episode.captionTrack, {
|
|
105
|
-
frameRate,
|
|
106
|
-
maxAllowedDriftFrames: 1
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
function frameDriftFrames(actual: number, expected: number) {
|
|
110
|
-
return Math.round(Math.abs(actual - expected) * frameRate);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const visemeLineSyncChecks = episode.dialogueTrack.lines.map((line) => {
|
|
114
|
-
const cues = visemeTrack.cues.filter((cue) => cue.lineId === line.lineId && cue.speakerId === line.speakerId);
|
|
115
|
-
const firstCue = cues[0];
|
|
116
|
-
const lastCue = cues[cues.length - 1];
|
|
117
|
-
const startDriftFrames = firstCue ? frameDriftFrames(firstCue.startTime, line.startTime) : 999;
|
|
118
|
-
const endDriftFrames = lastCue ? frameDriftFrames(lastCue.endTime, line.endTime) : 999;
|
|
119
|
-
const sampleTime = Math.min(line.endTime - 1 / frameRate, line.startTime + 1 / frameRate);
|
|
120
|
-
const sampledMouth = sampleVisemeTrack(visemeTrack, sampleTime, line.speakerId);
|
|
121
|
-
return {
|
|
122
|
-
lineId: line.lineId,
|
|
123
|
-
speakerId: line.speakerId,
|
|
124
|
-
characterId: line.speakerId,
|
|
125
|
-
cueCount: cues.length,
|
|
126
|
-
startDriftFrames,
|
|
127
|
-
endDriftFrames,
|
|
128
|
-
maxDriftFrames: Math.max(startDriftFrames, endDriftFrames),
|
|
129
|
-
sampledMouthState: {
|
|
130
|
-
time: sampleTime,
|
|
131
|
-
frame: Math.round(sampleTime * frameRate),
|
|
132
|
-
visemeId: sampledMouth.visemeId,
|
|
133
|
-
mouthOpenness: sampledMouth.mouthOpenness,
|
|
134
|
-
primitiveMouthCard: sampledMouth.primitiveMouthCard,
|
|
135
|
-
blendshapeWeights: sampledMouth.blendshapeWeights
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const maxVisemeLineDriftFrames = Math.max(0, ...visemeLineSyncChecks.map((check) => check.maxDriftFrames));
|
|
141
|
-
const missingVisemeLineIds = visemeLineSyncChecks
|
|
142
|
-
.filter((check) => check.cueCount === 0 || check.maxDriftFrames > 1)
|
|
143
|
-
.map((check) => check.lineId);
|
|
144
|
-
|
|
145
|
-
export const captionFrameSyncSourceProof = {
|
|
146
|
-
contractId: renderContractId,
|
|
147
|
-
sourceOnly: true,
|
|
148
|
-
proofType: "caption-display-one-frame-source-harness",
|
|
149
|
-
frameRate,
|
|
150
|
-
allowedDriftFrames: 1,
|
|
151
|
-
allowedFrameDurationSeconds: 1 / frameRate,
|
|
152
|
-
captionDisplayWithinOneFrame: captionTimingProof.status === "pass" && captionTimingProof.maxDriftFrames <= 1,
|
|
153
|
-
maxObservedDriftFrames: captionTimingProof.maxDriftFrames,
|
|
154
|
-
coveredLineIds: captionTimingProof.coveredLineIds,
|
|
155
|
-
missingLineIds: captionTimingProof.missingLineIds,
|
|
156
|
-
sampledCaptionCues: captionTimingProof.lines.map((line) => ({
|
|
157
|
-
lineId: line.lineId,
|
|
158
|
-
captionCueId: line.captionId,
|
|
159
|
-
startDriftFrames: line.startDriftFrames,
|
|
160
|
-
endDriftFrames: line.endDriftFrames,
|
|
161
|
-
maxDriftFrames: line.maxDriftFrames
|
|
162
|
-
})),
|
|
163
|
-
executionBoundary: "Source harness only; actual caption display proof requires rendered frame/video evidence."
|
|
164
|
-
} as const;
|
|
165
|
-
|
|
166
|
-
export const visemeFrameSyncSourceProof = {
|
|
167
|
-
contractId: renderContractId,
|
|
168
|
-
sourceOnly: true,
|
|
169
|
-
proofType: "mouth-movement-one-frame-source-harness",
|
|
170
|
-
frameRate,
|
|
171
|
-
allowedDriftFrames: 1,
|
|
172
|
-
allowedFrameDurationSeconds: 1 / frameRate,
|
|
173
|
-
mouthMovementWithinOneFrame: missingVisemeLineIds.length === 0 && maxVisemeLineDriftFrames <= 1,
|
|
174
|
-
maxObservedDriftFrames: maxVisemeLineDriftFrames,
|
|
175
|
-
coveredLineIds: visemeLineSyncChecks.filter((check) => check.cueCount > 0).map((check) => check.lineId),
|
|
176
|
-
missingLineIds: missingVisemeLineIds,
|
|
177
|
-
sampledMouthStates: visemeLineSyncChecks.map((check) => ({
|
|
178
|
-
lineId: check.lineId,
|
|
179
|
-
speakerId: check.speakerId,
|
|
180
|
-
characterId: check.characterId,
|
|
181
|
-
...check.sampledMouthState
|
|
182
|
-
})),
|
|
183
|
-
primitiveMouthRuntimeNodeIds: primitiveMouthRuntimeExample.runtimeNodes,
|
|
184
|
-
glbBlendshapeNames: glbVisemeRuntimeExample.sampleBlendshapeNames,
|
|
185
|
-
executionBoundary: "Source harness only; actual mouth movement proof requires rendered frame/video evidence."
|
|
186
|
-
} as const;
|
|
187
|
-
|
|
188
|
-
function shotForLine(lineId: string) {
|
|
189
|
-
return episode.shotTimeline.shots.find((shot) => lineId.startsWith(`${shot.shotId}:line-`));
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export const spanishDubMap = defineDubMap({
|
|
193
|
-
artifact: "dub-map",
|
|
194
|
-
contractId: episode.dialogueTrack.contractId,
|
|
195
|
-
episodeId: episode.episodePlan.episodeId,
|
|
196
|
-
sourceLanguage: "en",
|
|
197
|
-
targetLanguage: "es",
|
|
198
|
-
entries: episode.dialogueTrack.lines.map((line) => {
|
|
199
|
-
const shot = shotForLine(line.lineId);
|
|
200
|
-
return {
|
|
201
|
-
originalStoryboardId: shot?.sceneId,
|
|
202
|
-
dubbedStoryboardId: shot?.sceneId,
|
|
203
|
-
originalStoryboardSceneId: shot?.sceneId,
|
|
204
|
-
dubbedStoryboardSceneId: shot?.sceneId,
|
|
205
|
-
originalLineId: line.lineId,
|
|
206
|
-
dubbedLineId: line.lineId,
|
|
207
|
-
originalCaptionId: `${line.lineId}:caption`,
|
|
208
|
-
dubbedCaptionId: `${line.lineId}:caption`,
|
|
209
|
-
originalCharacterId: line.speakerId,
|
|
210
|
-
dubbedCharacterId: line.speakerId,
|
|
211
|
-
originalSpeakerId: line.speakerId,
|
|
212
|
-
dubbedSpeakerId: line.speakerId,
|
|
213
|
-
originalLanguage: line.language,
|
|
214
|
-
dubbedLanguage: "es",
|
|
215
|
-
originalShotId: shot?.shotId,
|
|
216
|
-
dubbedShotId: shot?.shotId,
|
|
217
|
-
originalSceneId: shot?.sceneId,
|
|
218
|
-
dubbedSceneId: shot?.sceneId
|
|
219
|
-
};
|
|
220
|
-
}),
|
|
221
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
const spanishLineTextBySourceText = new Map<string, string>([
|
|
225
|
-
["Luma, the moon lilies are losing their sparkle.", "Luma, los lirios lunares estan perdiendo su brillo."],
|
|
226
|
-
["Then we sweep softly and wake the glow stones.", "Entonces barremos con suavidad y despertamos las piedras brillantes."],
|
|
227
|
-
["I will polish the blue stones one tiny circle at a time.", "Pulire las piedras azules con circulos pequenitos."],
|
|
228
|
-
["And I will hum the garden's sleepy cleanup song.", "Y yo tarareare la cancion tranquila del jardin."],
|
|
229
|
-
["The moon lilies are twinkling again.", "Los lirios lunares vuelven a centellear."],
|
|
230
|
-
["Goodnight, little garden. Keep glowing.", "Buenas noches, jardin pequeno. Sigue brillando."]
|
|
231
|
-
]);
|
|
232
|
-
|
|
233
|
-
function spanishTextForLine(text: string): string {
|
|
234
|
-
return spanishLineTextBySourceText.get(text) ?? text;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export const spanishDubCaptionMetadata = {
|
|
238
|
-
artifact: "alternate-language-caption-metadata",
|
|
239
|
-
schema: "aura3d-cartoon-studio-alternate-language-captions/v1",
|
|
240
|
-
contractId: renderContractId,
|
|
241
|
-
episodeId: episode.episodePlan.episodeId,
|
|
242
|
-
sourceLanguage: episode.dialogueTrack.language,
|
|
243
|
-
targetLanguage: spanishDubMap.targetLanguage,
|
|
244
|
-
cues: episode.captionTrack.cues.map((cue) => {
|
|
245
|
-
const sourceLine = episode.dialogueTrack.lines.find((line) => line.lineId === cue.lineId);
|
|
246
|
-
return {
|
|
247
|
-
captionId: cue.captionId,
|
|
248
|
-
lineId: cue.lineId,
|
|
249
|
-
shotId: cue.shotId,
|
|
250
|
-
sceneId: cue.sceneId,
|
|
251
|
-
speakerId: cue.speakerId,
|
|
252
|
-
sourceText: cue.text,
|
|
253
|
-
text: spanishTextForLine(sourceLine?.text ?? cue.text),
|
|
254
|
-
language: "es",
|
|
255
|
-
startTime: cue.startTime,
|
|
256
|
-
endTime: cue.endTime,
|
|
257
|
-
lineSafe: cue.lineSafe
|
|
258
|
-
};
|
|
259
|
-
}),
|
|
260
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
261
|
-
} as const;
|
|
262
|
-
|
|
263
|
-
export const alternateLanguageDubMetadata = {
|
|
264
|
-
artifact: "cartoon-alternate-language-dub-proof",
|
|
265
|
-
schema: "aura3d-cartoon-studio-alternate-language-dub-proof/v1",
|
|
266
|
-
contractId: renderContractId,
|
|
267
|
-
episodeId: episode.episodePlan.episodeId,
|
|
268
|
-
sourceLanguage: episode.dialogueTrack.language,
|
|
269
|
-
alternateLanguageCount: 1,
|
|
270
|
-
alternateLanguages: [
|
|
271
|
-
{
|
|
272
|
-
language: spanishDubMap.targetLanguage,
|
|
273
|
-
label: "Spanish",
|
|
274
|
-
title: "Limpieza del Jardin Lunar",
|
|
275
|
-
dubMapArtifact: spanishDubMap.artifact,
|
|
276
|
-
lineCount: spanishDubMap.entries.length,
|
|
277
|
-
captionCueCount: spanishDubCaptionMetadata.cues.length,
|
|
278
|
-
captionMetadata: spanishDubCaptionMetadata,
|
|
279
|
-
audioStemSlots: episode.dialogueTrack.lines.map((line) => ({
|
|
280
|
-
id: `dub-slot:es:${line.lineId}`,
|
|
281
|
-
lineId: line.lineId,
|
|
282
|
-
speakerId: line.speakerId,
|
|
283
|
-
language: "es",
|
|
284
|
-
assetRequiredBeforePublish: true
|
|
285
|
-
})),
|
|
286
|
-
stableIds: {
|
|
287
|
-
shotIds: spanishDubMap.entries.every((entry) => entry.originalShotId === entry.dubbedShotId),
|
|
288
|
-
storyboardIds: spanishDubMap.entries.every((entry) => entry.originalStoryboardId === entry.dubbedStoryboardId),
|
|
289
|
-
sceneIds: spanishDubMap.entries.every((entry) => entry.originalSceneId === entry.dubbedSceneId),
|
|
290
|
-
lineIds: spanishDubMap.entries.every((entry) => entry.originalLineId === entry.dubbedLineId),
|
|
291
|
-
captionIds: spanishDubMap.entries.every((entry) => entry.originalCaptionId === entry.dubbedCaptionId),
|
|
292
|
-
characterIds: spanishDubMap.entries.every((entry) => entry.originalCharacterId === entry.dubbedCharacterId)
|
|
293
|
-
},
|
|
294
|
-
publishBoundary: "Metadata-only alternate-language proof. Add licensed/typed Spanish dialogue stems before claiming a rendered Spanish dub."
|
|
295
|
-
}
|
|
296
|
-
],
|
|
297
|
-
assetPolicy: {
|
|
298
|
-
inventsAudioAssets: false,
|
|
299
|
-
inventsModelAssets: false,
|
|
300
|
-
typedAssetSource: "./src/aura-assets"
|
|
301
|
-
},
|
|
302
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
303
|
-
} as const;
|
|
304
|
-
|
|
305
|
-
export const phonemeVisemeDubSyncSourceProof = {
|
|
306
|
-
contractId: renderContractId,
|
|
307
|
-
sourceOnly: true,
|
|
308
|
-
proofType: "phoneme-viseme-dub-sync-source-harness",
|
|
309
|
-
visemeFormat: visemeTrack.format,
|
|
310
|
-
frameRate,
|
|
311
|
-
allowedDriftFrames: 1,
|
|
312
|
-
phonemeFields: ["phoneme", "phonemeId", "word", "wordIndex", "wordStartTime", "wordEndTime"],
|
|
313
|
-
sampledPhonemeVisemeCues: visemeTrack.cues.slice(0, 8).map((cue) => ({
|
|
314
|
-
cueId: cue.id,
|
|
315
|
-
lineId: cue.lineId,
|
|
316
|
-
speakerId: cue.speakerId,
|
|
317
|
-
characterId: cue.characterId,
|
|
318
|
-
visemeId: cue.visemeId,
|
|
319
|
-
phoneme: cue.phoneme,
|
|
320
|
-
phonemeId: cue.phonemeId,
|
|
321
|
-
word: cue.word,
|
|
322
|
-
wordIndex: cue.wordIndex,
|
|
323
|
-
wordStartTime: cue.wordStartTime,
|
|
324
|
-
wordEndTime: cue.wordEndTime,
|
|
325
|
-
startTime: cue.startTime,
|
|
326
|
-
endTime: cue.endTime
|
|
327
|
-
})),
|
|
328
|
-
dubContinuity: {
|
|
329
|
-
sourceLanguage: spanishDubMap.sourceLanguage,
|
|
330
|
-
targetLanguage: spanishDubMap.targetLanguage,
|
|
331
|
-
stableShotIds: spanishDubMap.entries.every((entry) => entry.originalShotId === entry.dubbedShotId),
|
|
332
|
-
stableStoryboardIds: spanishDubMap.entries.every((entry) => entry.originalStoryboardId === entry.dubbedStoryboardId),
|
|
333
|
-
stableCaptionIds: spanishDubMap.entries.every((entry) => entry.originalCaptionId === entry.dubbedCaptionId),
|
|
334
|
-
stableLineIds: spanishDubMap.entries.every((entry) => entry.originalLineId === entry.dubbedLineId)
|
|
335
|
-
},
|
|
336
|
-
executionBoundary: "Source harness only; actual phoneme, viseme, and dub playback proof requires rendered frame/video evidence."
|
|
337
|
-
} as const;
|
|
338
|
-
|
|
339
|
-
export const cartoonStudioShowBibleBatchRenderPlan = {
|
|
340
|
-
artifact: "cartoon-show-bible-batch-render-plan",
|
|
341
|
-
schema: "aura3d-cartoon-studio-show-bible-batch-render-plan/v1",
|
|
342
|
-
contractId: renderContractId,
|
|
343
|
-
sourceStoryBible: {
|
|
344
|
-
episodeId: episode.storyBible.episodeId,
|
|
345
|
-
title: episode.storyBible.title,
|
|
346
|
-
characterIds: episode.storyBible.characters.map((character) => character.id),
|
|
347
|
-
locationIds: episode.storyBible.locations.map((location) => location.id),
|
|
348
|
-
propIds: episode.storyBible.props.map((prop) => prop.id),
|
|
349
|
-
continuityRules: episode.storyBible.continuityRules ?? []
|
|
350
|
-
},
|
|
351
|
-
renderJobs: [
|
|
352
|
-
{
|
|
353
|
-
id: "batch:moon-garden-cleanup-001",
|
|
354
|
-
episodeId: episode.episodePlan.episodeId,
|
|
355
|
-
title: episode.episodePlan.title,
|
|
356
|
-
sourceStoryBibleEpisodeId: episode.storyBible.episodeId,
|
|
357
|
-
route: renderPlan.route,
|
|
358
|
-
outputDirectory: "dist/episodes/moon-garden-001",
|
|
359
|
-
language: episode.episodePlan.language,
|
|
360
|
-
shotIds: episode.shotTimeline.shots.map((shot) => shot.shotId),
|
|
361
|
-
requiredTypedAssetKeys: typedCartoonAssetSummary.requiredCharacterAssets,
|
|
362
|
-
command: "npm run episode:render -- --episode moon-garden-cleanup-001"
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
id: "batch:moon-garden-glow-check-002",
|
|
366
|
-
episodeId: "moon-garden-glow-check-002",
|
|
367
|
-
title: "Moon Garden Glow Check",
|
|
368
|
-
sourceStoryBibleEpisodeId: episode.storyBible.episodeId,
|
|
369
|
-
route: renderPlan.route,
|
|
370
|
-
outputDirectory: "dist/episodes/moon-garden-002",
|
|
371
|
-
language: episode.episodePlan.language,
|
|
372
|
-
reusedCharacterIds: episode.storyBible.characters.map((character) => character.id),
|
|
373
|
-
reusedLocationIds: episode.storyBible.locations.map((location) => location.id),
|
|
374
|
-
reusedPropIds: episode.storyBible.props.map((prop) => prop.id),
|
|
375
|
-
requiredTypedAssetKeys: typedCartoonAssetSummary.requiredCharacterAssets,
|
|
376
|
-
command: "npm run episode:render -- --episode moon-garden-glow-check-002",
|
|
377
|
-
metadataOnly: true,
|
|
378
|
-
publishBoundary: "Second episode job reuses the same show bible and asset slots; rendered media is produced only when the template runner is executed with real typed assets."
|
|
379
|
-
}
|
|
380
|
-
],
|
|
381
|
-
guarantees: {
|
|
382
|
-
oneShowBible: true,
|
|
383
|
-
multipleEpisodes: true,
|
|
384
|
-
noInventedAssets: true,
|
|
385
|
-
stableCharacterIds: true,
|
|
386
|
-
stableLocationIds: true,
|
|
387
|
-
stablePropIds: true
|
|
388
|
-
},
|
|
389
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
390
|
-
} as const;
|
|
391
|
-
|
|
392
|
-
export const performanceCoverage = createCartoonPerformanceCoverage(episode.performance, episode.dialogueTrack);
|
|
393
|
-
|
|
394
|
-
export const reviewPackagePaths = renderOutputPackage.reviewPackagePaths;
|
|
395
|
-
|
|
396
|
-
export const thumbnailCapture = renderOutputPackage.thumbnailCapture;
|
|
397
|
-
|
|
398
|
-
export const plannedDeterministicCaptureSources = renderPlan.items.map((item) => ({
|
|
399
|
-
renderQueueItemId: item.id,
|
|
400
|
-
time: item.time,
|
|
401
|
-
frame: item.frame,
|
|
402
|
-
...(item.shotId ? { shotId: item.shotId } : {}),
|
|
403
|
-
sourceSceneStateId: item.sourceSceneState?.sceneStateId,
|
|
404
|
-
auraVoiceTimestamp: item.sourceSceneState?.auraVoiceTimestamp ?? item.time,
|
|
405
|
-
deterministicSeed: item.sourceSceneState?.deterministicSeed
|
|
406
|
-
}));
|
|
407
|
-
|
|
408
|
-
export const sampleRenderSourceWorkflow = {
|
|
409
|
-
contractId: renderContractId,
|
|
410
|
-
sourceOnly: true,
|
|
411
|
-
status: "source-workflow-ready",
|
|
412
|
-
promptToAudioToAura3DAnimation: true,
|
|
413
|
-
sampleEpisodeId: episode.episodePlan.episodeId,
|
|
414
|
-
runtimeSeconds: episode.episodePlan.runtime.duration,
|
|
415
|
-
minimumRuntimeSeconds: 60,
|
|
416
|
-
frameRate,
|
|
417
|
-
resolution: episode.episodePlan.runtime.resolution,
|
|
418
|
-
shotCount: episode.shotTimeline.shots.length,
|
|
419
|
-
speakingCharacterIds: Array.from(new Set(episode.dialogueTrack.lines.map((line) => line.speakerId))),
|
|
420
|
-
requiredTypedAssets: requiredCartoonCharacterAssets,
|
|
421
|
-
typedAssetSummary: typedCartoonAssetSummary,
|
|
422
|
-
missingTypedCharacterAssets: missingCartoonCharacterAssets,
|
|
423
|
-
assetCommands: publicCartoonAssetInstructions,
|
|
424
|
-
audioStemRoles: audioStemManifest.stems.map((stem) => stem.role),
|
|
425
|
-
requiresNoManualTimingEdits: true,
|
|
426
|
-
doesNotClaimRenderedArtifacts: true,
|
|
427
|
-
humanReviewRequired: true,
|
|
428
|
-
captionFrameSyncSourceProof,
|
|
429
|
-
visemeFrameSyncSourceProof,
|
|
430
|
-
phonemeVisemeDubSyncSourceProof,
|
|
431
|
-
artifactManifestExpectations: {
|
|
432
|
-
video: {
|
|
433
|
-
required: true,
|
|
434
|
-
outputId: renderOutputPackage.outputs.mp4?.id,
|
|
435
|
-
path: renderOutputPackage.outputs.mp4?.path,
|
|
436
|
-
evidenceJsonFields: ["path", "sha256", "byteSize", "duration", "frameRate", "resolution", "renderQueueId"]
|
|
437
|
-
},
|
|
438
|
-
thumbnail: {
|
|
439
|
-
required: true,
|
|
440
|
-
outputId: renderOutputPackage.outputs.thumbnail?.id,
|
|
441
|
-
path: renderOutputPackage.outputs.thumbnail?.path,
|
|
442
|
-
sourceSceneStateId: renderOutputPackage.thumbnailCapture.sourceSceneStateId,
|
|
443
|
-
evidenceJsonFields: ["path", "sha256", "byteSize", "width", "height", "captureTime", "shotId", "sourceSceneStateId"]
|
|
444
|
-
},
|
|
445
|
-
captions: {
|
|
446
|
-
required: true,
|
|
447
|
-
outputIds: renderOutputPackage.outputs.captions.map((output) => output.id),
|
|
448
|
-
paths: renderOutputPackage.outputs.captions.map((output) => output.path),
|
|
449
|
-
evidenceJsonFields: ["path", "sha256", "byteSize", "language", "cueCount", "captionTrackId"]
|
|
450
|
-
},
|
|
451
|
-
timeline: {
|
|
452
|
-
required: true,
|
|
453
|
-
outputId: renderOutputPackage.outputs.timelineJson?.id,
|
|
454
|
-
path: renderOutputPackage.outputs.timelineJson?.path,
|
|
455
|
-
evidenceJsonFields: ["path", "sha256", "byteSize", "shotTimelineId", "frameRate", "duration"]
|
|
456
|
-
},
|
|
457
|
-
audioStems: {
|
|
458
|
-
required: true,
|
|
459
|
-
artifact: audioStemManifest.artifact,
|
|
460
|
-
path: "dist/render/audio-stems.json",
|
|
461
|
-
stemCount: audioStemManifest.stems.length,
|
|
462
|
-
evidenceJsonFields: ["path", "sha256", "byteSize", "stemCount", "dialogueStemCount", "sfxStemCount"]
|
|
463
|
-
},
|
|
464
|
-
evidenceJson: {
|
|
465
|
-
required: true,
|
|
466
|
-
outputId: renderOutputPackage.outputs.evidenceJson?.id,
|
|
467
|
-
path: renderOutputPackage.outputs.evidenceJson?.path,
|
|
468
|
-
evidenceJsonFields: ["path", "sha256", "byteSize", "schema", "ok", "gates", "proofs"]
|
|
469
|
-
},
|
|
470
|
-
youtubeDraftMetadata: {
|
|
471
|
-
required: true,
|
|
472
|
-
outputId: renderOutputPackage.outputs.youtubeMetadata?.id,
|
|
473
|
-
path: renderOutputPackage.outputs.youtubeMetadata?.path,
|
|
474
|
-
evidenceJsonFields: ["title", "description", "language", "videoPath", "thumbnailPath", "captionsPath"]
|
|
475
|
-
}
|
|
476
|
-
},
|
|
477
|
-
requiredEvidenceJsonFields: [
|
|
478
|
-
"artifacts.video",
|
|
479
|
-
"artifacts.thumbnail",
|
|
480
|
-
"artifacts.captions",
|
|
481
|
-
"artifacts.timeline",
|
|
482
|
-
"artifacts.audioStems",
|
|
483
|
-
"artifacts.evidenceJson",
|
|
484
|
-
"captionFrameSyncSourceProof.captionDisplayWithinOneFrame",
|
|
485
|
-
"visemeFrameSyncSourceProof.mouthMovementWithinOneFrame",
|
|
486
|
-
"phonemeVisemeDubSyncSourceProof.sampledPhonemeVisemeCues",
|
|
487
|
-
"phonemeVisemeDubSyncSourceProof.dubContinuity.stableShotIds",
|
|
488
|
-
"humanReview.status"
|
|
489
|
-
],
|
|
490
|
-
remainingProofGates: [
|
|
491
|
-
"Fresh scaffold npm run build output",
|
|
492
|
-
"Browser route health and storyboard playback output",
|
|
493
|
-
"Typed character GLBs added through src/aura-assets.ts",
|
|
494
|
-
"npx @aura3d/cli@latest assets validate-cartoon output",
|
|
495
|
-
"Actual 60-second MP4/WebM render artifact",
|
|
496
|
-
"Actual thumbnail artifact captured from the same Aura3D scene state",
|
|
497
|
-
"Actual captions/timeline/audio-stems/evidence JSON files with hashes",
|
|
498
|
-
"Human visual review approval"
|
|
499
|
-
]
|
|
500
|
-
} as const;
|
|
501
|
-
|
|
502
|
-
export const templateEpisodePackageWorkflow = {
|
|
503
|
-
contractId: renderContractId,
|
|
504
|
-
sourceOnly: false,
|
|
505
|
-
status: "template-package-runner-ready",
|
|
506
|
-
packageDirectory: "dist/episodes/moon-garden-001",
|
|
507
|
-
commands: [
|
|
508
|
-
"npm run episode:plan",
|
|
509
|
-
"npm run episode:preview",
|
|
510
|
-
"npm run episode:render",
|
|
511
|
-
"npm run episode:package",
|
|
512
|
-
"npm run episode:review",
|
|
513
|
-
"npm run episode:verify"
|
|
514
|
-
],
|
|
515
|
-
requiredArtifacts: [
|
|
516
|
-
"thumbnail.png",
|
|
517
|
-
"captions.vtt",
|
|
518
|
-
"captions.srt",
|
|
519
|
-
"metadata.json",
|
|
520
|
-
"route-proof.json",
|
|
521
|
-
"asset-provenance.json",
|
|
522
|
-
"render-manifest.json",
|
|
523
|
-
"visual-acceptance.json",
|
|
524
|
-
"review-package.md"
|
|
525
|
-
],
|
|
526
|
-
renderOutputMode: "episode.webm-or-png-sequence-fallback-marker",
|
|
527
|
-
publishBoundary: "PNG sequence fallback proves template packaging only; publish-ready claims require a real encoded WebM or MP4 plus human review."
|
|
528
|
-
} as const;
|
|
529
|
-
|
|
530
|
-
export const auraVoicePackage = createAuraVoiceBridgePackage({
|
|
531
|
-
episodePlan: episode.episodePlan,
|
|
532
|
-
storyboard: episode.storyboard,
|
|
533
|
-
shotTimeline: episode.shotTimeline,
|
|
534
|
-
dialogueTrack: episode.dialogueTrack,
|
|
535
|
-
captionTrack: episode.captionTrack,
|
|
536
|
-
visemes: visemeTrack,
|
|
537
|
-
audioStems: audioStemManifest,
|
|
538
|
-
dubMap: spanishDubMap,
|
|
539
|
-
renderQueue: renderPlan,
|
|
540
|
-
renderOutputPackage
|
|
541
|
-
}, {
|
|
542
|
-
route: "/",
|
|
543
|
-
frameRate,
|
|
544
|
-
maxTimingDriftFrames: 1,
|
|
545
|
-
youtube: youtubeDraftMetadata
|
|
546
|
-
});
|
|
547
|
-
|
|
548
|
-
export const deterministicScreenshotFixtures = createPromptAnimationDeterministicScreenshotFixtureMetadata({
|
|
549
|
-
bridgePackage: auraVoicePackage,
|
|
550
|
-
count: 3,
|
|
551
|
-
pathPrefix: "artifacts/screenshots/moon-garden"
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
export const accessibilityProofMetadata = auraVoicePackage.artifacts.episodePlan.accessibilityProof;
|
|
555
|
-
|
|
556
|
-
export const bridgeIssues = validateAuraVoiceBridgePackage(auraVoicePackage);
|
|
557
|
-
|
|
558
|
-
export const bridgeSampleAtThumbnail = sampleAuraVoiceBridgeAtTime(auraVoicePackage, renderOutputPackage.thumbnailCapture.time);
|
|
559
|
-
|
|
560
|
-
export const promptAnimationEvidence = collectPromptAnimationEvidence({
|
|
561
|
-
bridgePackage: auraVoicePackage,
|
|
562
|
-
performanceCoverage,
|
|
563
|
-
routeHealth: { status: "missing" },
|
|
564
|
-
generatedAt: episode.episodePlan.generatedAt
|
|
565
|
-
});
|
|
566
|
-
|
|
567
|
-
export const publishReadiness = evaluatePromptAnimationPublishReadiness(promptAnimationEvidence);
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { captionTimingProof, renderOutputPackage, visemeFrameSyncSourceProof } from "./render-plan";
|
|
2
|
-
import { episode, missingCartoonCharacterAssets, publicCartoonAssetInstructions, typedCartoonAssetSummary, youtubeDraftMetadata } from "./episode";
|
|
3
|
-
|
|
4
|
-
export const cartoonEpisodePackageDirectory = "dist/episodes/moon-garden-001" as const;
|
|
5
|
-
|
|
6
|
-
export const requiredCartoonEpisodePackageFiles = [
|
|
7
|
-
"episode.webm",
|
|
8
|
-
"thumbnail.png",
|
|
9
|
-
"captions.vtt",
|
|
10
|
-
"captions.srt",
|
|
11
|
-
"metadata.json",
|
|
12
|
-
"prompt-animation-evidence.json",
|
|
13
|
-
"route-proof.json",
|
|
14
|
-
"asset-provenance.json",
|
|
15
|
-
"render-manifest.json",
|
|
16
|
-
"dub-metadata.json",
|
|
17
|
-
"batch-render-plan.json",
|
|
18
|
-
"motion-quality.json",
|
|
19
|
-
"visual-acceptance.json",
|
|
20
|
-
"review-package.md"
|
|
21
|
-
] as const;
|
|
22
|
-
|
|
23
|
-
export const optionalCartoonEpisodePackageFiles = [
|
|
24
|
-
"episode.mp4",
|
|
25
|
-
"episode.png-sequence-fallback.json"
|
|
26
|
-
] as const;
|
|
27
|
-
|
|
28
|
-
export interface CartoonEpisodeReviewInput {
|
|
29
|
-
readonly packageDirectory?: string;
|
|
30
|
-
readonly hasWebm: boolean;
|
|
31
|
-
readonly hasPngSequenceFallback: boolean;
|
|
32
|
-
readonly generatedAt: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function createCartoonEpisodeReviewPackage(input: CartoonEpisodeReviewInput): string {
|
|
36
|
-
const packageDirectory = input.packageDirectory ?? cartoonEpisodePackageDirectory;
|
|
37
|
-
const outputMode = input.hasWebm ? "encoded-webm" : input.hasPngSequenceFallback ? "png-sequence-fallback" : "missing-render-output";
|
|
38
|
-
const typedAssetStatus = missingCartoonCharacterAssets.length === 0 ? "typed character assets present" : "starter fallback mode";
|
|
39
|
-
const reviewStatus = input.hasWebm && missingCartoonCharacterAssets.length === 0 ? "ready-for-human-review" : "needs-render-upgrade-before-publish";
|
|
40
|
-
|
|
41
|
-
return [
|
|
42
|
-
"# Moon Garden 001 Review Package",
|
|
43
|
-
"",
|
|
44
|
-
`Generated: ${input.generatedAt}`,
|
|
45
|
-
`Episode: ${episode.episodePlan.title}`,
|
|
46
|
-
`Package: \`${packageDirectory}\``,
|
|
47
|
-
`Output mode: \`${outputMode}\``,
|
|
48
|
-
`Review status: \`${reviewStatus}\``,
|
|
49
|
-
"",
|
|
50
|
-
"## Required Files",
|
|
51
|
-
"",
|
|
52
|
-
...requiredCartoonEpisodePackageFiles.map((file) => `- [x] \`${file}\``),
|
|
53
|
-
input.hasPngSequenceFallback ? "- [x] `episode.png-sequence-fallback.json`" : "- [ ] `episode.png-sequence-fallback.json`",
|
|
54
|
-
"",
|
|
55
|
-
"## Episode Summary",
|
|
56
|
-
"",
|
|
57
|
-
`- Runtime: ${episode.episodePlan.runtime.duration}s at ${episode.episodePlan.runtime.frameRate}fps`,
|
|
58
|
-
`- Resolution: ${episode.episodePlan.runtime.resolution.width}x${episode.episodePlan.runtime.resolution.height}`,
|
|
59
|
-
`- Shots: ${episode.shotTimeline.shots.length}`,
|
|
60
|
-
`- Captions: ${episode.captionTrack.cues.length}`,
|
|
61
|
-
`- Characters: ${episode.episodePlan.characters.map((character) => character.name).join(", ")}`,
|
|
62
|
-
`- YouTube draft title: ${youtubeDraftMetadata.title}`,
|
|
63
|
-
"",
|
|
64
|
-
"## Asset Status",
|
|
65
|
-
"",
|
|
66
|
-
`- Status: ${typedAssetStatus}`,
|
|
67
|
-
`- Required typed assets: ${typedCartoonAssetSummary.requiredCharacterAssets.join(", ")}`,
|
|
68
|
-
`- Missing typed assets: ${missingCartoonCharacterAssets.length ? missingCartoonCharacterAssets.join(", ") : "none"}`,
|
|
69
|
-
"",
|
|
70
|
-
"Typed asset commands:",
|
|
71
|
-
"",
|
|
72
|
-
"```bash",
|
|
73
|
-
...publicCartoonAssetInstructions,
|
|
74
|
-
"```",
|
|
75
|
-
"",
|
|
76
|
-
"## Timing Proof",
|
|
77
|
-
"",
|
|
78
|
-
`- Caption timing: ${captionTimingProof.status}`,
|
|
79
|
-
`- Max caption drift frames: ${captionTimingProof.maxDriftFrames}`,
|
|
80
|
-
`- Mouth source sync: ${visemeFrameSyncSourceProof.mouthMovementWithinOneFrame ? "pass" : "fail"}`,
|
|
81
|
-
"",
|
|
82
|
-
"## Human Review Checklist",
|
|
83
|
-
"",
|
|
84
|
-
"- [ ] Both characters are readable in representative frames.",
|
|
85
|
-
"- [ ] Captions do not cover important action.",
|
|
86
|
-
"- [ ] Mouth movement is visible during dialogue in the browser route.",
|
|
87
|
-
"- [ ] Character body motion is more than still-image wobble.",
|
|
88
|
-
"- [ ] No route chrome, proof panels, or debug overlays appear in encoded output.",
|
|
89
|
-
"- [ ] Reviewer name and approval date are recorded before publish-ready claims.",
|
|
90
|
-
"",
|
|
91
|
-
"## Boundary",
|
|
92
|
-
"",
|
|
93
|
-
input.hasWebm
|
|
94
|
-
? "This package includes an encoded WebM output. Human review and asset readiness are still required before public publish-ready claims."
|
|
95
|
-
: "This package uses the PNG-sequence fallback marker because no real browser video encoder was attached. It is useful for package workflow proof, but it is not publish-ready video evidence.",
|
|
96
|
-
"",
|
|
97
|
-
`Render package metadata source: \`${renderOutputPackage.packageId}\``
|
|
98
|
-
].join("\n");
|
|
99
|
-
}
|