DocsRaw ffmpeg
Command rules
The supported ffmpeg command syntax, and the options, formats, codecs and filters a command can use.
To submit an existing ffmpeg command, send its arguments in command to POST /v1/jobs, without
ffmpeg itself, and name the input and output files with aliases in input_files and
output_files. This page lists the supported syntax, options, codecs, formats and filters. A JSON
request (Operations) compiles to a command within the same set.
Supported command syntax#
- Files by alias. Name every input and output file as
{{in_...}}or{{out_...}}. Paths, URLs and protocols written incommandare not supported. - One ffmpeg run.
commandholds ffmpeg's arguments only. Shell features are not supported:$HOME, backticks,~and globs stay plain text. - The listed options. Options, formats, codecs and filters that are not listed on this page are not supported, even when ffmpeg has them.
Aliases#
input_files maps input aliases to URLs and output_files maps output aliases to file names:
{
"input_files": { "in_video": "https://example.com/talk.mp4", "in_logo": "https://example.com/logo.png" },
"output_files": { "out_main": "talk-720p.mp4" },
"command": "-i {{in_video}} -i {{in_logo}} -filter_complex \"[0:v][1:v]overlay=10:10\" -c:a copy {{out_main}}"
}Copy failed. The text is selected; copy it with your keyboard.
- An alias is
in_orout_and 1 to 48 letters, digits or underscores. Each map holds 1 to 16 files. - Every alias appears in the command as a whole argument: an input alias right after
-i, an output alias where an output path goes. An output alias appears once. An input alias may follow-iseveral times (up to 16), each with its own options such as-ss, to read different parts of one file; the file is fetched and counted once. - Inputs come before outputs. Options before an input apply to that input; options before an output apply to that output, as in ffmpeg.
- An output file name is one plain name with one supported extension, such as
clip.mp4: up to 100 letters, digits, underscores or hyphens before the extension, starting with a letter or digit. No folders, no patterns like%03d. - Inputs are
httporhttpsURLs up to 4,096 characters, or completed private uploads named byvidexo://uploads/<id>(Files).
Syntax#
- One line of printable ASCII, at most 65,536 characters and
1,024 arguments. The one exception is the text of
drawtext(below), which may hold letters, marks, numbers, punctuation, symbols and spaces of any script, inside quotes. - Single quotes, double quotes and backslash escapes work as in a shell. Quote filter graphs that
contain
;,,or spaces. |,&,;,<and>are supported inside quotes only, as part of a filter graph or a value.- Leave out
-y,-nostdinand-hide_banner: they are not supported incommand.
Options#
Each option is supported where ffmpeg would read it: as a global option, for an input, or for an
output. Options marked with a stream suffix also take :v, :a, :v:0, :a:0 or :0, such as
-c:v or -b:a. Values are checked too: codecs, presets and pixel formats from the lists below,
numbers within ranges, times as seconds or HH:MM:SS.ms. Three values need a partner in the same
output: -b:v 0 needs -c:v libvpx-vp9 or libaom-av1 and a -crf; -tag:v hvc1 needs
-c:v libx265 in an MP4 or MOV file; -cpu-used (4 to 8) needs -c:v libaom-av1. With any of
them, give the video codec once, as -c:v or -codec:v, and no other codec option that could
reach the video (such as -c or -c:v:0).
| Option | Where | Stream suffix |
|---|---|---|
-loglevel | global | no |
-v | global | no |
-filter_complex | global | no |
-filter_complex_threads | global | no |
-filter_threads | global | no |
-f | input or output | no |
-ss | input or output | no |
-t | input or output | no |
-to | input or output | no |
-itsoffset | input | no |
-skip_frame | input | no |
-stream_loop | input | no |
-r | input or output | yes (:v, :a, :v:0, :a:0, :0) |
-s | input or output | yes (:v, :a, :v:0, :a:0, :0) |
-pix_fmt | input or output | yes (:v, :a, :v:0, :a:0, :0) |
-ar | input or output | yes (:v, :a, :v:0, :a:0, :0) |
-ac | input or output | yes (:v, :a, :v:0, :a:0, :0) |
-threads | input or output | yes (:v, :a, :v:0, :a:0, :0) |
-c | output | yes (:v, :a, :v:0, :a:0, :0) |
-codec | output | yes (:v, :a, :v:0, :a:0, :0) |
-b | output | yes (:v, :a, :v:0, :a:0, :0) |
-maxrate | output | yes (:v, :a, :v:0, :a:0, :0) |
-minrate | output | yes (:v, :a, :v:0, :a:0, :0) |
-bufsize | output | yes (:v, :a, :v:0, :a:0, :0) |
-crf | output | yes (:v, :a, :v:0, :a:0, :0) |
-q | output | yes (:v, :a, :v:0, :a:0, :0) |
-qscale | output | yes (:v, :a, :v:0, :a:0, :0) |
-preset | output | yes (:v, :a, :v:0, :a:0, :0) |
-tune | output | yes (:v, :a, :v:0, :a:0, :0) |
-profile | output | yes (:v, :a, :v:0, :a:0, :0) |
-level | output | yes (:v, :a, :v:0, :a:0, :0) |
-g | output | yes (:v, :a, :v:0, :a:0, :0) |
-keyint_min | output | yes (:v, :a, :v:0, :a:0, :0) |
-bf | output | yes (:v, :a, :v:0, :a:0, :0) |
-tag | output | yes (:v, :a, :v:0, :a:0, :0) |
-cpu-used | output | yes (:v, :a, :v:0, :a:0, :0) |
-frames | output | yes (:v, :a, :v:0, :a:0, :0) |
-vframes | output | no |
-aframes | output | no |
-map | output | no |
-map_metadata | output | no |
-map_chapters | output | no |
-metadata | output | no |
-movflags | output | no |
-fps_mode | output | yes (:v, :a, :v:0, :a:0, :0) |
-vn | input or output | no |
-an | input or output | no |
-sn | input or output | no |
-dn | input or output | no |
-shortest | output | no |
-vf | output | no |
-af | output | no |
-filter | output | yes (:v, :a, :v:0, :a:0, :0) |
Any other option is not supported.
Formats#
Supported input formats (ffmpeg demuxers):
mov, matroska, webm, avi, mpegts, mp3, aac, wav, flac, ogg, gif, png_pipe, jpeg_pipe, webp_pipe, bmp_pipe, rawvideo, s16le
Two generated inputs are allowed, each written in exactly this order. Silence:
-f lavfi -i anullsrc=r=48000:cl=stereo:d=4, with a rate from 8,000 to 192,000, and mono or stereo.
A solid colour: -f lavfi -i color=c=0x101828:s=1920x1080:r=30:d=3, with the colour in hex and a rate
from 1 to 120. Each takes a length from 0.1 to 300 seconds. It is not a file, so it has no alias, and
no other option may go with it. Every other lavfi source is refused, and a command still needs one
input file.
An output's format follows its file extension. -f, when you give it, names the same muxer:
| Extension | Muxer |
|---|---|
.mp4 | mp4 |
.mov | mov |
.m4a | ipod |
.mkv | matroska |
.webm | webm |
.ts | mpegts |
.mp3 | mp3 |
.aac | adts |
.wav | wav |
.flac | flac |
.ogg | ogg |
.opus | opus |
.gif | gif |
.png | image2pipe |
.jpg | image2pipe |
.jpeg | image2pipe |
.json | null |
.json writes no media: it is a scene list, and ffmpeg's null muxer gets the frames.
Codecs and encoder settings#
Codecs for -c, -codec and their stream forms such as -c:v:
copy, libx264, libx265, libvpx, libvpx-vp9, libaom-av1, mpeg4, mjpeg, png, gif, ffv1, aac, libmp3lame, libopus, libvorbis, flac, pcm_s16le, pcm_s24le, pcm_f32le, alac
Presets for -preset, with -c:v libx264 or libx265:
ultrafast, superfast, veryfast, faster, fast, medium, slow
The slower presets, slower, veryslow and placebo, are refused with command_invalid
(option_value): they take several times as long for a few percent smaller files. Without
-preset, x264 and x265 run medium; JSON jobs run veryfast unless they name a preset.
Pixel formats for -pix_fmt and the format filter:
yuv420p, yuv422p, yuv444p, yuv420p10le, yuv422p10le, yuv444p10le, yuva420p, rgb24, rgba, bgra, gray, pal8, nv12
Filters#
Filter graphs in -vf, -af, -filter and -filter_complex support these filters and their
documented ffmpeg options:
acrossfade, afade, aformat, amix, apad, aresample, asetpts, asplit, atempo, atrim, boxblur, colorchannelmixer, concat, crop, drawtext, eq, fade, format, fps, hflip, hue, loudnorm, overlay, pad, palettegen, paletteuse, rotate, scale, scale2ref, scdet, select, setdar, setpts, setsar, showspectrum, showwaves, split, subtitles, thumbnail, tile, tpad, transpose, trim, unsharp, vflip, volume, xfade, zoompan
A command uses at most 128 filters in all. Literal sizes, such as scale=1920:1080
or -s, are at most 16,384 on a side and 33,554,432 pixels in all.
drawtext draws literal text: it needs expansion=none (no %{...} functions), text (1 to 500
characters) and a fontfile from the list below (Fonts has their scripts and
licences), and takes fontsize (1 to 1,000), fontcolor, alpha, x, y, y_align, box,
boxcolor, boxborderw (one to four widths, top|right|bottom|left), borderw, bordercolor, shadowx, shadowy, shadowcolor and
enable, each once and by name. textfile, font and the timecode options are not supported.
Escape : and ' in the text for the option (\:) and ,, ;, [, ] for the graph, as ffmpeg
reads them, or write the job as JSON, whose text layers escape it for you.
xfade crosses two links of equal size, rate and pixel format: every option named,
xfade=transition=fade:duration=1:offset=4, with one of the fixed transition names and no custom
or expr. acrossfade crosses two sounds: acrossfade=d=1:c1=tri:c2=tri, without ns or o.
subtitles draws captions from a subtitle file given as an input alias:
subtitles=filename={{in_captions}}, with in_captions in input_files and read by nothing else
(no -i, no second subtitles). It also takes fontsdir=/opt/videxo/fonts, charenc=UTF-8 and
force_style, a quoted comma list of FontName (a family from Fonts, such as
Open Sans), FontSize (1 to 200), PrimaryColour, OutlineColour and BackColour
(&HAABBGGRR), Bold (0 or -1), BorderStyle (1 or 3), Outline and Shadow (0 to 20),
Alignment (1 to 9: 2 is bottom centre, 6 top centre) and MarginL, MarginR, MarginV (0 to
2,000), each once; sizes are on a 288-line script that libass scales to the video. The file is an
SRT or WebVTT in UTF-8 of at most 1 MB; its tags and styles are removed before ffmpeg reads it.
-i {{in_video}} -vf "subtitles=filename={{in_captions}}:fontsdir=/opt/videxo/fonts:charenc=UTF-8:force_style='FontName=Inter,FontSize=12.8,Outline=0.5,MarginV=13'" {{out_main}}Copy failed. The text is selected; copy it with your keyboard.
| Font id | fontfile |
|---|---|
inter | /opt/videxo/fonts/Inter-Regular.ttf |
inter-bold | /opt/videxo/fonts/Inter-Bold.ttf |
roboto | /opt/videxo/fonts/Roboto-Regular.ttf |
roboto-bold | /opt/videxo/fonts/Roboto-Bold.ttf |
open-sans | /opt/videxo/fonts/OpenSans-Regular.ttf |
open-sans-bold | /opt/videxo/fonts/OpenSans-Bold.ttf |
montserrat | /opt/videxo/fonts/Montserrat-Regular.ttf |
montserrat-bold | /opt/videxo/fonts/Montserrat-Bold.ttf |
poppins | /opt/videxo/fonts/Poppins-Regular.ttf |
poppins-bold | /opt/videxo/fonts/Poppins-Bold.ttf |
oswald | /opt/videxo/fonts/Oswald-Regular.ttf |
oswald-bold | /opt/videxo/fonts/Oswald-Bold.ttf |
bebas-neue | /opt/videxo/fonts/BebasNeue-Regular.ttf |
playfair-display | /opt/videxo/fonts/PlayfairDisplay-Regular.ttf |
playfair-display-bold | /opt/videxo/fonts/PlayfairDisplay-Bold.ttf |
merriweather | /opt/videxo/fonts/Merriweather-Regular.ttf |
merriweather-bold | /opt/videxo/fonts/Merriweather-Bold.ttf |
noto-sans | /opt/videxo/fonts/NotoSans-Regular.ttf |
noto-sans-bold | /opt/videxo/fonts/NotoSans-Bold.ttf |
noto-serif | /opt/videxo/fonts/NotoSerif-Regular.ttf |
noto-serif-bold | /opt/videxo/fonts/NotoSerif-Bold.ttf |
jetbrains-mono | /opt/videxo/fonts/JetBrainsMono-Regular.ttf |
jetbrains-mono-bold | /opt/videxo/fonts/JetBrainsMono-Bold.ttf |
atempo changes the tempo of sound and keeps its pitch: one literal factor from 0.5 to 2, or two
of them in a row for 0.25 to 4.
scdet scores how much each frame differs from the one before, with threshold (or t) from 0 to
100 and sc_pass (or s).
Scene lists#
An output file named .json is a scene list. It takes exactly this shape: one -map of one video
stream (0:v:0, not 0:v), and one -vf with one chain of filters that ends in scdet, without sc_pass.
-i {{in_video}} -map 0:v:0 -vf "scale=640:-2,scdet=threshold=12" {{out_scenes}}Copy failed. The text is selected; copy it with your keyboard.
Other options on that output are refused. Videxo writes the JSON file from scdet's scores
(Scene detection). metadata, the filter that prints them, is not available
in a command.
When a command is invalid#
The API returns 400 command_invalid, creates no job and describes the problem in problems.
Correct the reported problem and validate the command again:
{
"type": "https://videxo.io/docs/errors#command_invalid",
"title": "The command contains unsupported or invalid arguments. `problems` lists each one.",
"status": 400,
"detail": "Option -crf has an invalid value.",
"code": "command_invalid",
"retryable": false,
"request_id": "req_7h2m4x9q0c3v8k1n5r6t2b4z",
"problems": [
{
"code": "option_value",
"message": "Option -crf has an invalid value.",
"option": "-crf"
}
]
}Copy failed. The text is selected; copy it with your keyboard.
Every problem code:
| Code | Meaning |
|---|---|
command_limit | The command is empty or longer than 65,536 characters, has more than 1,024 arguments, a file map declares more than 16 files, an input alias follows -i more than 16 times, or the command has more than 32 -i. |
command_character | The command has a character outside printable ASCII, such as a control character or a look-alike dash. |
command_quoting | A quote is not closed, or the command ends with a lone backslash. |
shell_operator | The command uses |, &, ;, < or > outside quotes. A command is one ffmpeg run: quote the character or remove it. |
alias_invalid | An alias in input_files or output_files is not in_ or out_ followed by 1 to 48 letters, digits or underscores. |
alias_unknown | The command names an alias that is not in input_files or output_files. |
alias_position | An alias is not where a file goes: input aliases follow -i, output aliases stand as output paths. |
alias_reused | An output alias is used as a path more than once. |
alias_unused | An alias in input_files or output_files does not appear in the command. |
filename_invalid | An output file name has a path, a pattern, more than one extension or an unsupported extension. |
filename_duplicate | Two outputs have the same file name. Each output needs its own. |
path_forbidden | The command names a file, URL or protocol directly. Name every file by its alias. |
option_forbidden | The option is not supported in a command. Remove it. |
option_unknown | The option is not one of the supported options listed above. |
option_scope | The option is supported, but not in that place (global, input or output). |
option_value | The option's value is outside its supported values or range. |
option_missing_value | The option needs a value and has none. |
format_forbidden | The -f format is not a supported format, or does not match the output file name. |
graph_invalid | The filter graph cannot be read, has an invalid link label, or uses more than 128 filters. |
filter_forbidden | The filter is not one of the supported filters listed above. |
filter_option | A filter option is not supported, or its value is outside the filter's supported range. |
command_structure | The command needs at least one input and one output, every input before the first output, and no option after the last output; a .json output also needs one -map of a video stream and one -vf. |