# Av1an

Canonical URL: https://encode.wiki/tools/utilities/av1an/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): d249dfd506eccfcd7cc96afbfa198f4dce0a8f87105ace4a14a7c645d4868aac

> **Repository:** [rust-av/Av1an](https://github.com/rust-av/Av1an). Cross-platform command-line AV1 / VP9 / HEVC / H264 encoding framework with per scene quality encoding. Latest release: [v0.5.2](https://github.com/rust-av/Av1an/releases/tag/v0.5.2), Jan 4, 2026. Last commit: Sep 14, 2026. License: GPL-3.0. Stars: 1,997.

Av1an is a command-line encoding framework. It detects scene changes, cuts the video into chunks at those scenes, runs several encoder processes ("workers") at once, and joins the results with the audio. Encoders scale poorly across many cores on their own, so running one instance per chunk is how most people keep a modern CPU fully busy with slow AV1 presets.

It can also run in target-quality mode, where it searches for the CRF/quantizer of each chunk that hits a metric score (VMAF, SSIMULACRA2, Butteraugli or XPSNR).

Av1an does not encode anything itself. It drives the encoder executables (`aomenc`, `SvtAv1EncApp`, `rav1e`, `vpxenc`, `x264`, `x265`), and uses FFmpeg and VapourSynth for decoding. The cost of parallelism is memory: every worker holds its own encoder instance and source decoder, so RAM use grows with the worker count.

## Install it

- **Windows:** download `av1an.exe` from the [`latest`](https://github.com/rust-av/Av1an/releases/tag/latest) pre-release, a nightly build of `master`. The tagged releases carry no binaries.
- **Arch Linux:** `pacman -S av1an` (release build) or `av1an-git` from the AUR (master).
- **Cargo:** `cargo install av1an` for the release. For master, clone the repository and run `cargo build --release`. Building needs Rust, NASM, clang, FFmpeg and VapourSynth.
- **macOS:** build with Cargo; MacPorts also has a port.
- **Docker:** `masterofzen/av1an:master` contains every supported encoder and the optional plugins. Mount your working directory at `/videos`:

```sh
docker run --privileged -v "$(pwd):/videos" --user $(id -u):$(id -g) -it --rm masterofzen/av1an:master -i input.mkv -o output.mkv
```

> **Caution — Use a master build with current VapourSynth.**
>
> The latest tagged release, v0.5.2 (January 2026), cannot load VapourSynth R74 or newer, which changed how VapourSynth is packaged. It panics with `Failed to get VSScript API`. Compatibility landed on `master` in April and May 2026. If your VapourSynth is R74 or newer, use the nightly Windows build, `av1an-git`, the Docker image, or build master yourself.
Outside Docker you provide the dependencies yourself:

| Dependency                                                                                                                                                                                    | Needed for                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| [FFmpeg](/tools/utilities/ffmpeg/) and [VapourSynth](/tools/filtering/vapoursynth/)                                                                                                           | Always                                                                                  |
| At least one encoder executable                                                                                                                                                               | Always. A library package such as `libSvtAv1Enc` is not enough; you need `SvtAv1EncApp`. |
| A VapourSynth source plugin: [L-SMASH-Works](https://github.com/HomeOfAviSynthPlusEvolution/L-SMASH-Works), [FFMS2](https://github.com/FFMS/ffms2) or [BestSource](https://github.com/vapoursynth/bestsource) | Fast, frame-accurate chunking (strongly recommended)                                    |
| [mkvmerge](/tools/utilities/mkvtoolnix/)                                                                                                                                                      | The default concatenation method                                                        |
| FFmpeg with libvmaf                                                                                                                                                                           | VMAF target quality                                                                     |
| [Vship](/tools/utilities/vship/) (GPU) or [vszip](https://github.com/dnjulek/vapoursynth-zip) (CPU)                                                                                          | SSIMULACRA2 target quality                                                              |
| Vship or [vapoursynth-julek-plugin](https://github.com/dnjulek/vapoursynth-julek-plugin)                                                                                                       | Butteraugli target quality                                                              |

On Windows, install the plugins with VapourSynth's plugin manager from the VapourSynth directory: `python3 vsrepo.py install lsmas ffms2 bs vszip julek`. `av1an --version` lists which plugins and encoders it can find.

## Encode with SVT-AV1

```sh
av1an -i input.mkv -o output.mkv -e svt-av1 -v "--preset 4 --crf 30 --tune 0" -m lsmash
```

- `-e` picks the encoder and `-v` passes options straight to its executable, so use the encoder's own syntax (`--crf 30`, not FFmpeg's `-crf 30`). Run `SvtAv1EncApp --help` for the list.
- `--tune 0` selects SVT-AV1's visual-quality tune; its default (tune 1) optimises for PSNR.
- `-m lsmash` is the chunk method. Without `-m`, Av1an picks the first installed of `bestsource`, `lsmash`, `ffms2`, `dgdecnv`, then falls back to `hybrid`. BestSource is accurate but slow, so set `-m lsmash` when L-SMASH-Works is installed.
- Audio is copied (`-c:a copy`) and subtitles are passed through by default. Output is 10-bit 4:2:0 (`--pix-format yuv420p10le`) even from 8-bit sources, which is what you want for AV1.

To re-encode the audio, pass FFmpeg audio options with `-a`:

```sh
av1an -i input.mkv -o output.mkv -e svt-av1 -v "--preset 4 --crf 30 --tune 0" -a "-c:a libopus -b:a 128k"
```

`-a` uses stream specifiers rather than `-map`; for example `-a "-c:a:0 libopus -b:a:0 128k -c:a:1 copy"` treats two audio tracks differently.

## Encode with aomenc

```sh
av1an -i input.mkv -o output.mkv -e aom -v "--cpu-used=4 --end-usage=q --cq-level=30 --threads=2"
```

aomenc options use `=`. Av1an runs aomenc (and vpxenc) in two passes by default even in constant-quality mode, because both encoders use the first pass for better decisions; `-p 1` turns that off. `--threads=2` keeps each instance small so that more workers fit, which is the usual way to run aomenc under Av1an. The automatic worker count assumes about four threads per aomenc worker whatever `--threads` says, so set `-w` yourself (up to about half your CPU threads, RAM permitting).

## Options that matter

| Option                                     | Default                     | What it does                                                                                                                                                         |
| ------------------------------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-w`, `--workers`                          | `0` (automatic)             | Number of parallel encoder instances. Automatic picks the smaller of a CPU-based count (for example threads ÷ 6 for SVT-AV1, ÷ 4 for aomenc) and a RAM-based estimate. |
| `-m`, `--chunk-method`                     | First available (see above) | How exact frame ranges are fed to each encoder. See [Chunk methods](#chunk-methods).                                                                                  |
| `-c`, `--concat`                           | `mkvmerge`                  | How chunks are joined. `ffmpeg` can write WebM but does not work with x265; `ivf` is video-only.                                                                  |
| `-x`, `--extra-split` / `--extra-split-sec` | 10 seconds                  | Maximum chunk length. Longer scenes are split, which also caps the keyframe interval.                                                                                 |
| `--min-scene-len`                          | 24 frames                   | Shortest scene Av1an will cut.                                                                                                                                       |
| `--sc-downscale-height`                    | Off                         | Run scene detection on a downscaled copy (for example `720`) to make it faster on 4K sources.                                                                         |
| `-s`, `--scenes`                           | None                        | Save scene cuts to a JSON file, or reuse an existing one. Add `--sc-only` to detect scenes and exit.                                                                   |
| `-f`, `--ffmpeg`                           | None                        | FFmpeg filter arguments applied to the source, such as `-f "-vf crop=1920:800"`. For real filtering, use a VapourSynth script as input.                              |
| `--photon-noise`                           | `0` (off)                   | Generates an AV1 film-grain table (ISO-like strength, 1–64) for aomenc, rav1e and SVT-AV1. Do not combine it with the encoder's own grain option.                     |
| `--zones`                                  | None                        | File of frame ranges with different encoder settings.                                                                                                                |
| `--resume` / `-k`                          | Off                         | `-k` keeps the temporary directory; `--resume` continues an interrupted job from it.                                                                                   |
| `--temp`                                   | Hash of the input name      | Location of the work directory, which holds the encoded chunks.                                                                                                      |

## Target quality

```sh
av1an -i input.mkv -o output.mkv -e svt-av1 -v "--preset 4 --tune 0" --target-metric ssimulacra2 --target-quality 80
```

For each chunk, Av1an encodes a few fast probes at different CRFs (four by default), measures them, interpolates the CRF that should hit the target, and encodes the chunk at that value. It costs extra encoding time but evens out quality between easy and hard scenes.

| --target-metric  | Scale                      | Requires                                                    |
| ------------------ | -------------------------- | ----------------------------------------------------------- |
| `vmaf` (default)   | 0–100, higher is better    | FFmpeg built with libvmaf                                   |
| `ssimulacra2`      | Up to 100, higher is better | Vship or vszip, and a VapourSynth chunk method              |
| `butteraugli-inf`  | Distance, lower is better  | Vship or vapoursynth-julek-plugin, and a VapourSynth chunk method |
| `butteraugli-3`    | Distance, lower is better  | Vship, and a VapourSynth chunk method                       |
| `xpsnr`            | dB, higher is better       | FFmpeg's `xpsnr` filter (vszip when `--probing-rate` > 1). Scores the weakest of the Y, U and V planes. |
| `xpsnr-weighted`   | dB, higher is better       | As `xpsnr`; weights luma 4:1:1 over the chroma planes        |

Useful knobs: `--qp-range 15-45` bounds the CRF search; `--probes` sets the number of probes; `--probing-stat` chooses how per-frame scores are pooled (a low percentile or harmonic mean protects the worst frames better than a mean). Probes use a fast fixed preset by default; `--probe-video-params copy` probes with your real `-v` settings, which is more accurate and much slower, or you can pass your own probe settings.

VMAF is the default, but the community generally prefers SSIMULACRA2 or Butteraugli for this: VMAF's default model scores 1080p viewing on a TV and can be inflated by sharpening. Whatever metric you target, watch the result. See [SSIMULACRA2](/reference/metrics/ssimulacra2/), [Butteraugli](/reference/metrics/butteraugli/), [XPSNR](/reference/metrics/xpsnr/) and [VMAF](/reference/metrics/vmaf/).

## Use a VapourSynth script

Pass a `.vpy` or `.py` script as the input to filter (denoise, deband, crop, resize) before encoding:

```sh
av1an -i script.vpy -o output.mkv -e svt-av1 -v "--preset 4 --crf 30 --tune 0"
```

Scene detection and target-quality probing also run through the script, so expensive filters slow them down too. `--proxy` points those steps at a cheaper input with the same frame count, such as the unfiltered source. With a script input, Av1an has no source file to take audio from; mux audio separately with [mkvmerge](/tools/utilities/mkvtoolnix/) afterwards.

## Chunk methods

| Method       | Notes                                                                                                                      |
| ------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `lsmash`     | L-SMASH-Works. Usually the best choice: fast, frame-accurate, and errors out on a broken stream instead of hiding it.        |
| `ffms2`      | FFMS2. Similar to lsmash, but occasionally produces artifacts that lsmash does not.                                        |
| `bestsource` | BestSource. The default when installed. Decodes linearly, so it is slow, but it is the most reliable when seeking is the problem. |
| `dgdecnv`    | DGDecNV. Very fast NVIDIA hardware decoding; AVC, HEVC, MPEG-2 and VC-1 only; needs `dgindexnv` in `PATH`.                   |
| `hybrid`     | FFmpeg only. Splits the source at keyframes into temporary files, then trims precisely; needs disk space.                  |
| `segment`    | FFmpeg only. Cuts at existing keyframes, so chunks are not frame-exact.                                                    |
| `select`     | FFmpeg only. Decodes from the start every time; extremely slow.                                                            |

The VapourSynth methods write an index next to the source file on the first run. `--cache-mode temp` puts it in the work directory instead.

## Common problems

- **Av1an adds its own encoder defaults.** Unless you pass `--no-defaults`, Av1an puts its default arguments in front of your `-v` string, dropping any flag you set yourself. For SVT-AV1 that leaves `--keyint 0 --scd 0 --rc 0`; for aomenc it prepends `--threads=8 --cpu-used=6 --disable-kf --kf-max-dist=9999` (your own `--threads=`/`--cpu-used=` come later and win). The point is that keyframes come from Av1an: every chunk starts with exactly one keyframe and the encoder places none of its own. Use `--extra-split-sec` (or `-x` in frames) to change the maximum interval rather than `--keyint`. With `--no-defaults`, only your `-v` is passed, so add `--keyint 0` (SVT-AV1) or `--disable-kf --kf-max-dist=9999` (aomenc) yourself.
- **Gray or corrupted frames at chunk boundaries.** The source filter seeked inaccurately, which happens with some files. Switch to `-m bestsource`, which decodes linearly, or encode a lossless intermediate first (for example x264 with `--qp 0`), which fixes seeking problems at the cost of a very large file.
- **Running out of memory.** Lower `-w`. A 4K SVT-AV1 worker can need several gigabytes, and the automatic worker count is estimated from total RAM, not free RAM.
- **Too many short scenes.** Flashes and strobes can trigger extra cuts. `--min-scene-len` stops cuts closer together than that many frames; save the scenes with `-s` so later attempts reuse the same cuts instead of detecting them again.
- **XPSNR target scores use swapped inputs.** FFmpeg's `xpsnr` filter treats its first input as the reference, but Av1an (v0.5.2 and current master) passes the encoded probe first. With the default `--probing-rate 1`, XPSNR targets are therefore computed with the perceptual weighting taken from the encode and do not match XPSNR measured correctly elsewhere. The vszip path (`--probing-rate` 2–4) passes the inputs correctly.
- **Changed settings while resuming.** `--resume` reuses finished chunks as they are. If you change the encoder settings, the input or the scenes, delete the work directory and start again.
