Skip to content本文へ移動

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.

  • settings defines dimensions, frame rate, audio sample rate, and optional duration.
  • assets registers source media by id: video, audio, image, or font. Sources can be local files or HTTP(S) URLs; remote files use the native media cache.
  • tracks contains video, audio, overlay, or dialogue tracks and their items.
  • Each item has a range with a start and duration, plus its content and optional transform, opacity, and blendMode.

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="…" />.

Try it without installing.

The playground runs Celesta in your browser, export included.

Open the playground