Developer docs

Developer docs/API

Methods

Every method the API answers, what it takes, what it gives back.

Cheat sheet

MethodDoesReplies with
versionwhat this build servesVersionInfo
project.createnew project folder, openedEditorView
project.openopen a folderEditorView
project.closeclose, optionally save{}
project.listrecent projectsProjectInfo[]
project.getcurrent stateEditorView
project.documentthe concat.json a save writesJSON object
project.savewrite to disk, optionally rename{}
project.setVideoframe size and rate (undoable)EditorView
edit.applyone edit commandEditorView
edit.undostep backEditorView
edit.redostep forwardEditorView
media.probewhat is in a fileMediaSummary
media.importprobe + add to binEditorView
catalogue.listeffect packages and their paramsPackageInfo[]
template.listthe template libraryTemplateInfo[]
template.instantiateproject from a templateEditorView
template.saveproject into a templateTemplateInfo
export.runrender to a file, as a jobStarted
export.cancelstop a job{}
preview.frameone frame as PNGWritten or Picture

Types in italics are in Types.

How to read this page

  • Examples are bare requests, the shape concat-cli api takes on stdin. On a socket or over gRPC the same fields go in params inside the envelope. See JSON-RPC.
  • Replies are shown as the result payload alone.
  • optional parameters may be left out; the default is stated.
  • path is always the project folder, and it must be open first, or the reply is notOpen.

version

What this build serves. Call it first.

Parameters: none.

{ "method": "version" }

Reply, a VersionInfo:

{
  "apiVersion": "0.2",
  "concat": "0.2.4",
  "dirs": {
    "config": "/Users/ada/Library/Application Support/app.concat.editor",
    "data": "/Users/ada/Library/Application Support/app.concat.editor"
  },
  "capabilities": ["events", "gpu", "json-rpc"]
}

The capability names and the bump rules are in the overview.


project.create

Creates a project folder and opens it.

ParameterTypeMeaning
locationstringThe directory the project folder is made in
namestringThe project’s name. The folder is named after it; characters a filesystem refuses become -
videoVideoSettingsoptional. Frame and rate. Default: 1920×1080 at 30 fps
{
  "method": "project.create",
  "location": "/edits",
  "name": "Reel",
  "video": { "width": 1080, "height": 1920, "rateNum": 30, "rateDen": 1 }
}

Reply: an EditorView of the new project.

Good to know:

  • A fresh project has one timeline TL1 with four tracks T1–T4.
  • It is added to the recents list, like one the window made.
  • A folder that already holds a project is refused (failed).
  • Over a socket, location must lie under one of the server’s write roots, or the request is refused; see the JSON-RPC transport’s Security. A folder the window has open is refused too.

project.open

Opens a project folder.

ParameterTypeMeaning
pathstringThe project folder
{ "method": "project.open", "path": "/edits/Reel" }

Reply: an EditorView.

Good to know:

  • Opening a folder already open returns its state as it stands, edits and all. The history is untouched.

project.close

Closes an open project.

ParameterTypeMeaning
pathstringThe project folder
savebooloptional. Write the document first. Default: false
{ "method": "project.close", "path": "/edits/Reel", "save": true }

Reply: {}.

A running export is not affected; it holds its own copy of what it needs.


project.list

The projects this machine opened most recently, newest first.

Parameters: none.

Reply: an array of ProjectInfo.

[
  {
    "path": "/edits/Reel",
    "name": "Reel",
    "width": 1920,
    "height": 1080,
    "rateNum": 30,
    "rateDen": 1,
    "openedAt": 1790002385144
  }
]

This is the launch screen’s list. It names projects whether or not they are open now.


project.get

The state of an open project.

ParameterTypeMeaning
pathstringThe project folder

Reply: an EditorView.


project.document

The document exactly as a save writes it: the contents of concat.json.

ParameterTypeMeaning
pathstringThe project folder

Reply: the document, a JSON object.


project.save

Writes the document to the project folder.

ParameterTypeMeaning
pathstringThe project folder
namestringoptional. A new name for the project

Reply: {}.


project.setVideo

Sets the active timeline’s frame and rate, as an undoable edit.

ParameterTypeMeaning
pathstringThe project folder
videoVideoSettingsThe frame and rate
{
  "method": "project.setVideo",
  "path": "/edits/Reel",
  "video": { "width": 3840, "height": 2160, "rateNum": 60, "rateDen": 1 }
}

Reply: an EditorView.

A zero dimension or rate is refused.


edit.apply

Applies one edit command and records one undo step.

ParameterTypeMeaning
pathstringThe project folder
commandCommandThe edit: {"op": "…", …fields}. All of them are in Edit commands
{
  "method": "edit.apply",
  "path": "/edits/Reel",
  "command": { "op": "addClip", "mediaId": "m1", "trackId": "T1", "start": 2.5 }
}

Reply: an EditorView of the project after the edit.

Good to know:

  • createdId in the reply is the id of what the command made: a clip c…, track t…, timeline tl… or media m…. For a batch it is the last id minted inside.
  • A refusal is a refused error. Its message is the sentence the window would show. Nothing changed.
  • An edit that names something no longer there is, for most commands, a tolerated no-op: unchanged view, no undo step.
  • Several commands as one undo step: wrap them in {"op": "batch", "commands": [...]}.

edit.undo

Steps the history back one edit.

ParameterTypeMeaning
pathstringThe project folder

Reply: an EditorView. With nothing to undo, it is the unchanged view. canUndo and canRedo say where the history stands.


edit.redo

Steps the history forward one edit.

ParameterTypeMeaning
pathstringThe project folder

Reply: an EditorView.


media.probe

What is inside a media file. Touches no project.

ParameterTypeMeaning
pathstringThe file
{ "method": "media.probe", "path": "/footage/take1.mp4" }

Reply: a MediaSummary.

{
  "path": "/footage/take1.mp4",
  "duration": 6.121029,
  "kind": "video",
  "video": {
    "index": 0,
    "codec": "h264",
    "width": 854,
    "height": 480,
    "frameRate": 30.0,
    "frameRateFraction": "30/1"
  },
  "audio": {
    "index": 1,
    "codec": "aac",
    "sampleRate": 48000,
    "channels": 2,
    "title": "",
    "language": "und"
  },
  "audioTracks": [
    {
      "index": 1,
      "codec": "aac",
      "sampleRate": 48000,
      "channels": 2,
      "title": "",
      "language": "und"
    },
    {
      "index": 2,
      "codec": "aac",
      "sampleRate": 48000,
      "channels": 2,
      "title": "",
      "language": "und"
    }
  ]
}

A file that cannot be read or decoded is failed.


media.import

Probes a file and adds it to the project’s bin. What dropping a file on the window does.

ParameterTypeMeaning
pathstringThe project folder
filestringThe file to import
{ "method": "media.import", "path": "/edits/Reel", "file": "/footage/take1.mp4" }

Reply: an EditorView. createdId is the new media id (m1, m2, …).

Good to know:

  • A path already in the bin is a no-op, and createdId is absent.
  • This is media.probe + the addMedia command, as one request.
  • The bin item’s fields are in Types → MediaItem.

catalogue.list

Every effect package the build knows, with its parameters. Enough to build a valid effect chain without reading a manifest.

ParameterTypeMeaning
kindstringoptional. One of effect, filter, audio, transition, generator. Default: all kinds. Any other word is invalid
{ "method": "catalogue.list", "kind": "effect" }

Reply: an array of PackageInfo, in id order.

[
  {
    "id": "concat.gaussian-blur",
    "name": "Gaussian Blur",
    "kind": "effect",
    "category": "Blur",
    "description": "A soft, even blur.",
    "intensity": "radius",
    "params": [
      {
        "key": "radius",
        "label": "Radius",
        "type": "float",
        "min": 1.0,
        "max": 50.0,
        "default": 10.0,
        "step": 1.0,
        "unit": "px",
        "animate": false,
        "values": [],
        "labels": []
      }
    ]
  }
]

How to use it:

  • id is what a clip’s chain stores: in videoEffects, filters, or a transitionIn.
  • each param’s key is what the chain entry’s params object stores it under. See Types → AppliedFilter.

template.list

The template library.

Parameters: none.

Reply: an array of TemplateInfo, each naming its slots.

What a template is: a bundle folder under templates/ in the config directory, holding template.json (a project document whose placeholder media have blank paths), assets/ (media and fonts that are part of the design) and poster.jpg.


template.instantiate

Makes a project from a template with every slot filled, and opens it.

ParameterTypeMeaning
templatestringThe bundle folder, as template.list gave it
locationstringThe directory the project folder is made in
namestringThe project’s name
fillsarray of {"mediaId", "file"}The file for each slot. mediaId is the slot’s id from template.list
{
  "method": "template.instantiate",
  "template": "/Users/ada/Library/Application Support/app.concat.editor/templates/Intro",
  "location": "/edits",
  "name": "My intro",
  "fills": [
    { "mediaId": "m1", "file": "/footage/logo.png" },
    { "mediaId": "m2", "file": "/footage/take1.mp4" }
  ]
}

