Where you are: docs → reference → api → format-encoder Read this first: api.md See also: subsystems/codec.md · deployment.md · subsystems/switcher.md
TL;DR Two tiny REST surfaces cover the overall pipeline format (resolution and fps) and the live video encoder choice. Format is a shared invariant — changing it rebuilds decoders/encoders across the whole pipeline — so it's blocked while a transition is in flight. Encoder selection is hot-swappable across the detected backends (x264, NVENC, VideoToolbox, VA-API, OpenH264).
Purpose: return the current pipeline format and the list of supported presets.
Auth: required.
Handler: control/api_format.go → (*API).handleGetFormat.
Request body: none.
Response 200 (control.formatResponse):
{
"format": { "width": 1920, "height": 1080, "fpsNum": 60, "fpsDen": 1, "name": "1080p60" },
"presets": ["1080p25", "1080p29.97", "1080p50", "1080p59.94", "1080p60", "720p50", "720p60"]
}Errors: none.
Emits: nothing.
Related: subsystems/switcher.md
Purpose: change the pipeline format to a named preset, or to a fully-specified width/height/fpsNum/fpsDen tuple.
Auth: required.
Handler: control/api_format.go → (*API).handleSetFormatInner (wrapped by timedHandler).
Request body (control.formatRequest):
{ "format": "1080p59.94" }or
{ "width": 1920, "height": 1080, "fpsNum": 60000, "fpsDen": 1001 }| Field | Type | Required | Description |
|---|---|---|---|
format |
string | either this or width/height/fpsNum/fpsDen | preset name from switcher.FormatPresets |
width |
int | see above | horizontal pixels |
height |
int | see above | vertical pixels |
fpsNum |
int | see above | frame rate numerator |
fpsDen |
int | see above | frame rate denominator (default 1) |
Response 200: full ControlRoomState with updated PipelineFormat.
Errors:
| Code | When |
|---|---|
| 400 | invalid JSON, unknown preset, invalid dimensions |
| 409 | switcher.ErrFormatDuringTransition — a transition or FTB is active |
Emits: state broadcast with updated PipelineFormat. The switcher rebuilds its encoder pool, preview streams, and pipeline codecs internally — this is an expensive operation (tens of ms) so avoid toggling mid-show.
Related: subsystems/switcher.md · deployment.md
Purpose: return the active video encoder and the list of detected alternatives.
Auth: required.
Handler: control/api_encoder.go → (*API).handleGetEncoder.
Request body: none.
Response 200 (control.encoderResponse):
{
"current": "videotoolbox",
"available": [
{ "name": "x264", "displayName": "x264 (software)", "isDefault": false },
{ "name": "videotoolbox", "displayName": "Apple VideoToolbox (HW)", "isDefault": true }
]
}EncoderInfo is defined in codec.EncoderInfo. Availability is determined at startup by codec.ProbeEncoders — detection is platform-specific.
Errors: none.
Emits: nothing.
Related: subsystems/codec.md · deployment.md
Purpose: switch the live video encoder backend without restarting the server.
Auth: required.
Handler: control/api_encoder.go → (*API).handleSetEncoderInner (wrapped by timedHandler).
Request body (control.encoderRequest):
{ "encoder": "nvenc" }| Field | Type | Required | Description |
|---|---|---|---|
encoder |
string | yes | name from available[].name |
Response 200: full ControlRoomState with updated Encoder.Current.
Errors:
| Code | When |
|---|---|
| 400 | invalid JSON, empty name, or switcher.ErrEncoderNotAvailable |
Emits: state broadcast with updated Encoder. The new encoder kicks in on the next frame; currently-transcoding work uses the previous encoder until it drains.
Related: subsystems/codec.md
- Concepts: gpu.md · pipeline.md
- Reference: api.md · state-broadcast.md
- Subsystems: codec.md · switcher.md
- Operations: deployment.md