Video Project Endpoints

CRUD for video timelines, plus the render endpoint.

List projects on a board

GET /api/moodboards/{id}/video-projects

Returns an array of project summaries (id, name, last_modified, duration).

Create a project

POST /api/moodboards/{id}/video-projects
{
  "name": "Hero reel"
}

Returns the new project’s full state — empty timeline, default settings.

Get a project

GET /api/moodboards/{id}/video-projects/{pid}

Returns the project row with its full editor state in data (stored as an opaque JSON blob):

{
  "id": "…",
  "name": "…",
  "data": {
    "version": 3,
    "videoSize": { "w": 1920, "h": 1080 },
    "motionBlurEnabled": false,
    "motionBlurShutter": 180,
    "clips": [
      { "id": "…", "source": "REMOTE", "mediaType": "video", "url": "/media/…", "name": "…", "duration": 5 }
    ],
    "channels": [
      {
        "id": "…",
        "name": "Channel 1",
        "visible": true,
        "items": [
          {
            "id": "…",
            "clipId": "…",
            "trimStart": 0,
            "trimEnd": 5,
            "zoom": 1, "panX": 0, "panY": 0,
            "opacity": 100,
            "propertyKeyframes": {
              "scale": [ { "position": 0, "value": "1", "easing": "Smooth" }, { "position": 100, "value": "1.25", "easing": "Linear" } ]
            },
            "keyframeTransformOrigin": "center"
          }
        ]
      }
    ],
    "activeChannelId": "…",
    "currentTime": 0
  }
}

Keyframes are stored as per-property tracks: propertyKeyframes maps each property to an independent {position, value, easing} key list, plus an item-level keyframeTransformOrigin. See the Keyframe Builder doc and skills/greenlight-dash/references/video-projects.md for the full schema; the frontend’s sanitizeTimelineItem (frontend/src/components/videoEditor/VideoEditor.jsx) is canonical for the item fields. (Legacy projects may still carry a flat keyframes: [] array from the retired all-properties-per-key mode; it is no longer read.)

Update a project

PUT /api/moodboards/{id}/video-projects/{pid}
{ … full project state, replacing the current … }

The frontend sends the entire project state on each save. The backend stores it as a JSON blob.

Render

POST /api/moodboards/{id}/video-projects/{pid}/render
{
  "format": "mp4",
  "codec": "h264",
  "crf": 23,
  "size_preset": "1080p",
  "fps": 60
}

Starts the render job. Returns immediately with a job id:

{ "job_id": "…", "status": "queued" }

Poll status:

GET /api/moodboards/{id}/video-projects/{pid}/render/{job_id}

Returns:

{
  "status": "running" | "complete" | "error",
  "progress": 0.42,
  "eta_seconds": 30,
  "output_url": "/media/…"      // when complete
}

Delete a project

DELETE /api/moodboards/{id}/video-projects/{pid}

Where to go next

Camera preset endpoints

Saved camera moves are global JSON files under the media folder’s camera-presets/ (a separate directory from video-presets/, so names can’t collide).

GET    /api/camera-presets              → { "presets": [{ "id", "name", "description", "duration", "keyframes", "updated_at" }] }
POST   /api/camera-presets              { "name", "duration?", "keyframes", "base?" }
DELETE /api/camera-presets/{preset_id}

A preset’s keyframes are whole-frame snapshots at position 0–100 % of its own duration:

{ "position": 100, "easing": "AE Smooth", "properties": { "camZoom": "1.28" } }

The optional base object holds the preset’s un-keyframed camera settings (the depth-of-field rig), e.g. { "camDofEnabled": 1, "camAperture": 40 }. A preset needs either keyframes or base.

See Camera Layer for the property registry and skills/greenlight-dash/references/video-projects.md for how to apply one to a project.

Was this helpful?

0

Updated

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *