Media

GET /api/media/videofileinput/play

Requires: control (operator+)

Loads a media file into a Video File Input and starts playback.

Parameters:

Parameter Required Description
videofileinput Yes Name of the Video File Input component
sourceuri Yes File path (absolute or relative) to the media file

Behavior:

  • If the player is Playing or Paused, it stops first, then loads and plays the new file
  • If Stopped or NoMedia, it loads and plays immediately
  • If Parsing, returns an error

Response:

  • 200 OK — OK - Request forwarded to Composer. Resolved file path: {path}
  • 400 Bad Request — Missing parameters
  • 404 Not Found — Input or file not found

GET /api/cavjumptocuepoint

Requires: control (operator+)

Jumps a CAV Player to a specific cue point.

Selecting the target object (exactly one of these is required):

Parameter Description
target Object GUID
targetname Object name (must be unique)
targettype Object type name (must be unique)

Additional parameters:

Parameter Required Description
cuepointid Yes Cue point identifier string

Example:

/api/cavjumptocuepoint?targetname=CAV Player 1&cuepointid=chapter1

Response:

  • 200 OK — JumpToCuePoint {id} on {name} performed successfully!
  • 400 Bad Request — Missing parameters, target not a CAV player, cue point not found, or jump not allowed

GET /api/cavgetcuepoints

Requires: read (viewer+)

Returns all cue points from a CAV Player as JSON.

Selecting the target object (exactly one of these is required):

Parameter Description
target Object GUID
targetname Object name (must be unique)
targettype Object type name (must be unique)

Example:

/api/cavgetcuepoints?targetname=CAV Player 1

Response:

  • 200 OK — JSON:
{
  "Target": "CavPlayerInput1",
  "Count": 3,
  "CuePoints": [
    { "Id": "intro", "Frame": 0 },
    { "Id": "chapter1", "Frame": 150 },
    { "Id": "outro", "Frame": 900 }
  ]
}
  • 400 Bad Request — Missing parameters, target not a CAV player, or no source loaded

GET /api/facedetect/getimage

Requires: read (viewer+)

Returns the best face detection result as a JPEG image.

Parameters:

Parameter Required Description
target Yes Face detector component GUID

Response:

  • 200 OK — JPEG image data (Content-Type: image/jpeg)
  • 200 OK — Error message if detector not found (text)

GET /api/image/get

Requires: read (viewer+)

Returns a single snapshot of a rendered image source — either a Scene or an AbstractInput (any input that has produced a RenderedCudaBgraImage). JPEG by default; format=png returns the frame losslessly.

Reach for PNG whenever the pixels have to be exact. JPEG at quality 100 still differs from the render by more than a reference-image comparison tolerates (~0.68% against a 0.5% gate), so a JPEG snapshot cannot serve as a golden and cannot be measured against absolute thresholds. PNG can, and it keeps the alpha channel that the JPEG path discards. The cost is size: roughly 1–3 MB for a 1920×720 frame against ~100 KB. JPEG stays the default because that is what the streaming consumers want.

Selecting the source (provide at most one — selectors are checked in this priority order):

Parameter Description
target NamedModel GUID — matches a Scene or an AbstractInput
targetname NamedModel name — matches a Scene or an AbstractInput
scene Scene name (legacy; selects a Scene only)

If no selector is supplied, the topmost scene is used (falling back to active scene, then first scene in the project).

A selector that names something which does not exist replies 204. A malformed target is the exception: the GUID branch is gated on a successful parse, so an unparseable value is not treated as "no such source" but falls through every selector to the topmost-scene default and returns a picture of it. Long-standing behaviour, recorded here because it is easy to be caught by — a client with a corrupted id gets a valid image of the wrong source, which is harder to notice than an error. Pinned by 2250-api-image-get-contract, so tightening it later is a deliberate change rather than a silent one.

Additional parameters:

Parameter Required Description
format No jpeg (default) or png. PNG is lossless and preserves alpha. Any other value is refused.
quality No JPEG quality 1–100 (default: 75). Ignored when format=png.
width No Output width in pixels. 0 = original.
height No Output height in pixels. 0 = original (aspect preserved when only one dimension is set).

Response:

  • 200 OK — image data; Content-Type: image/jpeg, or image/png when format=png
  • 204 No Content — Source resolved but no image has been rendered yet (e.g. an input that hasn't produced its first frame)
  • 400 Bad Request — format was neither jpeg nor png. Deliberately not a fallback to JPEG: a caller that asked for exact pixels and silently received lossy ones would compare them against a reference and blame the renderer.
  • 503 Service Unavailable — the compression queue is full. Retry; this is not an error in the frame or the request.

Why a 503 exists at all. The frame is captured on the render thread — it has to be, or you would not get the frame that was live when you asked — but the compression and the response write happen on a small pool of worker threads. At 1080p an encode costs roughly 27 ms as JPEG and 157 ms as PNG against a 33 ms frame budget at 29.97 fps, so doing it inline charged every caller's snapshot to the whole composition.

The queue behind that pool is deliberately shallow (4 slots, 1 worker) and refuses rather than grows: each waiting job pins a full uncompressed frame (~8 MB at 1080p), and a snapshot served from the back of a long queue is a stale snapshot. A slot is reserved before the capture, so a refused request costs no device-to-host copy at all.

One worker rather than several is measured, not arbitrary. Three encode threads running alongside the render loop made it congest — an autotest whose picture was correct went from 0 processing-queue flushes to 34, and from 29.97 fps to about 7 — so concurrency in the encoder was traded away for a render loop that stays at rate. The practical consequence is that concurrent callers serialise: a burst of 16 measures 6 × 200 + 10 × 503 rather than 7 × 200 + 9 × 503. Sequential callers are unaffected either way.

A sequential caller never has more than one job outstanding and so cannot hit this — the refusal is for concurrent pullers. It is 503 and not 204 on purpose: 204 means "nothing has rendered", and conflating the two would let a golden-image test quietly compare against a stale file instead of retrying. ComposerTestSdk's CaptureFrameAsync retries a 503 twice at 250 ms for exactly this reason.


GET /api/image/stream

Requires: read (viewer+)

Opens a long-lived MJPEG (multipart/x-mixed-replace) stream of a rendered image source. Each connection spawns its own worker thread so the VideoWorker is never blocked by the streaming loop, and each connection gets its own JPEG compressor to avoid cross-connection contention. The connection stays open until the client disconnects or the server shuts down. The source is re-resolved on every tick, so renaming or replacing the underlying NamedModel takes effect on the next frame without restarting the stream.

Selecting the source (same selectors as /api/image/get):

Parameter Description
target NamedModel GUID — Scene or AbstractInput
targetname NamedModel name — Scene or AbstractInput
scene Scene name (legacy; default: topmost scene)

Additional parameters:

Parameter Required Description
quality No JPEG quality 1–100 (default: 75).
width No Output width in pixels. 0 = original.
height No Output height in pixels. 0 = original (aspect preserved when only one dimension is set).
fps No Target frames per second 1–30 (default: 5).

Response: 200 OK — Content-Type: multipart/x-mixed-replace; boundary=frame with JPEG frames at the requested cadence. Frames are skipped silently when the source isn't currently rendering, and the stream resumes as soon as it is.


GET /api/image/preview

Requires: read (viewer+)

Serves an HTML page with an embedded MJPEG viewer, scene selector, quality/size/FPS controls, and a collapsible performance sidebar. Styled to match the Composer Desktop dark theme.

Response: 200 OK — text/html