project.json

The whole edit in one file: canvas, markers, tracks, media and clips.

{
  "name": "My Edit",
  "width": 1280, "height": 720, "fps": 30,   // composition canvas + timeline/export rate — sole FPS source (UI: FPS select)
  "exportFrame": { "x": 438, "y": 0, "w": 404, "h": 720 },  // optional delivery crop (even w/h for H.264)
  // ^ omit = export the full canvas. Preview dims outside this rect; Fast export crops
  // JPEGs to w×h. Clip x/y/scale stay relative to the composition center, not the frame.
  // Frame size is always even (yuv420p / libx264); 9:16 on 1280×720 → 404×720, not 405.
  "background": "#000000",                    // canvas color behind all clips (optional)
  "revision": 7,                              // bump on every write!
  "panSchema": 1,                             // 1 = pan-aware; omit only on pre-pan projects (UI migrates once)
  "markers": [ { "t": 2.5 }, { "t": 5.0, "label": "drop", "color": "red" } ],
  // ^ beat/cue markers: diamonds on the ruler (label shown beside them), snap
  //   targets for clip edges. color: gold (default) · red · orange · green ·
  //   cyan · blue · purple · pink. Kept sorted by t; the UI rounds t to 1 ms.
  "inPoint": 10.023, // IN work-area marker (Limit playback + optional export range)
  "outPoint": 21.500, // OUT work-area marker; omit = timeline end
  "folders": [
    // Project-bin virtual folders (tree). Media reference them via folderId.
    { "id": "f_broll", "name": "B-roll", "parentId": null, "open": true }
  ],
  "disabledTracks": [ "A2" ],
  // ^ optional — track ids (e.g. V4 V3 V2 V1 A1 A2 A3) omitted from preview/export when listed
  "lockedTracks": [ "A3" ],
  // ^ optional — locked lanes: nothing on them may be edited or moved (see Semantics)
  "untargetedTracks": [ "V2" ],
  // ^ optional — lanes edits skip (split, insert, ripple, close gap…); default: all targeted
  "encodeProfile": "hq",  // optional — fast-export profile id (see encoding-profiles.json)
  "delivery": { "preset": "youtube", "width": 1920, "height": 1080, "…": "…" },
  // ^ optional — the delivery spec exports use by default (see "Delivery presets"); setProject takes a preset id
  "outputs": [ { "id": "o_1", "on": true, "preset": "master", "…": "…" } ],
  // ^ optional — batch outputs: files made together, one render per frame rate (see "Batch outputs and the export queue")
  "master": { "gain": -1.5, "fx": [ { "type": "limiter", "ceiling": -1 } ] },
  // ^ optional — master fader, dB (−60 = silence … +12; omit = 0 dB) and master effects (see "Audio mix")
  "tracks": [                          // optional — timeline lanes (default V3…V1 + A1…A4)
    { "id": "V3", "kind": "video" },   // video: higher number drawn on top (V1 under V2 under V3…)
    { "id": "V2", "kind": "video" },
    { "id": "V1", "kind": "video" },
    { "id": "A1", "kind": "audio", "gain": -6, "pan": 0, "out": "B1" },   // audio: A1…An top→bottom; +V/+A appends Vn+1 / An+1
    // ^ gain = track fader in dB (−60 = silence … +12), pan = −1…1, fx = track effects,
    //   out = the submix bus it feeds (default: the master); all optional
    { "id": "A2", "kind": "audio" },
    { "id": "A3", "kind": "audio" },
    { "id": "A4", "kind": "audio" }
  ],
  "buses": [ { "id": "B1", "name": "Dialogue", "gain": -2, "fx": [ { "type": "compressor" } ] } ],
  // ^ optional — submix buses B1…B8: name, gain (dB), pan, mute, fx; tracks route in with `out`
  "collections": [ { "id": "col_sel", "name": "Selects", "media": [ "m_abc" ] } ],
  // ^ optional — Project-bin collections: media grouped across folders; see "Media management"
  "comps": [ { "id": "lt", "name": "Lower third", "width": 1280, "height": 720, "duration": 5, "clips": [ /* … */ ] } ],
  // ^ optional — compositions (nested sequences), placed with kind:"comp" clips; see "Compositions (nested sequences)"
  "sequence": "main", "sequences": [ { "id": "main", "name": "Main" }, { "id": "seq_v9", "name": "Reel 9:16", "width": 1080, "height": 1920, "clips": [ /* … */ ] } ],
  // ^ optional — several timelines in one project; the open one is this top level; see "Sequences"
  "media": [
    { "id": "m_abc", "name": "intro.mp4", "kind": "video",  // video|audio|image|svg
      "src": "/media/intro.mp4",             // path under ./media or ./library (never a raw https:// URL)
      "duration": 12.4, "width": 1920, "height": 1080,
      "fps": 29.97, "codec": "h264", "audioCodec": "aac", "audioChannels": 2, "sampleRate": 48000,
      "size": 45200000, "bitrate": 29300000, // probed from the file (read-only; see "Media management")
      "favorite": true, "tags": [ "interview", "day 1" ],   // optional: bin organization
      "folderId": null },                    // optional: id of a folders[] entry
    { "id": "m_abd", "name": "intro.denoise-medium.flac", "kind": "audio", "src": "/media/intro.denoise-medium.flac",
      "derivedFrom": "m_abc", "denoise": "medium" }  // a noise-reduced copy of m_abc (see "Audio mix")
  ],
  "clips": [
    {
      "id": "c_xyz",             // unique string
      "mediaId": "m_abc",        // null for kind:"text", "adjust", "shape", "null" and "comp"
      "kind": "video",           // video | audio | image | svg | text | adjust | shape | null | comp
      // kind:"comp" also has "compId" (a comps[] entry) — see "Compositions (nested sequences)"
      "track": "V1",             // Vn…V1 (video) | A1…An (audio); extras via UI +V/+A or tracks[]
      "start": 0,                // timeline position, seconds
      "in": 2.5,                 // offset into source media, seconds (0 for image/svg/text)
      "duration": 5,             // clip length on timeline, seconds
      "name": "intro",
      "linkGroup": "lg_abc",     // OPTIONAL — AV link: video + per-channel audio stems share one id
      "locked": true,            // OPTIONAL — locked by the user: leave it alone (MCP patch refuses edits)
      "disabled": true,          // OPTIONAL — stays on the timeline, hidden from preview / audio / export
      "unlinked": true,          // OPTIONAL — the user unlinked this clip; never auto-relinked on load
      "parent": "c_null",        // OPTIONAL — moves, turns and scales with that clip (see "Shapes, nulls and parenting")
      "props": { /* all optional — see the props reference below */ },
      // OPTIONAL — keyframe animation. Times are seconds RELATIVE TO CLIP START.
      // "ease" sits on the DESTINATION keyframe of each segment:
      // linear | ease-in | ease-out | ease-in-out (default ease-in-out).
      // x and y keys at the same time are a position key; pin / pout on them (px)
      // are motion-path curve handles (see "Motion paths, motion blur and text on a path").
      "keyframes": {
        "scale":   [ { "t": 0, "v": 1 }, { "t": 5, "v": 1.25, "ease": "linear" } ],
        "opacity": [ { "t": 0, "v": 0 }, { "t": 0.8, "v": 1 } ]
      },
      // OPTIONAL — audio effects (audio clips), processed in order. See "Audio mix".
      "fx": [ { "type": "highpass", "freq": 80 }, { "type": "compressor", "threshold": -20, "ratio": 4 } ],
      // OPTIONAL — transitions at the clip's head/tail.
      "transitionIn":  { "type": "fade", "duration": 0.8 },
      "transitionOut": { "type": "slide-left", "duration": 0.6 }
    }
  ]
}