Skip to main content

Automation and FFmpeg

The commands API lets you define FFmpeg presets, queue conversions, inspect logs, stop running work, and optionally run post-conversion automation such as VMAF checks and conditional source deletion.

Command preset model

CommandPreset documents the conversion recipe saved in MongoDB.

FieldPurpose
nameHuman-readable preset name.
descriptionOptional description shown to users.
argument_templateFFmpeg argument template. Must contain both {input} and {output}.
output_suffixSuffix added before the output extension. Defaults to .converted.
output_extensionOutput file extension. Normalized to a real extension such as .mkv.
is_enabledEnables or disables the preset for execution.
check_vmaf_score_after_runningIf true, the backend runs post-conversion VMAF analysis.
delete_input_file_after_runningIf true, the backend attempts to delete the source file after success.
delete_input_only_if_vmaf_is_larger_thanOptional threshold from 0 to 100 for conditional source deletion.

Example preset

{
"name": "AV1 1080p",
"description": "Convert the source to AV1 and keep audio unchanged.",
"argument_template": "-hide_banner -y -i {input} -c:v av1_qsv -b:v 3M -c:a copy {output}",
"output_suffix": ".converted",
"output_extension": ".mkv",
"is_enabled": true,
"check_vmaf_score_after_running": true,
"delete_input_file_after_running": false,
"delete_input_only_if_vmaf_is_larger_than": null
}

Preset management endpoints

EndpointPurpose
GET /api/commandsList all presets.
POST /api/commandsCreate a preset.
PUT /api/commands/{id}Replace an existing preset.
DELETE /api/commands/{id}Remove a preset.

Validation rules worth knowing:

  • argument_template must include both {input} and {output}
  • presets with delete_input_only_if_vmaf_is_larger_than must keep the threshold between 0 and 100
  • a disabled preset cannot be run

Running a preset

POST /api/commands/{id}/run

{
"input_path": "D:\\Media\\Movies\\Movie.mkv"
}

The backend will:

  1. load the preset
  2. verify the input file exists
  3. build an output path from the preset suffix and extension
  4. prevent in-place conversion
  5. reserve the input and output files so conflicting jobs cannot run at the same time
  6. enqueue the job in the tracker

The response is 202 Accepted and includes the generated process_id, resolved output_path, and display-ready FFmpeg arguments.

Process lifecycle endpoints

EndpointPurpose
GET /api/commands/processesList queued, running, and finished jobs.
GET /api/commands/processes/{processId}Return one job with stdout and stderr logs.
POST /api/commands/processes/{processId}/killStop a running job or cancel a queued one. Optional delete_output=true removes the output file if possible.
DELETE /api/commands/processes/{processId}Remove a finished record. Running or queued records cannot be deleted.
POST /api/commands/processes/clear-completedBulk-remove completed entries.

Queue and persistence behavior

  • jobs are stored in MongoDB collection ffmpeg_jobs
  • queue state survives backend restarts
  • concurrency is capped by FFMPEG_MAX_PARALLEL_PROCESSES
  • file reservations prevent overlapping work on the same input or output path
  • logs are persisted and exposed through the details endpoint

Post-run automation

When either check_vmaf_score_after_running or delete_input_file_after_running is enabled, the backend starts a background post-run automation workflow after the conversion is accepted.

That workflow:

  1. waits for the conversion job to finish
  2. skips follow-up work if the conversion failed
  3. optionally runs a VMAF comparison between input and output
  4. optionally deletes the source file
  5. respects delete_input_only_if_vmaf_is_larger_than when a threshold is configured

This makes it possible to implement safer transcode pipelines where deletion only happens after a measured quality check.

Execution modes

Local mode

Set:

FFMPEG_EXECUTION_MODE=local

Use this when the backend host already has direct access to FFmpeg and the media library.

Docker mode

Set:

FFMPEG_EXECUTION_MODE=docker
FFMPEG_WORKER_PROFILE=cpu

Use this when you want worker containers for isolation or hardware-specific profiles.

Requirements:

  • mount the Docker socket into the backend container
  • make media paths visible to both the backend and worker containers
  • mount /dev/dri when using Intel or AMD profiles

Worker profiles

ProfileBehavior
cpuNo GPU-specific flags or device mounts.
intelPasses /dev/dri and is intended for Intel acceleration workflows.
amdPasses /dev/dri for AMD acceleration workflows.
nvidiaUses GPU flags and NVIDIA runtime environment variables.

Operational tips

  • Start with local mode unless you specifically need worker containers.
  • Keep media mounts consistent if the backend itself runs in Docker.
  • Poll the process details endpoint when you need logs for a job details page.
  • Use clear-completed or targeted delete to keep the process history manageable.