Reference · Processing

# Options and filters we refuse

The service runs FFmpeg options sent by many customers on shared infrastructure. So one rule holds for every task: nothing may read or write outside the job’s own folder, and nothing may open the network. A task that tries is refused with 400 before anything runs, and is not charged.

## How a task runs

- Every input is downloaded into the job’s folder first, including URL inputs. FFmpeg itself only ever reads local files.
- FFmpeg runs with `-nostdin`, and with `-protocol_whitelist file,pipe` before every input. It is also told which kinds of input it may open; playlists and manifests are not among them.
- Each job has its own folder on its own machine, and the machine’s disk is erased when the job ends.

## Options

These are refused in `inputs[].options` and `outputs[].options`. They name other files or the network, or undo a protection.

- -i
- -protocol_whitelist
- -protocol_blacklist
- -attach
- -dump_attachment
- -dump
- -hex
- -filter_script
- -filter_complex_script
- -progress
- -report
- -sdp_file
- -vstats
- -vstats_file
- -stdin
- -safe
- -enable_drefs
- -use_absolute_path
- -allowed_extensions
- -allowed_segment_extensions
- -extension_picky
- -listen
- -listen_timeout
- -format_whitelist
- -codec_whitelist
- -/option
- --

`-/option` is the form that reads an option’s value from a file. Inputs come only from `task.inputs[]`, which is why `-i` is on the list.

So are the options that only print something and exit, since they leave nothing to process:

- -L
- -license
- -h
- -help
- -version
- -buildconf
- -formats
- -muxers
- -demuxers
- -devices
- -codecs
- -decoders
- -encoders
- -bsfs
- -protocols
- -filters
- -pix_fmts
- -layouts
- -sample_fmts
- -dispositions
- -colors
- -sources
- -sinks
- -hwaccels

## How an options array is read

Each `options` array is read the way FFmpeg reads it. A flag such as `-an` or `-shortest` stands alone. Every other option is followed by exactly one value. Anything else is refused: FFmpeg would take a stray entry for one more output file.

- `["-crf", "23", "-an"]` is an option with its value, then a flag.
- `["-movflags", "-faststart"]` is fine: a value may begin with a dash.
- `["-crf"]` is refused: the option needs a value.
- `["extra.mp4"]` is refused: it is not an option.

## Playlists and manifests

An input that is itself a list of other files is refused with 400, by its content and whatever its name: an HLS playlist, a DASH manifest, a concat script, an SDP description or an IMF composition. Such a file names its real sources inside itself, where no check of the request can see them. This holds for uploaded files and URL inputs, for processing and for probes. Upload the media files themselves.

## Formats

These values of `-f` are refused. They take their real sources or targets from somewhere other than the task’s inputs and outputs.

- concat
- lavfi
- tee
- fifo

So are the capture and playback devices:

- x11grab
- v4l2
- video4linux2
- alsa
- pulse
- oss
- fbdev
- kmsgrab
- dshow
- avfoundation
- gdigrab
- jack
- sndio
- iec61883
- libcdio
- libdc1394
- openal
- decklink
- xv
- sdl
- sdl2
- opengl
- caca

## Filters

These filters are refused wherever a filter graph appears: `task.filter_complex`, `-vf`, `-af`, `-filter`. They open files or sockets, or load code, by design.

- movie
- amovie
- zmq
- azmq
- sendcmd
- asendcmd
- frei0r
- frei0r_src
- ladspa
- lv2

## Values

Whatever the option or filter, a value is refused when it:

- is an absolute path (it starts with `/`, `~` or `\`);
- has a `..` segment;
- contains `://`;
- starts with an FFmpeg protocol prefix, such as `file:`, `http:`, `concat:`, `subfile,…:`, `pipe:` or `tcp:`;
- is `-` alone, which would read or write a pipe;
- contains a control character.

Two kinds of value are plain data and are not checked this way: the text of `drawtext=text=`, and the values of `-metadata`.

`outputs[].maps[]` takes stream specifiers and filter labels only.

## What is allowed

Relative names inside the job’s folder. A filter may read a file that is one of the task’s inputs by its name, so `subtitles=subs.srt` works when `subs.srt` is an input of the same task.

## What a refusal looks like

The error names the place and the reason:

```json
{"ok": false, "error": "outputs[0].options: the \"-report\" option is not allowed"}
{"ok": false, "error": "filter_complex: the \"movie\" filter is not allowed"}
{"ok": false, "error": "inputs[0].options: URLs are not allowed in options or filters"}
{"ok": false, "error": "outputs[0].options: the \"-crf\" option needs a value"}
{"ok": false, "error": "Input 'index.m3u8' is an HLS playlist. Playlists and manifests are not supported: upload the media files themselves."}
```
