- Verovio single-system engraving, MuseScore audio/MIDI from the same source - React + Remotion player with live camera, colour and orb controls - Express pipeline, render queue and local H.264/AAC export - MIT license plus third-party notices for the reference skill
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import fs from 'node:fs';
|
|
import {buildScrollKeys} from '../src/shared/scroll.js';
|
|
import type {RenderData, VisualSettings} from '../src/shared/types.js';
|
|
|
|
/** Builds Remotion still props for a finished job, using exactly its saved settings. */
|
|
const id = process.argv[2];
|
|
if (!id) throw new Error('usage: tsx scripts/props-from-job.ts <jobId> [outFile]');
|
|
const out = process.argv[3] ?? 'data/check/p-job.json';
|
|
|
|
const data = JSON.parse(fs.readFileSync(`data/jobs/${id}/score.json`, 'utf8')) as RenderData;
|
|
const job = JSON.parse(fs.readFileSync(`data/jobs/${id}/job.json`, 'utf8')) as {
|
|
settings?: Partial<VisualSettings>;
|
|
};
|
|
const settings: VisualSettings = {...data.settings, ...(job.settings ?? {})};
|
|
|
|
const displayHeight = settings.height * settings.scoreHeightRatio;
|
|
const displayScale = displayHeight / Math.max(1, data.meta.svgHeight);
|
|
const viewWidthScore = settings.width / displayScale;
|
|
const maxLeft = Math.max(0, data.meta.svgWidth - viewWidthScore);
|
|
const scroll = buildScrollKeys(
|
|
data.events,
|
|
settings.scrollLead,
|
|
viewWidthScore,
|
|
maxLeft,
|
|
data.meta.musicDuration,
|
|
);
|
|
|
|
fs.writeFileSync(
|
|
out,
|
|
JSON.stringify(
|
|
{
|
|
data: {
|
|
...data,
|
|
settings,
|
|
scroll,
|
|
svgUrl: `http://127.0.0.1:3001/jobs/${id}/score.svg`,
|
|
audioUrl: `http://127.0.0.1:3001/jobs/${id}/audio.wav`,
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
console.log(`${out}: ${settings.width}x${settings.height} tiltX=${settings.tiltX} tiltZ=${settings.tiltZ}`);
|