Files
video-shader-toys/docs/openapi.yaml
2026-05-12 22:04:46 +10:00

987 lines
28 KiB
YAML

openapi: 3.0.3
info:
title: Video Shader Toys Control API
version: 0.1.0
description: |
REST API exposed by the local Video Shader Toys control server.
The API is intended for local control tools and the bundled React UI. All mutating
endpoints return a small action result object.
RenderCadenceCompositor serves `/api/state` for snapshots and `/ws` for local
WebSocket state updates consumed by the bundled control UI.
servers:
- url: http://127.0.0.1:8080
description: Default local control server
tags:
- name: State
description: Runtime state and status.
- name: Static
description: Bundled control UI and static assets served by the local host.
- name: Docs
description: OpenAPI and Swagger UI documentation served by the local host.
- name: Layers
description: Layer stack control.
- name: Stack Presets
description: Save and recall layer stack presets.
- name: Runtime
description: Runtime actions.
paths:
/:
get:
tags: [Static]
summary: Serve the bundled control UI
description: Returns the built React control UI `index.html` from `ui/dist`.
operationId: getControlUiRoot
responses:
"200":
description: Control UI HTML.
content:
text/html:
schema:
type: string
"404":
description: UI bundle was not found.
content:
text/plain:
schema:
type: string
/index.html:
get:
tags: [Static]
summary: Serve the bundled control UI index file
description: Returns the built React control UI `index.html` from `ui/dist`.
operationId: getControlUiIndex
responses:
"200":
description: Control UI HTML.
content:
text/html:
schema:
type: string
"404":
description: UI bundle was not found.
content:
text/plain:
schema:
type: string
/assets/{assetPath}:
get:
tags: [Static]
summary: Serve a bundled control UI asset
description: Serves files from `ui/dist/assets`. The server rejects unsafe relative paths and guesses the content type from the file extension.
operationId: getControlUiAsset
parameters:
- name: assetPath
in: path
required: true
description: Relative asset path below `ui/dist/assets`.
schema:
type: string
responses:
"200":
description: Static asset.
content:
text/javascript:
schema:
type: string
text/css:
schema:
type: string
image/svg+xml:
schema:
type: string
image/png:
schema:
type: string
format: binary
text/plain:
schema:
type: string
"404":
description: Asset was not found or the path was unsafe.
content:
text/plain:
schema:
type: string
/docs:
get:
tags: [Docs]
summary: Serve Swagger UI
description: Returns a small Swagger UI page pointed at `/docs/openapi.yaml`.
operationId: getSwaggerUi
responses:
"200":
description: Swagger UI HTML.
content:
text/html:
schema:
type: string
/docs/:
get:
tags: [Docs]
summary: Serve Swagger UI
description: Alias for `/docs`.
operationId: getSwaggerUiWithTrailingSlash
responses:
"200":
description: Swagger UI HTML.
content:
text/html:
schema:
type: string
/docs/openapi.yaml:
get:
tags: [Docs]
summary: Serve the OpenAPI document
operationId: getOpenApiDocumentFromDocs
responses:
"200":
description: OpenAPI YAML document.
content:
application/yaml:
schema:
type: string
"404":
description: OpenAPI document was not found.
content:
text/plain:
schema:
type: string
/openapi.yaml:
get:
tags: [Docs]
summary: Serve the OpenAPI document
description: Alias for `/docs/openapi.yaml`.
operationId: getOpenApiDocument
responses:
"200":
description: OpenAPI YAML document.
content:
application/yaml:
schema:
type: string
"404":
description: OpenAPI document was not found.
content:
text/plain:
schema:
type: string
/api/state:
get:
tags: [State]
summary: Get current runtime state
operationId: getRuntimeState
responses:
"200":
description: Current runtime state.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeState"
/ws:
get:
tags: [State]
summary: Stream runtime state over WebSocket
description: |
Upgrades to a WebSocket connection. The server sends JSON runtime-state
snapshots using the same shape as `GET /api/state` whenever the serialized
state changes.
operationId: streamRuntimeState
responses:
"101":
description: WebSocket protocol upgrade accepted.
"400":
description: The request was not a valid WebSocket upgrade.
content:
text/plain:
schema:
type: string
/api/layers/add:
post:
tags: [Layers]
summary: Add a layer using a shader package
operationId: addLayer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AddLayerRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/remove:
post:
tags: [Layers]
summary: Remove a layer
operationId: removeLayer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/LayerIdRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/move:
post:
tags: [Layers]
summary: Move a layer by direction
description: Moves a layer up or down by one or more positions, depending on the signed direction value.
operationId: moveLayer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/MoveLayerRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/reorder:
post:
tags: [Layers]
summary: Move a layer to an absolute index
operationId: reorderLayer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ReorderLayerRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/set-bypass:
post:
tags: [Layers]
summary: Set layer bypass state
operationId: setLayerBypass
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SetBypassRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/set-shader:
post:
tags: [Layers]
summary: Change the shader package used by a layer
operationId: setLayerShader
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SetShaderRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/update-parameter:
post:
tags: [Layers]
summary: Update a layer parameter value
operationId: updateLayerParameter
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateParameterRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/layers/reset-parameters:
post:
tags: [Layers]
summary: Reset a layer's parameters to shader defaults
operationId: resetLayerParameters
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/LayerIdRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/stack-presets/save:
post:
tags: [Stack Presets]
summary: Save the current layer stack as a preset
operationId: saveStackPreset
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PresetNameRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/stack-presets/load:
post:
tags: [Stack Presets]
summary: Load a layer stack preset
operationId: loadStackPreset
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PresetNameRequest"
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/reload:
post:
tags: [Runtime]
summary: Reload shaders
description: Rescans the shader library, re-reads manifests, queues shader compilation, and refreshes shader availability/errors. If a changed shader fails, the previous working stack remains active where possible.
operationId: reloadShaders
requestBody:
required: false
content:
application/json:
schema:
type: object
additionalProperties: false
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
/api/screenshot:
post:
tags: [Runtime]
summary: Queue a PNG screenshot of the final output render target
description: Captures the next completed output render target and writes it under `runtime/screenshots/`.
operationId: queueScreenshot
requestBody:
required: false
content:
application/json:
schema:
type: object
additionalProperties: false
responses:
"200":
$ref: "#/components/responses/ActionOk"
"400":
$ref: "#/components/responses/ActionError"
components:
responses:
ActionOk:
description: Action succeeded.
content:
application/json:
schema:
$ref: "#/components/schemas/ActionResponse"
example:
ok: true
ActionError:
description: Action failed or request JSON was invalid.
content:
application/json:
schema:
$ref: "#/components/schemas/ActionResponse"
example:
ok: false
error: Unknown layer id.
schemas:
ActionResponse:
type: object
required: [ok]
properties:
ok:
type: boolean
error:
type: string
description: Present when the request fails or when the runtime returns a diagnostic.
additionalProperties: false
AddLayerRequest:
type: object
required: [shaderId]
properties:
shaderId:
type: string
example: studio-color
additionalProperties: false
LayerIdRequest:
type: object
required: [layerId]
properties:
layerId:
type: string
example: layer-1
additionalProperties: false
MoveLayerRequest:
type: object
required: [layerId, direction]
properties:
layerId:
type: string
direction:
type: integer
description: Signed movement direction. Negative moves toward the top of the stack; positive moves toward the bottom.
example: -1
additionalProperties: false
ReorderLayerRequest:
type: object
required: [layerId, targetIndex]
properties:
layerId:
type: string
targetIndex:
type: integer
minimum: 0
example: 0
additionalProperties: false
SetBypassRequest:
type: object
required: [layerId, bypass]
properties:
layerId:
type: string
bypass:
type: boolean
additionalProperties: false
SetShaderRequest:
type: object
required: [layerId, shaderId]
properties:
layerId:
type: string
shaderId:
type: string
example: vhs
additionalProperties: false
UpdateParameterRequest:
type: object
required: [layerId, parameterId, value]
properties:
layerId:
type: string
parameterId:
type: string
example: brightness
value:
description: Parameter value. Type depends on the shader parameter definition.
oneOf:
- type: number
- type: boolean
- type: string
- type: array
items:
type: number
example: 1.25
additionalProperties: false
PresetNameRequest:
type: object
required: [presetName]
properties:
presetName:
type: string
example: live-show-look
additionalProperties: false
RuntimeState:
type: object
properties:
app:
$ref: "#/components/schemas/AppState"
runtime:
$ref: "#/components/schemas/RuntimeStatus"
video:
$ref: "#/components/schemas/VideoStatus"
decklink:
$ref: "#/components/schemas/DeckLinkStatus"
videoIO:
$ref: "#/components/schemas/VideoIOStatus"
performance:
$ref: "#/components/schemas/PerformanceStatus"
backendPlayout:
$ref: "#/components/schemas/BackendPlayoutStatus"
runtimeEvents:
$ref: "#/components/schemas/RuntimeEventStatus"
shaders:
type: array
items:
$ref: "#/components/schemas/ShaderSummary"
stackPresets:
type: array
items:
type: string
layers:
type: array
items:
$ref: "#/components/schemas/LayerState"
AppState:
type: object
properties:
serverPort:
type: number
oscPort:
type: number
oscBindAddress:
type: string
oscSmoothing:
type: number
autoReload:
type: boolean
maxTemporalHistoryFrames:
type: number
previewFps:
type: number
startupSettleMs:
type: number
enableExternalKeying:
type: boolean
inputVideoFormat:
type: string
inputFrameRate:
type: string
outputVideoFormat:
type: string
outputFrameRate:
type: string
RuntimeStatus:
type: object
properties:
layerCount:
type: number
compileSucceeded:
type: boolean
compileMessage:
type: string
VideoStatus:
type: object
properties:
hasSignal:
type: boolean
width:
type: number
height:
type: number
modeName:
type: string
DeckLinkStatus:
type: object
deprecated: true
description: Legacy DeckLink-specific status object. Prefer `videoIO` for new clients.
properties:
modelName:
type: string
supportsInternalKeying:
type: boolean
supportsExternalKeying:
type: boolean
keyerInterfaceAvailable:
type: boolean
externalKeyingRequested:
type: boolean
externalKeyingActive:
type: boolean
statusMessage:
type: string
VideoIOStatus:
type: object
properties:
backend:
type: string
example: decklink
modelName:
type: string
supportsInternalKeying:
type: boolean
supportsExternalKeying:
type: boolean
keyerInterfaceAvailable:
type: boolean
externalKeyingRequested:
type: boolean
externalKeyingActive:
type: boolean
statusMessage:
type: string
PerformanceStatus:
type: object
properties:
frameBudgetMs:
type: number
renderMs:
type: number
smoothedRenderMs:
type: number
budgetUsedPercent:
type: number
completionIntervalMs:
type: number
smoothedCompletionIntervalMs:
type: number
maxCompletionIntervalMs:
type: number
lateFrameCount:
type: number
droppedFrameCount:
type: number
flushedFrameCount:
type: number
cadence:
$ref: "#/components/schemas/CadenceTelemetry"
CadenceTelemetry:
type: object
properties:
clockOverruns:
type: number
description: Render cadence overruns where the render thread was late enough to skip one or more frame intervals.
clockSkippedFrames:
type: number
description: Total render cadence frame intervals skipped instead of catch-up rendering.
clockOveruns:
type: number
deprecated: true
description: Deprecated misspelled alias for clockOverruns.
clockSkipped:
type: number
deprecated: true
description: Deprecated alias for clockSkippedFrames.
inputFramesReceived:
type: number
inputFramesDropped:
type: number
inputConsumeMisses:
type: number
description: Render ticks where no ready input frame was available to upload.
inputUploadMisses:
type: number
description: Input texture upload attempts that reused the previous GL input texture.
inputReadyFrames:
type: number
description: Ready input frames currently queued in the input mailbox.
inputReadingFrames:
type: number
description: Input frames currently protected while render uploads them.
inputLatestAgeMs:
type: number
inputUploadMs:
type: number
inputCaptureFps:
type: number
inputConvertMs:
type: number
inputSubmitMs:
type: number
inputCaptureFormat:
type: string
BackendPlayoutStatus:
type: object
properties:
lifecycleState:
type: string
example: running
degraded:
type: boolean
statusMessage:
type: string
lateFrameCount:
type: number
droppedFrameCount:
type: number
flushedFrameCount:
type: number
readyQueue:
$ref: "#/components/schemas/BackendReadyQueueStatus"
outputRender:
$ref: "#/components/schemas/BackendOutputRenderStatus"
recovery:
$ref: "#/components/schemas/BackendPlayoutRecoveryStatus"
BackendReadyQueueStatus:
type: object
properties:
depth:
type: number
description: Current number of ready output frames.
capacity:
type: number
description: Maximum ready output frames currently allowed.
minDepth:
type: number
description: Minimum observed ready queue depth since backend worker start.
maxDepth:
type: number
description: Maximum observed ready queue depth since backend worker start.
zeroDepthCount:
type: number
description: Number of observed samples where the ready queue was empty.
pushedCount:
type: number
poppedCount:
type: number
droppedCount:
type: number
underrunCount:
type: number
BackendOutputRenderStatus:
type: object
properties:
renderMs:
type: number
description: Most recent output render duration in milliseconds.
smoothedRenderMs:
type: number
description: Smoothed output render duration in milliseconds.
maxRenderMs:
type: number
description: Maximum observed output render duration in milliseconds.
acquireFrameMs:
type: number
description: Time spent acquiring a writable backend output frame in milliseconds.
renderRequestMs:
type: number
description: Time spent executing the render-thread output frame request in milliseconds.
endAccessMs:
type: number
description: Time spent ending write access to the backend output frame in milliseconds.
queueWaitMs:
type: number
description: Time the output render request spent waiting for the render thread in milliseconds.
drawMs:
type: number
description: Time spent drawing, blitting, packing, and flushing the output frame in milliseconds.
fenceWaitMs:
type: number
description: Time spent waiting for the async readback fence in milliseconds.
mapMs:
type: number
description: Time spent mapping the async readback pixel buffer in milliseconds.
readbackCopyMs:
type: number
description: Time spent copying async readback bytes into the backend output frame in milliseconds.
cachedCopyMs:
type: number
description: Time spent copying the cached output frame when async readback is not ready in milliseconds.
asyncQueueMs:
type: number
description: Time spent queueing the next async readback in milliseconds.
asyncQueueBufferMs:
type: number
description: Time spent orphaning or allocating the async readback pixel buffer in milliseconds.
asyncQueueSetupMs:
type: number
description: Time spent applying readback pixel-store, framebuffer, and pixel-pack-buffer state in milliseconds.
asyncQueueReadPixelsMs:
type: number
description: Time spent issuing glReadPixels for the async readback in milliseconds.
asyncQueueFenceMs:
type: number
description: Time spent creating the async readback fence in milliseconds.
syncReadMs:
type: number
description: Time spent in bootstrap synchronous readback in milliseconds.
asyncReadbackMissCount:
type: number
description: Count of output render requests where async readback was not ready.
cachedFallbackCount:
type: number
description: Count of output render requests served from the cached output frame.
syncFallbackCount:
type: number
description: Count of output render requests that used bootstrap synchronous readback.
BackendPlayoutRecoveryStatus:
type: object
properties:
completionResult:
type: string
enum: [Completed, DisplayedLate, Dropped, Flushed, Unknown]
completedFrameIndex:
type: number
scheduledFrameIndex:
type: number
scheduledLeadFrames:
type: number
measuredLagFrames:
type: number
catchUpFrames:
type: number
lateStreak:
type: number
dropStreak:
type: number
RuntimeEventStatus:
type: object
properties:
queue:
$ref: "#/components/schemas/RuntimeEventQueueStatus"
dispatch:
$ref: "#/components/schemas/RuntimeEventDispatchStatus"
RuntimeEventQueueStatus:
type: object
properties:
name:
type: string
depth:
type: number
capacity:
type: number
droppedCount:
type: number
oldestEventAgeMs:
type: number
RuntimeEventDispatchStatus:
type: object
properties:
dispatchCallCount:
type: number
dispatchedEventCount:
type: number
handlerInvocationCount:
type: number
handlerFailureCount:
type: number
lastDispatchDurationMs:
type: number
maxDispatchDurationMs:
type: number
ShaderSummary:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
category:
type: string
available:
type: boolean
description: False when the shader package exists but failed manifest or compile validation.
error:
type: string
description: Error text for unavailable shader packages.
temporal:
$ref: "#/components/schemas/TemporalState"
feedback:
$ref: "#/components/schemas/FeedbackState"
TemporalState:
type: object
properties:
enabled:
type: boolean
historySource:
type: string
enum: [source, preLayerInput, none]
requestedHistoryLength:
type: number
effectiveHistoryLength:
type: number
FeedbackState:
type: object
properties:
enabled:
type: boolean
writePass:
type: string
LayerState:
type: object
properties:
id:
type: string
shaderId:
type: string
shaderName:
type: string
bypass:
type: boolean
temporal:
$ref: "#/components/schemas/TemporalState"
parameters:
type: array
items:
$ref: "#/components/schemas/ParameterState"
ParameterState:
type: object
properties:
id:
type: string
label:
type: string
description:
type: string
description: Short helper text shown under the parameter label in the control UI.
type:
type: string
enum: [float, vec2, color, bool, enum, text, trigger]
defaultValue:
description: Default parameter value from the shader manifest.
oneOf:
- type: number
- type: boolean
- type: string
- type: array
items:
type: number
min:
type: array
items:
type: number
max:
type: array
items:
type: number
step:
type: array
items:
type: number
options:
type: array
items:
$ref: "#/components/schemas/ParameterOption"
maxLength:
type: number
description: Maximum length for text parameters.
font:
type: string
description: Font asset id used by text parameters, when declared.
value:
description: Current parameter value.
oneOf:
- type: number
- type: boolean
- type: string
- type: array
items:
type: number
ParameterOption:
type: object
properties:
value:
type: string
label:
type: string