Reply: an EditorView of the new project.

Good to know:

  • Every slot must be filled. A set that leaves one empty makes nothing.
  • Every file is probed first, so a bad path refuses the whole request and leaves no folder behind.
  • Over a socket, location must lie under one of the server’s write roots, or the request is refused.

template.save

Packs an open project into a new template bundle in the library.

ParameterTypeMeaning
pathstringThe project folder
namestringThe template’s name

Reply: the new bundle’s TemplateInfo.


export.run

Renders the active timeline to a file, as a job. Exactly what the window’s Export sheet does: cutouts analysed, titles painted, then the frame loop and the mix.

ParameterTypeMeaning
pathstringThe project folder
outputstringThe file to write. The container follows the extension; .mp4 is the usual choice
crfintegeroptional. Constant rate factor; lower is better and bigger. Default: 20
presetstringoptional. x264 preset name, ultrafast … veryslow. Default: medium
widthintegeroptional. Default: the timeline’s
heightintegeroptional. Default: the timeline’s
rateNumintegeroptional. Frame rate numerator. Default: the timeline’s
rateDenintegeroptional. Frame rate denominator. Default: the timeline’s
codecstringoptional. h264, hevc or av1. Default: h264. Anything else is invalid
tenBitbooloptional. Ten bits a channel. Default: false
colorRangestringoptional. limited (16-235, what every player and YouTube expect) or full (0-255, for screen content bound for a PC player). The file is tagged and converted to match. Default: limited. Anything else is invalid
{
  "method": "export.run",
  "path": "/edits/Reel",
  "output": "/edits/reel.mp4",
  "crf": 18,
  "codec": "hevc"
}

Reply, a Started, at once:

{ "job": "j1", "path": "/edits/Reel", "output": "/edits/reel.mp4" }

Then events, until the job ends:

{"event":"cutout.progress","job":"j1","path":"/edits/Reel","mediaId":"m3","fetching":true,"fraction":0.4}
{"event":"export.progress","job":"j1","path":"/edits/Reel","frame":30,"total":150,"stage":"video"}
{"event":"export.progress","job":"j1","path":"/edits/Reel","frame":150,"total":150,"stage":"mux"}
{"event":"export.done","job":"j1","path":"/edits/Reel","output":"/edits/reel.mp4","width":1920,"height":1080}

or

{
  "event": "export.failed",
  "job": "j1",
  "path": "/edits/Reel",
  "error": { "code": "failed", "message": "…" }
}

Rules:

  • One export at a time. A second is refused with busy. From the window’s Remote page the slot is the window’s own, so an export begun in the Export sheet counts.
  • An empty timeline is refused.
  • Over a socket, output must lie under one of the server’s write roots, or the request is refused.
  • width and height are at most 8192 a side, the frame rate at most 240 a second, crf at most 63: anything larger is invalid.
  • cutout.progress only appears for clips with an automatic cutout whose masks are not cached yet. fetching is true while the model downloads.
  • Event shapes are in Types → Events. The job model is in the overview.

export.cancel

Stops a running export at its next frame.

ParameterTypeMeaning
jobstringThe job export.run named

Reply: {}. The job then ends with export.failed whose error.code is cancelled.

A job that is not running (finished, or never existed) is notFound.


preview.frame

Composites the true frame at one instant, titles and effects included, as a PNG.

ParameterTypeMeaning
pathstringThe project folder
timenumberThe timeline instant, in seconds
outputstringoptional. The file to write; folders above it are created. Absent: the picture comes back inline
widthintegeroptional. Frame width
heightintegeroptional. Frame height
{
  "method": "preview.frame",
  "path": "/edits/Reel",
  "time": 1.5,
  "output": "/edits/frames/1.5.png",
  "width": 640,
  "height": 360
}

Reply with output, a Written:

{ "path": "/edits/frames/1.5.png", "width": 640, "height": 360 }

Reply without, a Picture:

{ "width": 640, "height": 360, "png": "iVBORw0KGgo…" }

Rules:

  • width and height count only together. Give both or neither; neither means the timeline’s size.
  • Zero for either is invalid, and so is anything over 8192 a side.
  • Over a socket, output must lie under one of the server’s write roots, or the request is refused.
  • The PNG is RGBA, 8 bits a channel, base64 in the standard alphabet with padding.

Edit this page on GitHub