Legacy JSON timelines
Compatibility guide for existing projects; use React for new work.
A .celesta.json file describes settings, assets, characters, tracks, and properties for older projects. These APIs remain available for compatibility; use React compositions for new work.
settingsdefines dimensions, frame rate, audio sample rate, and optional duration.assetsregisters source media by id:video,audio,image, orfont. Sources can be local files or HTTP(S) URLs; remote files use the native media cache.trackscontains video, audio, overlay, or dialogue tracks and their items.- Each item has a
rangewith a start and duration, plus its content and optionaltransform,opacity, andblendMode.
Time is represented as { value, timescale }: divide the value by the timescale to get seconds. For example, { "value": 10, "timescale": 1 } means ten seconds.
Copy the project below into project.celesta.json in your project folder, then open it with File Open….
View the complete built-in title project
{
"version": 0,
"settings": {
"width": 1280,
"height": 720,
"frameRate": {
"numerator": 60,
"denominator": 1
},
"sampleRate": 48000,
"duration": {
"value": 10,
"timescale": 1
}
},
"assets": {},
"characters": {},
"tracks": [
{
"id": "titles",
"name": "Titles",
"kind": "overlay",
"items": [
{
"id": "welcome",
"name": "Welcome",
"range": {
"start": {
"value": 0,
"timescale": 1
},
"duration": {
"value": 10,
"timescale": 1
}
},
"content": {
"type": "text",
"text": "Celesta",
"style": {
"fontSize": 96,
"fill": {
"type": "solid",
"color": "#FFA13BFF"
},
"align": "center"
}
},
"transform": {
"position": {
"x": 640,
"y": 360
}
}
}
]
}
],
"properties": {
"title": "Celesta editor demo"
}
}examples/minimal.celesta.json is an empty starting point. For a visible result, begin with the title project above, then change the text and save. Use File Reload to update the preview.
celesta-exporter project.celesta.json output.mp4
Animate with keyframes
In a JSON transform, position places the item’s center. Any transform value, opacity, and audio volume can be a fixed number or keyframes. Keyframe times are relative to the item’s start, and easing shapes the curve into that keyframe:
"opacity": {
"type": "keyframes",
"keyframes": [
{ "time": { "value": 0, "timescale": 30 }, "value": 0 },
{ "time": { "value": 15, "timescale": 30 }, "value": 1, "easing": "ease-out" }
]
}
Easing names match the React Easings in kebab case, such as ease-in-out-cubic or ease-out-back.
Dialogue in a JSON project
A JSON project declares characters in characters and lines as items on a dialogue track. The portrait and subtitle transforms position their centers:
View the complete JSON dialogue project
{
"version": 0,
"settings": {
"width": 1920,
"height": 1080,
"frameRate": { "numerator": 30, "denominator": 1 },
"sampleRate": 48000,
"duration": { "value": 6, "timescale": 1 }
},
"assets": {
"mira-calm": { "type": "image", "source": { "type": "file", "path": "./mira/calm.png" } },
"mira-smile": { "type": "image", "source": { "type": "file", "path": "./mira/smile.png" } },
"line-01": { "type": "audio", "source": { "type": "file", "path": "./voices/line-01.wav" } },
"line-02": { "type": "audio", "source": { "type": "file", "path": "./voices/line-02.wav" } }
},
"characters": {
"mira": {
"name": "Mira",
"portrait": {
"defaultExpression": "calm",
"expressions": { "calm": "mira-calm", "smile": "mira-smile" },
"transform": { "position": { "x": 1460, "y": 420 } }
},
"subtitle": {
"style": {
"fontSize": 56,
"fill": { "type": "solid", "color": "#FFFFFFFF" },
"stroke": { "paint": { "type": "solid", "color": "#3A2D52FF" }, "width": 6 },
"align": "center"
},
"transform": { "position": { "x": 960, "y": 940 } },
"maxWidth": 1600
}
}
},
"tracks": [
{
"id": "dialogue",
"name": "Dialogue",
"kind": "dialogue",
"items": [
{
"id": "line-01",
"range": {
"start": { "value": 0, "timescale": 1 },
"duration": { "value": 3, "timescale": 1 }
},
"content": {
"type": "dialogue",
"character": "mira",
"text": "Welcome back. Shall we begin?",
"audio": "line-01"
}
},
{
"id": "line-02",
"range": {
"start": { "value": 3, "timescale": 1 },
"duration": { "value": 3, "timescale": 1 }
},
"content": {
"type": "dialogue",
"character": "mira",
"text": "Every scene starts with a single line.",
"audio": "line-02",
"expression": "smile"
}
}
]
}
],
"properties": {}
}JSON lines can lip-sync as well: add mouth-image asset ids under the portrait’s lipSync, and list timed shapes on the line, such as "lipSync": [{ "time": { "value": 0, "timescale": 30 }, "shape": "a" }]. Cue times are relative to the line’s start. For automatic timing from the recording, use React’s loadLipSync().
Combine a project with React
A React composition can include <ProjectTimeline />. Pass its companion JSON project when exporting so Celesta can resolve the timeline:
celesta-exporter --react with-project.tsx --project project.celesta.json output.mp4
View the companion React composition
import { Composition, Text } from '@celesta/react';
import { ProjectTimeline } from '@celesta/project';
export default function Root() {
return (
<Composition width={640} height={360} fps={30} durationInFrames={30}>
<ProjectTimeline />
<Text
x={320}
y={40}
anchorX={0.5}
anchorY={0.5}
style={{ fontSize: 24, fill: { type: 'solid', color: '#ffffff' } }}
>
React overlay
</Text>
</Composition>
);
}Save this as with-project.tsx beside your JSON file. The command above assumes celesta-exporter is on PATH; see Export a video for the installed executable paths. To draw one track, use <ProjectTrack id="…" />.