feat: add adaptive soundtrack layer assets
This commit is contained in:
@@ -47,6 +47,54 @@
|
||||
"rightsHolder": "Luca Pîslaru",
|
||||
"license": "All rights reserved",
|
||||
"attribution": "Original AI-assisted soundtrack produced by Luca Pîslaru with ACE-Step 1.5"
|
||||
},
|
||||
{
|
||||
"id": "soundtrack-afterglow-opus",
|
||||
"fileName": "nightdrive-afterglow.opus",
|
||||
"sha256": "693215397e8ae4c2c13a4a6e4cc74b0059fb26b396c7f35d99e0e2c3e738d4b1",
|
||||
"mediaType": "audio/ogg",
|
||||
"width": null,
|
||||
"height": null,
|
||||
"durationMs": 25123,
|
||||
"rightsHolder": "Luca Pîslaru",
|
||||
"license": "All rights reserved",
|
||||
"attribution": "Original AI-assisted soundtrack produced by Luca Pîslaru with ACE-Step 1.5"
|
||||
},
|
||||
{
|
||||
"id": "soundtrack-afterglow-mp3",
|
||||
"fileName": "nightdrive-afterglow.mp3",
|
||||
"sha256": "685687ad131d61c34e42bcee29af16a4c8180d788c67d75f2331fa9082a3a44e",
|
||||
"mediaType": "audio/mpeg",
|
||||
"width": null,
|
||||
"height": null,
|
||||
"durationMs": 25116,
|
||||
"rightsHolder": "Luca Pîslaru",
|
||||
"license": "All rights reserved",
|
||||
"attribution": "Original AI-assisted soundtrack produced by Luca Pîslaru with ACE-Step 1.5"
|
||||
},
|
||||
{
|
||||
"id": "soundtrack-drive-lift-opus",
|
||||
"fileName": "nightdrive-drive-lift.opus",
|
||||
"sha256": "d580e58039c9d700599cf100c96b50d4b5816d93a0af738a93a1e8646fbb7566",
|
||||
"mediaType": "audio/ogg",
|
||||
"width": null,
|
||||
"height": null,
|
||||
"durationMs": 11169,
|
||||
"rightsHolder": "Luca Pîslaru",
|
||||
"license": "All rights reserved",
|
||||
"attribution": "Original AI-assisted soundtrack produced by Luca Pîslaru with ACE-Step 1.5"
|
||||
},
|
||||
{
|
||||
"id": "soundtrack-drive-lift-mp3",
|
||||
"fileName": "nightdrive-drive-lift.mp3",
|
||||
"sha256": "edcb802938d3d1e53392f9ccd2e153f72a24b494c205ce6f556d73de5fe709ec",
|
||||
"mediaType": "audio/mpeg",
|
||||
"width": null,
|
||||
"height": null,
|
||||
"durationMs": 11163,
|
||||
"rightsHolder": "Luca Pîslaru",
|
||||
"license": "All rights reserved",
|
||||
"attribution": "Original AI-assisted soundtrack produced by Luca Pîslaru with ACE-Step 1.5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -253,6 +253,14 @@
|
||||
"main": {
|
||||
"opusAssetId": "soundtrack-main-opus",
|
||||
"mp3AssetId": "soundtrack-main-mp3"
|
||||
},
|
||||
"afterglow": {
|
||||
"opusAssetId": "soundtrack-afterglow-opus",
|
||||
"mp3AssetId": "soundtrack-afterglow-mp3"
|
||||
},
|
||||
"driveLift": {
|
||||
"opusAssetId": "soundtrack-drive-lift-opus",
|
||||
"mp3AssetId": "soundtrack-drive-lift-mp3"
|
||||
}
|
||||
},
|
||||
"sceneDescription": "A restrained retro-futuristic night drive supports the reading journey while the portfolio content remains fully available as a semantic document."
|
||||
|
||||
BIN
inputs/prepared-assets/nightdrive-afterglow.mp3
Normal file
BIN
inputs/prepared-assets/nightdrive-afterglow.mp3
Normal file
Binary file not shown.
BIN
inputs/prepared-assets/nightdrive-afterglow.opus
Normal file
BIN
inputs/prepared-assets/nightdrive-afterglow.opus
Normal file
Binary file not shown.
BIN
inputs/prepared-assets/nightdrive-drive-lift.mp3
Normal file
BIN
inputs/prepared-assets/nightdrive-drive-lift.mp3
Normal file
Binary file not shown.
BIN
inputs/prepared-assets/nightdrive-drive-lift.opus
Normal file
BIN
inputs/prepared-assets/nightdrive-drive-lift.opus
Normal file
Binary file not shown.
@@ -76,7 +76,12 @@ for (const group of content.toolkit ?? []) for (const technology of group.techno
|
||||
}
|
||||
if (content.metadata?.socialPreviewAssetId) assetClassById.set(content.metadata.socialPreviewAssetId, 'project-still');
|
||||
if (content.soundtrack) {
|
||||
for (const region of [content.soundtrack.intro, content.soundtrack.main]) {
|
||||
for (const region of [
|
||||
content.soundtrack.intro,
|
||||
content.soundtrack.main,
|
||||
content.soundtrack.afterglow,
|
||||
content.soundtrack.driveLift,
|
||||
]) {
|
||||
if (region?.opusAssetId) assetClassById.set(region.opusAssetId, 'soundtrack-audio');
|
||||
if (region?.mp3AssetId) assetClassById.set(region.mp3AssetId, 'soundtrack-audio');
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const PERFORMANCE_BUDGETS = Object.freeze({
|
||||
deferredProjectVisuals: 2.5 * 1024 * 1024,
|
||||
highTierExtras: 750 * 1024,
|
||||
deferredNonVideo: 3.5 * 1024 * 1024,
|
||||
deferredAudio: 13 * 1024 * 1024,
|
||||
deferredAudio: 16 * 1024 * 1024,
|
||||
imageSceneConcurrency: 2,
|
||||
videoConcurrency: 1,
|
||||
mobileTextureDimension: 2048,
|
||||
@@ -44,7 +44,7 @@ export const classifyArtifact = (path, source = '') => {
|
||||
if (/^assets\/project-[^/]+\.(?:webm|mp4)$/u.test(path)) return 'project-video';
|
||||
if (/^assets\/project-[^/]*chart[^/]*\.(?:avif|webp|png|jpe?g)$/u.test(path)) return 'chart';
|
||||
if (/^assets\/project-[^/]+\.(?:avif|webp|png|jpe?g|svg)$/u.test(path)) return 'project-still';
|
||||
if (/^assets\/nightdrive-(?:intro|main)\.(?:opus|mp3)$/u.test(path)) return 'soundtrack-audio';
|
||||
if (/^assets\/nightdrive-(?:intro|main|afterglow|drive-lift)\.(?:opus|mp3)$/u.test(path)) return 'soundtrack-audio';
|
||||
if (/^(?:robots\.txt|sitemap\.xml|_headers\.example|_redirects\.example)$/u.test(path)) return 'release-metadata';
|
||||
throw new Error(`Artifact is unclassified: ${path}`);
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ const assetReferences = (content) => {
|
||||
if (typeof content.soundtrack !== 'object' || content.soundtrack === null || Array.isArray(content.soundtrack)) {
|
||||
throw new Error('Portfolio soundtrack must be an object.');
|
||||
}
|
||||
for (const regionName of ['intro', 'main']) {
|
||||
for (const regionName of ['intro', 'main', 'afterglow', 'driveLift']) {
|
||||
const region = content.soundtrack[regionName];
|
||||
if (typeof region !== 'object' || region === null || Array.isArray(region)) {
|
||||
throw new Error(`Portfolio soundtrack ${regionName} must be an object.`);
|
||||
|
||||
@@ -202,6 +202,8 @@ const portfolioContentSchema = z.object({
|
||||
soundtrack: z.object({
|
||||
intro: soundtrackAssetSourcesSchema,
|
||||
main: soundtrackAssetSourcesSchema,
|
||||
afterglow: soundtrackAssetSourcesSchema,
|
||||
driveLift: soundtrackAssetSourcesSchema,
|
||||
}).strict().optional(),
|
||||
sceneDescription: visibleString,
|
||||
}).strict().superRefine((content, context) => {
|
||||
@@ -321,6 +323,10 @@ export const parseProductionInputSnapshot = (input: unknown): ProductionInputs =
|
||||
content.soundtrack.intro.mp3AssetId,
|
||||
content.soundtrack.main.opusAssetId,
|
||||
content.soundtrack.main.mp3AssetId,
|
||||
content.soundtrack.afterglow.opusAssetId,
|
||||
content.soundtrack.afterglow.mp3AssetId,
|
||||
content.soundtrack.driveLift.opusAssetId,
|
||||
content.soundtrack.driveLift.mp3AssetId,
|
||||
]),
|
||||
];
|
||||
const seenReferences = new Set<string>();
|
||||
|
||||
@@ -141,6 +141,8 @@ export interface SoundtrackAssetSources {
|
||||
export interface SoundtrackContent {
|
||||
intro: SoundtrackAssetSources;
|
||||
main: SoundtrackAssetSources;
|
||||
afterglow: SoundtrackAssetSources;
|
||||
driveLift: SoundtrackAssetSources;
|
||||
}
|
||||
|
||||
export interface PortfolioContent {
|
||||
|
||||
@@ -64,6 +64,10 @@ describe('approved asset publication closure', () => {
|
||||
['soundtrack-intro-mp3', 'nightdrive-intro.mp3'],
|
||||
['soundtrack-main-opus', 'nightdrive-main.opus'],
|
||||
['soundtrack-main-mp3', 'nightdrive-main.mp3'],
|
||||
['soundtrack-afterglow-opus', 'nightdrive-afterglow.opus'],
|
||||
['soundtrack-afterglow-mp3', 'nightdrive-afterglow.mp3'],
|
||||
['soundtrack-drive-lift-opus', 'nightdrive-drive-lift.opus'],
|
||||
['soundtrack-drive-lift-mp3', 'nightdrive-drive-lift.mp3'],
|
||||
].map(([id, fileName], index) => {
|
||||
const bytes = Buffer.from(`approved soundtrack asset ${index}`);
|
||||
return { id, fileName, bytes, sha256: createHash('sha256').update(bytes).digest('hex') };
|
||||
@@ -78,6 +82,8 @@ describe('approved asset publication closure', () => {
|
||||
soundtrack: {
|
||||
intro: { opusAssetId: 'soundtrack-intro-opus', mp3AssetId: 'soundtrack-intro-mp3' },
|
||||
main: { opusAssetId: 'soundtrack-main-opus', mp3AssetId: 'soundtrack-main-mp3' },
|
||||
afterglow: { opusAssetId: 'soundtrack-afterglow-opus', mp3AssetId: 'soundtrack-afterglow-mp3' },
|
||||
driveLift: { opusAssetId: 'soundtrack-drive-lift-opus', mp3AssetId: 'soundtrack-drive-lift-mp3' },
|
||||
},
|
||||
}));
|
||||
await mkdir(join(root, 'inputs/prepared-assets'), { recursive: true });
|
||||
|
||||
@@ -47,6 +47,10 @@ describe('approved public portfolio projection', () => {
|
||||
content.soundtrack.intro.mp3AssetId,
|
||||
content.soundtrack.main.opusAssetId,
|
||||
content.soundtrack.main.mp3AssetId,
|
||||
content.soundtrack.afterglow.opusAssetId,
|
||||
content.soundtrack.afterglow.mp3AssetId,
|
||||
content.soundtrack.driveLift.opusAssetId,
|
||||
content.soundtrack.driveLift.mp3AssetId,
|
||||
]),
|
||||
];
|
||||
expect([...publishedReferences].sort()).toEqual(manifest.assets.map((asset) => asset.id).sort());
|
||||
|
||||
@@ -118,6 +118,28 @@ describe('artifact verification', () => {
|
||||
await expect(verifyArtifactDirectory(directory, inputs, contract)).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'an omitted adaptive soundtrack file',
|
||||
mutate: async (directory: string) => rm(join(directory, 'assets/nightdrive-afterglow.opus')),
|
||||
error: /missing.*artifact|digest|public asset/iu,
|
||||
},
|
||||
{
|
||||
name: 'an altered adaptive soundtrack file',
|
||||
mutate: async (directory: string) => writeFile(join(directory, 'assets/nightdrive-drive-lift.mp3'), 'altered'),
|
||||
error: /digest does not match|hash/u,
|
||||
},
|
||||
{
|
||||
name: 'an unreferenced adaptive soundtrack file',
|
||||
mutate: async (directory: string) => writeFile(join(directory, 'assets/nightdrive-unreferenced.opus'), 'unreferenced'),
|
||||
error: /unexpected artifact|unreferenced/u,
|
||||
},
|
||||
])('rejects $name', async ({ mutate, error }) => {
|
||||
const { directory, inputs, contract } = await writeValidArtifacts();
|
||||
await mutate(directory);
|
||||
await expect(verifyArtifactDirectory(directory, inputs, contract)).rejects.toThrow(error);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'an unexpected preview sitemap',
|
||||
|
||||
@@ -31,6 +31,7 @@ describe('release budgets', () => {
|
||||
});
|
||||
|
||||
it('pins every exact section 14 threshold', () => {
|
||||
expect(PERFORMANCE_BUDGETS.deferredAudio).toBe(16 * 1024 * 1024);
|
||||
expect(PERFORMANCE_BUDGETS).toMatchObject({
|
||||
initialHtmlCriticalCss: 100 * 1024,
|
||||
initialApplicationJs: 120 * 1024,
|
||||
@@ -46,7 +47,7 @@ describe('release budgets', () => {
|
||||
deferredProjectVisuals: 2.5 * 1024 * 1024,
|
||||
highTierExtras: 750 * 1024,
|
||||
deferredNonVideo: 3.5 * 1024 * 1024,
|
||||
deferredAudio: 13 * 1024 * 1024,
|
||||
deferredAudio: 16 * 1024 * 1024,
|
||||
imageSceneConcurrency: 2,
|
||||
videoConcurrency: 1,
|
||||
mobileTextureDimension: 2048,
|
||||
@@ -63,6 +64,10 @@ describe('release budgets', () => {
|
||||
expect(classifyArtifact('assets/nightdrive-grand-tourer-a.glb', '')).toBe('first-live-scene');
|
||||
expect(classifyArtifact('assets/nightdrive-main.opus', '')).toBe('soundtrack-audio');
|
||||
expect(classifyArtifact('assets/nightdrive-intro.mp3', '')).toBe('soundtrack-audio');
|
||||
expect(classifyArtifact('assets/nightdrive-afterglow.opus', '')).toBe('soundtrack-audio');
|
||||
expect(classifyArtifact('assets/nightdrive-afterglow.mp3', '')).toBe('soundtrack-audio');
|
||||
expect(classifyArtifact('assets/nightdrive-drive-lift.opus', '')).toBe('soundtrack-audio');
|
||||
expect(classifyArtifact('assets/nightdrive-drive-lift.mp3', '')).toBe('soundtrack-audio');
|
||||
expect(classifyArtifact('assets/high-tier-b.js', 'optional bloom')).toBe('high-tier-extras');
|
||||
expect(() => classifyArtifact('assets/mystery.bin', '')).toThrow(/unclassified/u);
|
||||
});
|
||||
|
||||
@@ -27,6 +27,8 @@ type MutableContentFixture = {
|
||||
soundtrack?: {
|
||||
intro: { opusAssetId: string; mp3AssetId: string };
|
||||
main: { opusAssetId: string; mp3AssetId: string };
|
||||
afterglow: { opusAssetId: string; mp3AssetId: string };
|
||||
driveLift: { opusAssetId: string; mp3AssetId: string };
|
||||
};
|
||||
};
|
||||
|
||||
@@ -48,6 +50,8 @@ describe('content schemas', () => {
|
||||
content.soundtrack = {
|
||||
intro: { opusAssetId: 'soundtrack-intro-opus', mp3AssetId: 'soundtrack-intro-mp3' },
|
||||
main: { opusAssetId: 'soundtrack-main-opus', mp3AssetId: 'soundtrack-main-mp3' },
|
||||
afterglow: { opusAssetId: 'soundtrack-afterglow-opus', mp3AssetId: 'soundtrack-afterglow-mp3' },
|
||||
driveLift: { opusAssetId: 'soundtrack-drive-lift-opus', mp3AssetId: 'soundtrack-drive-lift-mp3' },
|
||||
};
|
||||
const audioMetadata = {
|
||||
width: null,
|
||||
@@ -61,6 +65,10 @@ describe('content schemas', () => {
|
||||
{ id: 'soundtrack-intro-mp3', fileName: 'nightdrive-intro.mp3', sha256: 'b'.repeat(64), mediaType: 'audio/mpeg', durationMs: 56_064, ...audioMetadata },
|
||||
{ id: 'soundtrack-main-opus', fileName: 'nightdrive-main.opus', sha256: 'c'.repeat(64), mediaType: 'audio/ogg', durationMs: 178_605, ...audioMetadata },
|
||||
{ id: 'soundtrack-main-mp3', fileName: 'nightdrive-main.mp3', sha256: 'd'.repeat(64), mediaType: 'audio/mpeg', durationMs: 178_605, ...audioMetadata },
|
||||
{ id: 'soundtrack-afterglow-opus', fileName: 'nightdrive-afterglow.opus', sha256: 'e'.repeat(64), mediaType: 'audio/ogg', durationMs: 56_064, ...audioMetadata },
|
||||
{ id: 'soundtrack-afterglow-mp3', fileName: 'nightdrive-afterglow.mp3', sha256: 'f'.repeat(64), mediaType: 'audio/mpeg', durationMs: 56_064, ...audioMetadata },
|
||||
{ id: 'soundtrack-drive-lift-opus', fileName: 'nightdrive-drive-lift.opus', sha256: '1'.repeat(64), mediaType: 'audio/ogg', durationMs: 178_605, ...audioMetadata },
|
||||
{ id: 'soundtrack-drive-lift-mp3', fileName: 'nightdrive-drive-lift.mp3', sha256: '2'.repeat(64), mediaType: 'audio/mpeg', durationMs: 178_605, ...audioMetadata },
|
||||
];
|
||||
const manifest = {
|
||||
assets: [...(validManifest as { assets: unknown[] }).assets, ...soundtrackAssets],
|
||||
|
||||
Reference in New Issue
Block a user