# Technical Documentation: WyattBlue/auto-editor

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/WyattBlue/auto-editor)

### Overview (`README.md`)

<p align="center"><img src="https://auto-editor.com/img/auto-editor-banner.webp" title="Auto-Editor" width="700"></p>

**Auto-Editor** is a command line application for automatically **editing video and audio** by analyzing a variety of methods, most notably audio loudness.

---

[](https://basswood.io/discord)
[](https://nim-lang.org)

Before doing the real editing, you first cut out the "dead space" which is typically silence. This is known as a "first pass". Cutting these is a boring task, especially if the video is very long.

```
auto-editor path/to/your/video.mp4
```

<h2 align="center">Installing</h2>

See [Installing](https://auto-editor.com/installing) for more information.

<h2 align="center">Skills</h2>

```
npx skills add WyattBlue/auto-editor
```

<h2 align="center">Cutting</h2>

Change the **pace** of the edited video by using `--margin`.

`--margin` adds in some "silent" sections to make the editing feel nicer.

```
# Add 0.2 seconds of padding before and after to make the edit nicer.
# `0.2s` is the default value for `--margin`
auto-editor example.mp4 --margin 0.2sec

# Add 0.3 seconds of padding before, 1.5 seconds after
auto-editor example.mp4 --margin 0.3s,1.5sec
```

### Methods for Making Automatic Cuts
The `--edit` option is how auto-editor makes automated cuts.

For example, edit out motionlessness in a video by setting `--edit motion`.

```
# cut out sections where the total motion is less than 2%.
auto-editor example.mp4 --edit motion:threshold=0.02

# `--edit audio:threshold=0.04,stream=all` is used by defaut.
auto-editor example.mp4

# Different tracks can be set with different attribute.
auto-editor multi-track.mov --edit "(or audio:stream=0 audio:threshold=10%,stream=1)"
```

Different editing methods can be used together.
```
# 'threshold' is always the first argument for edit-method objects
auto-editor example.mp4 --edit "(or audio:0.03 motion:0.06)"
```

You can also use `dB` unit, a volume unit familiar to video-editors (case-sensitive):
```
auto-editor example.mp4 --edit audio:-19dB
auto-editor example.mp4 --edit audio:-7dB
auto-editor example.mp4 --edit motion:-19dB
```

### Labels
Every moment gets an integer **label**: `0` is silent (cut by default), `1` is active (kept). `--edit` sets what's label `1`; `-w:0`/`-w:1` set each one's action. Add more classes with `--edit:N` and `--when:N` (`N` up to 255); where they overlap, the higher label wins.
```
# Cut silence, keep speech, and additionally speed up the loud parts
auto-editor example.mp4 --edit:2 audio:-12dB --when:2 speed:1.5
```
As a value (not a label), `--edit 1` keeps everything and `--edit 0` cuts everything. See the [actions docs](https://auto-editor.com/docs/actions) for more.

### See What Auto-Editor Cuts Out
To export what auto-editor normally cuts out. Set `--when-active` to `cut` and `--when-inactive` to `nil` (leave as is). This is the reverse of the usual default values.

```
auto-editor example.mp4 --when-active cut --when-inactive nil
```

<h2 align="center">Exporting to Editors</h2>

Create an XML file that can be imported to Adobe Premiere Pro using this command:

```
auto-editor example.mp4 --export premiere
```

Auto-Editor can also export to:
- DaVinci Resolve with `--export resolve`
- Final Cut Pro with `--export final-cut-pro`
- ShotCut with `--export shotcut`
- Kdenlive with `--export kdenlive`
- Individual media clips with `--export clip-sequence`

<h2 align="center">More Options</h2>

List all available options:

```
auto-editor --help
```

## Articles
 - [How to Install Auto-Editor](https://auto-editor.com/installing)
 - [All the Options (And What They Do)](https://auto-editor.com/ref/options)
 - [Docs](https://auto-editor.com/docs)
 - [Blog](https://basswood.io/blog/)

## Run Online and as an Application
You can [run auto-editor online](https://app.auto-editor.com/online) or [download the application](https://app.auto-editor.com/download). They use assets from this repository (Unlicense); their own unique assets are under a separate proprietary license.

## Copyright
Everything in this repository is under the [Public Domain](https://github.com/WyattBlue/auto-editor/blob/master/LICENSE). Binary artifacts in the "Releases" section may be under various open source licenses.

---

### Overview (`docs/README.md`)

# Source Code, Documents, and Resources For https://auto-editor.com.

## Requirements
 - [Hunim](https://github.com/basswood-io/hunim)
 - rsync and ssh (for deployment)

```sh
# Run local
hunim server

# Publish
make upload
```

## Server Requirements
 - systemd
 - reverse proxy (nginx, etc.)
 - [bun](https://bun.com)

## Deployment Example

file `/etc/systemd/system/ae.service`

```
[Unit]
Description=AutoEditor Website
After=network.target

[Service]
User=root
WorkingDirectory=/var/www/auto-editor
ExecStart=/root/.bun/bin/bun run server.js

[Install]
WantedBy=multi-user.target
```

---

### Src Docs Index (`docs/src/docs/index.md`)

---
title: The Docs
---

## General
 * [Cookbook](./cookbook)
 * [Actions Cookbook](./actions)
 * [Audio Normalizing](./anorm)
 * [How to Shrink File Size](./file-size)
 * [Subcommands](./subcommands)
 * [Supported Media](./supported-media)
 * [Range Syntax](./range-syntax)
 * [Transitions](./transition)

## Timeline Documentation
 * [The v1 format](./v1)
 * [The v2 format](./v2)
 * [The v3 format](./v3)

See also: [reference](../ref)

---

### Src Ref Index (`docs/src/ref/index.md`)

---
title: Reference
---

[CLI Options](./options) — Describes auto-editor's command line options

[Actions](./actions) - Reference of all actions

[Edit](./edit) - How `--edit` Works

---

### Src Docs Subcommands Index (`docs/src/docs/subcommands/index.md`)

---
title: Subcommands
---

Commands (or subcommands) are auxiliary programs that offer additional functionality. They have their own options, separate from the main auto-editor cli.

* [cache](./cache)
* [desc](./desc)
* [info](./info)
* [levels](./levels)
* [subdump](./subdump)
* [whisper](./whisper)

<a class="next" href="/docs/supported-media">Next: Supported Media</a>

---

### Package.Json (`docs/package.json`)

{
  "name": "auto-editor.com",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "dev": "bun run --watch server.js"
  },
  "dependencies": {
    "express": "latest"
  }
}

---

### Src Installing (`docs/src/installing.md`)

---
title: Installing Auto-Editor
---

## Method 1 (Recommended)
Get the official binary, available on Windows, macOS, and Linux.

 1. Go to the [Releases page](https://github.com/WyattBlue/auto-editor/releases) on GitHub, and download the binary for your platform.
 2. Rename the binary to auto-editor (or auto-editor.exe for Windows).
 3. `cd` into your downloads folder. If on macOS/Linux, run `chmod +x ./auto-editor` first.
 4. Run Auto-Editor in the terminal. Because the binaries are unsigned, you may get "Unknown developer" warnings. Ignore them.

Congratulations, auto-editor should now be installed. To verify auto-editor is installed, run:

```sh
./auto-editor --help
```

It's recommended to place the binary in a PATH directory so that `auto-editor` is always available no matter your current working directory.

## Method 2: Platform Installers
If you're on macOS, use [Homebrew](https://brew.sh):
```sh
brew install auto-editor
```

Auto-Editor is available on the Arch Linux AUR:

```sh
yay -S auto-editor
```

### Notice for Pip Users
The auto-editor cli is no longer being published on pip. It is recommended to switch to a different installation method.

### Notice for 'Apt' Users
The pkg versions available are very old. Either use the official binaries (recommened) or use [Homebrew for Linux](https://docs.brew.sh/Homebrew-on-Linux).

## Installing from Source (Unix-Like):
Install `nim`, `nimble`, `cmake`, `meson`, `ninja`, then run:

```sh
nimble makeff  # Downloads and builds all dependencies
nimble make  # Build statically
```

or build dynamically

```sh
# Needs ffmpeg libs installed.
nimble brewmake
```

## Installing from Source (Windows)
To build an `.exe`, you'll need [WSL](https://learn.microsoft.com/en-us/windows/wsl/about). In that environment, install `nim`, `nimble`, `cmake`, `meson`, `ninja`, then run:

```sh
nimble makeffwin
nimble makewin
```

For Windows ARM, run:

```sh
nimble makeffwinarm
nimble makewinarm
```

## Optional Dependencies
If yt-dlp is installed, auto-editor can download and use URLs as inputs.
```sh
auto-editor "https://www.youtube.com/watch?v=kcs82HnguGc"
```

How yt-dlp is installed does not matter.

<a class="next" href="/docs/cookbook">Next: Cookbook</a>

---

### Src Robots (`docs/src/robots.txt`)

User-agent: *
Sitemap: https://auto-editor.com/sitemap.xml

---

### Src Docs Actions (`docs/src/docs/actions.md`)

---
title: Actions
---

Actions define what auto-editor does to different parts of your media. By default, inactive (silent) sections are cut out and active (loud) sections are kept unchanged. Actions give you fine-grained control over this behavior.

## Basic Syntax

Actions are specified using the `--when-inactive` and `--when-active` options:

```sh
# Cut inactive sections (default behavior)
auto-editor video.mp4 --when-inactive cut

# Keep active sections unchanged (default behavior)
auto-editor video.mp4 --when-active nil
```

These options have aliases:
- `--when-inactive` = `--when-silent`, `-w:0`
- `--when-active` = `--when-normal`, `-w:1`

## Labels

The `:0` and `:1` in `-w:0`/`-w:1` are **labels**. Auto-editor tags every moment
of the timeline with an integer label (0–255) and runs that label's action. Two
labels are built in:

- **0** — *inactive* ("silent"): everything `--edit` does **not** match. Its
  action is `--when-inactive` / `-w:0` / `--when:0` (default `cut`).
- **1** — *active* ("normal"): what `--edit` matches. Its action is
  `--when-active` / `-w:1` / `--when:1` (default `nil`).

So `--edit METHOD` is shorthand for `--edit:1 METHOD` — it sets which moments get
label 1.

### Custom classes (`--edit:N` / `--when:N`)

Define extra classes with `--edit:N EXPR` (where `N` is `2`–`255`) and give each
its own action with `--when:N ACTION`. Where two classes overlap, the **higher
label wins**, so later/larger labels layer on top of the basic silent/active split.

```sh
# Cut silence and keep speech as usual, but additionally speed up the loud parts
auto-editor video.mp4 --edit:2 audio:-12dB --when:2 speed:1.5

# -e/-w short forms; zoom wherever there is motion, on top of the audio edit
auto-editor video.mp4 -e:2 motion:0.02 -w:2 zoom:2
```

## Available Actions

### nil

Do nothing. Keep the section unchanged.

```sh
# Keep everything, even silent sections
auto-editor video.mp4 --when-inactive nil
```

### cut

Remove the section completely from the output.

```sh
# Remove inactive sections (default behavior)
auto-editor video.mp4 --when-inactive cut

# Remove active ("loud") sections (inverted editing)
auto-editor video.mp4 --when-active cut
```

### speed

Change the playback speed while preserving pitch using time-stretching.

```sh
# Speed up inactive sections to 8x (preserving pitch)
auto-editor video.mp4 -w:0 speed:8

# Slow down active sections to half speed
auto-editor video.mp4 -w:1 speed:0.5
```

### varispeed

Change the playback speed by varying pitch, like analog tape or vinyl.
- **Value range:** 0.2 to 100.0

```sh
# Speed up inactive sections with pitch variation
auto-editor video.mp4 -w:0 varispeed:2

# Create slow-motion effect with lower pitch
auto-editor video.mp4 -w:1 varispeed:0.5
```

### pitch

Shift the pitch of the section in semitones, leaving its speed and duration alone.
- **Value range:** -24.0 to 24.0 semitones
- **12** = one octave up, **-12** = one octave down, **0** = unchanged

```sh
# Chipmunk the silent sections
auto-editor video.mp4 -w:0 pitch:12

# Drop active sections a fifth
auto-editor video.mp4 -w:1 pitch:-7

# Subtle detune (a quarter tone)
auto-editor video.mp4 -w:1 pitch:0.5
```

To change speed and pitch together, use `varispeed` instead.

### tone

Synthesize a wave at the pitch of a MIDI note, `tone:note[:waveform]`:

- **note** — a whole MIDI note number, 0 to 127. `69` is A4 (440 Hz) and `60`
  is middle C; each step is a semitone, so `f = 440 * 2^((note-69)/12)`.
- **waveform** — `sine` (the default), `saw`, `square`, or `triangle`.

`tone` is a **generator action**: it does not alter existing audio, it stands in for a file in `add:` and lays the note on its own audio layer (see [add](#add) below). Because it adds a layer rather than a second output stream, the tone is mixed into the audio you already have.

```sh
# A 440 Hz reference tone over every kept section
auto-editor video.mp4 -w:1 add:tone:69

# Beep the silent sections instead of cutting them
auto-editor video.mp4 -w:0 nil,add:tone:81

# A C major chord: one layer per note, summed by the mix
auto-editor video.mp4 -w:1 add:tone:60,add:tone:64,add:tone:67

# A buzzy bass instead of a pure tone
auto-editor video.mp4 -w:1 add:tone:36:saw

# Square for a chiptune blip, triangle for something softer
auto-editor video.mp4 -w:1 add:tone:84:square
auto-editor video.mp4 -w:1 add:tone:72:triangle
```

It has no envelope of its own, so a bare `tone` holds flat for the whole
section. Chain the animatable `volume` action for fades and decays:

```sh
# A plucked note that decays away
auto-editor video.mp4 -w:1 add:tone:60,volume:1..0:ease=out

# Quieter, so it sits under the program audio
auto-editor video.mp4 -w:1 add:tone:69,volume:0.3
```

### volume

Adjust the audio volume level.
- **1.0** = normal volume
- **0.5** = half volume (-6dB)
- **2.0** = double volume (+6dB)

```sh
# Reduce silent section volume to 20%
auto-editor video.mp4 -w:0 volume:0.2

# Boost loud sections
auto-editor video.mp4 -w:1 volume:1.5

# Fade the audio in across the section (see Animations below)
auto-editor video.mp4 -w:1 volume:0..1
```

### deesser

Reduce harsh "s" and "sh" sibilance in the audio section. Takes up to three
positional args, `deesser:intensity[:max[:freq]]`, each in the range 0.0 to 1.0:
- **intensity** — how much to de-ess (0.0 = none, 1.0 = maximum)
- **max** — caps the maximum reduction (default 0.5)
- **freq** — split frequency (default 0.5)

```sh
# De-ess active (spoken) sections
auto-editor video.mp4 -w:1 deesser:0.5

# Stronger de-essing with a higher max reduction and tuned frequency
auto-editor video.mp4 -w:1 deesser:0.8:0.7:0.4
```

### invert

Invert all pixels in the video section.

```sh
auto-editor video.mp4 -w:0 invert
```

### zoom

Zoom in or out by a factor.
- **Value range:** greater than 0.0, up to 100.0
- **1.0** = no zoom

```sh
# Zoom in 2x on active sections
auto-editor video.mp4 -w:1 zoom:2

# Zoom out on silent sections
auto-editor video.mp4 -w:0 zoom:0.5
```

### rotate

Rotate the picture clockwise about its center by a **fixed** `deg` angle,
`rotate:deg`. The picture is **expanded** so nothing is clipped (a 90° rotation
turns a landscape picture upright), and the corners exposed by the rotation are
filled with the background color. The rotated picture is then fit into the output
`--resolution` as usual, so pair `rotate:90` with a matching `--resolution` for a
true portrait output. For a continuous rotation, use [`spin`](#spin) instead.

```sh
# Turn the picture upside-down
auto-editor video.mp4 -w:1 rotate:180

# Turn a 1920x1080 landscape video into a 1080x1920 portrait one
auto-editor video.mp4 -w:1 rotate:90 --resolution 1080,1920
```

**How it works:** Uses FFmpeg's `rotate` filter with `ow=rotw:oh=roth`. Unlike
the ramp effects below, `rotate` is not affected by `ease`.

### spin

Spin the picture continuously, `spin:deg/rate`: start at `deg` and turn at `rate`
degrees per second (negative `rate` spins counter-clockwise).

```sh
# Spin at 120 degrees/second (one full turn every 3 seconds)
auto-editor video.mp4 -w:1 spin:0/120

# Start at 90 degrees and spin counter-clockwise at 45 degrees/second
auto-editor video.mp4 -w:1 spin:90/-45
```

The picture spins inside a constant square big enough to contain every rotation,
so it is **never clipped** at any angle. When `spin` is applied to an overlay
layer (see [`add`](#add)) the exposed corners are left **transparent**, so only
the picture shows over the layers below; otherwise they are filled with the
background color.

```sh
# Spin a logo overlay over the video
auto-editor video.mp4 -w:1 add:./logo.png,spin:0/-30
```

**How it works:** Uses FFmpeg's `rotate` filter with the angle driven by a
per-frame time expression. Like `rotate`, it is not affected by `ease`.

### drawbox

Draw a filled rectangle onto the picture. Takes five positional args,
`drawbox:x:y:w:h:color`:

- **x**, **y** — the top-left corner, in pixels.
- **w**, **h** — the width and height, in pixels (both must be positive).
- **color** — an RGB color, either a name (`red`) or a hex value (`#ff0000`).

```sh
# Cover the top-left corner with a 400x200 red box
auto-editor video.mp4 -w:1 drawbox:100:100:400:200:red

# A black bar across part of the frame (e.g. to redact something)
auto-editor video.mp4 -w:1 drawbox:0:0:1920:200:#000000
```

`drawbox` is also a **generator action**: `add:drawbox:...` paints the box on
its own overlay layer instead of onto the picture (see [add](#add) below).

**How it works:** Uses FFmpeg's `drawbox` filter with `t=fill`, so the
rectangle is filled rather than outlined. Only RGB colors are supported.

### pos

Place this clip as an overlay when it is composited over a lower video track,
`pos:x:y[:scale]`:

- **x**, **y** — the overlay's top-left corner, in canvas pixels.
- **scale** — optional size multiplier of the source's native size (default
  `1.0`).

`pos` has no effect on the base (bottom) track. It is mainly used inside a v3
timeline's effects array (see [The v3 format](./v3)) or attached automatically by
the `add` action below.

### add

Overlay a media file on top of the matched sections, `add:path` or
`add:path:x:y:scale`:

- **path** — a media file (e.g. a PNG logo, a video, or an audio file). Still
  images are held for the whole section. In place of a file, a **generator action** (with its
  usual arguments) may be given: the layer starts as a transparent canvas that
  the action paints, so the picture below shows through everywhere it did not
  draw. The video generators are [confetti](/ref/actions#confetti) and
  [drawbox](/ref/actions#drawbox); [tone](/ref/actions#tone) is an audio
  generator, and adds an audio layer instead of a picture (all are marked `G`
  in the [quick reference](/ref/actions#quick-reference)).
- **x**, **y**, **scale** — optional placement, applied via a `pos` action
  (above). When omitted, the overlay is scaled to fit the canvas (preserving
  aspect ratio) and centered, like a full-frame layer. Each may be a **ramp**
  (e.g. `0..600`), so the overlay animates across the section.

```sh
# Overlay a logo scaled to fit and centered over every kept (normal) section
auto-editor video.mp4 -w:1 add:./logo.png

# Put a logo at (600, 300)
auto-editor video.mp4 -w:1 add:./logo.png:600:300:1.0

# Slide a logo across the frame while shrinking it (ramps in x and scale)
auto-editor video.mp4 -w:1 add:./logo.png:0..1000:300:1..0.5

# Shrink an overlay video to a quarter size in the corner
auto-editor video.mp4 -w:1 add:./pip.mp4:900:60:0.25

# Overlay only over a specific time range (frames where 1s..2s plays)
auto-editor video.mp4 --set-action add:./logo.png:600:300:1.0,1sec,2sec

# Confetti on its own layer, over the picture rather than baked into it
auto-editor video.mp4 -w:1 add:confetti:300

# Recolor the layer without touching the video below
auto-editor video.mp4 -w:1 add:confetti:300:white,invert

# Audio plus a confetti layer: a video with no footage
auto-editor song.mp3 -w:1 add:confetti:300:white

# A box on its own layer, so later actions hit only the box
auto-editor video.mp4 -w:1 add:drawbox:100:100:400:200:red,opacity:0.5

# A tone on its own audio layer, mixed under the video's own audio
auto-editor video.mp4 -w:1 add:tone:69,volume:0.3
```

`add` brings **every stream** the source holds, so an added clip sounds like it
looks. A video with sound becomes a video layer plus one audio layer per audio
stream, on exactly the same sections, so picture and sound stay together. A file
with no picture (an mp3, a wav) adds only sound — handy for background music —
and grows no video stream; a still image adds only picture. Actions chained after
the `add` reach whichever of the two exist, so `add:pip.mp4,volume:0.3` tucks the
overlay's audio under the base while leaving the base's own audio alone.

```sh
# Picture-in-picture that you can also hear
auto-editor video.mp4 -w:1 add:./pip.mp4:900:60:0.25

# ...with its audio tucked under the original
auto-editor video.mp4 -w:1 add:./pip.mp4:900:60:0.25,volume:0.3

# Background music over the whole edit (no picture added)
auto-editor video.mp4 -w:1 add:./music.mp3,volume:0.4
```

An added layer is an overlay, so its audio is **mixed into** the output's audio
rather than written beside it as a second stream — which is also why several
`add:tone` layers stack into a chord, and why `-o out.wav` still works. An audio
generator likewise needs no canvas and never grows a video stream.

Unlike the other actions, `add` is **virtual**: it is not a per-frame effect but
adds an overlay layer to the timeline (the same compositing used by stacked v3
tracks; see [The v3 format](./v3)). It is colon-separated (one comma-field), so
it chains with other actions.

**Actions chained after an `add` apply to that new overlay layer, not the
original.** So in `-w:1 add:./logo.png,spin:0/-30` the `spin` rotates the
logo, while `-w:1 zoom:2,add:./logo.png` zooms the base video and then
overlays the logo on top. A later `add` starts a new overlay, and following
actions attach to it.

The overlay only appears where the section it is attached to is kept — so
`-w:0 add:...` requires keeping those sections too, e.g.
`-w:0 nil,add:./logo.png`. With `--set-action`, the range is kept
automatically. Overlay transparency (a PNG alpha channel) is preserved.

For an **audio-only** input, `add` synthesizes a background video canvas (the
`--background` color, at `--resolution`) so the output gains a video stream —
handy for turning an audio file plus an image into a video. The video is only
created when there is an active section for the overlay to sit on: e.g.
`auto-editor song.mp3 -bg white -w:1 add:./cover.png` makes a video, but if the
edit leaves no active sections (so the `-w:1` overlay matches nothing) the
output stays audio-only.

The default output name copies the input's extension, which could not hold that
video (`song.mp3` → `song_ALTERED.mp3`), so it switches to `.mp4` instead. An
explicit `-o out.mp3` is still honored, with a warning that the video is dropped.

## Multiple Actions (Chaining)

You can combine multiple actions using commas. Actions are applied in the order specified.

```sh
# Speed up AND reduce volume
auto-editor video.mp4 -w:0 speed:3,volume:0.5

# Combine speed and varispeed
# Effective speed: 1.25 × 1.25 = 1.5625x
auto-editor video.mp4 -w:1 varispeed:1.25,speed:1.25

# Triple action: speed, varispeed, and volume
auto-editor video.mp4 -w:0 speed:2,varispeed:1.5,volume:0.8
```

## Animations

For transitions between clips, use the [edit-point option](./transition) instead of an action:

```sh
# Cross-dissolve cuts of at least 1 second; fade the timeline endpoints.
auto-editor video.mp4 --transition dissolve:0.5sec

# Override the minimum cut duration, or use :0 to include every eligible cut.
auto-editor video.mp4 --transition dissolve:0.5sec:2sec
auto-editor video.mp4 --transition dissolve:0.5sec:0
```

The transition is linked across the primary video and audio tracks. `opacity`
and `volume` ramps remain useful when only one section or one media type should
fade. The minimum-cut duration defaults to one second and affects internal cuts
only; timeline start/end fades are unchanged.

The animatable effects — `zoom`, `opacity`, `blur`, and `brightness` for video,
plus `volume` for audio — accept a **ramp** instead of a single value, written
`from..to`. The value is interpolated across the section, so the effect changes
over time. (For rotation, use the constant-speed `rotate:deg/rate` form
described above.)

`pos` and `pixelate` are animatable too: each of their fields (`x`, `y` and
`scale`; block `w` and `h`) takes its own ramp, so an overlay can slide and
resize across the section and a mosaic can coarsen as it plays.

```sh
# Slowly zoom in from 1x to 1.5x across the section (Ken Burns)
auto-editor video.mp4 -w:1 zoom:1..1.5

# Fade in (opacity 0 to 1)
auto-editor video.mp4 -w:1 opacity:0..1

# Fade the audio in alongside it
auto-editor video.mp4 -w:1 volume:0..1

# Slide a logo across the frame while shrinking it
auto-editor video.mp4 -w:1 add:./logo.png,pos:0..1200:40:1..0.5

# Dissolve the picture into ever-coarser blocks
auto-editor video.mp4 -w:1 pixelate:1..64
```

The ramp reaches `to` on the section's last frame.

### Keyframes

A ramp can have more than two points — list them with `..` and the value is
interpolated piecewise between them, evenly spread across the section:

```sh
# Zoom in then back out
auto-editor video.mp4 -w:1 zoom:1..1.5..1

# Fade in, hold, fade out
auto-editor video.mp4 -w:1 opacity:0..1..1..0
```

### Easing and duration

By default a ramp is linear and spans the whole section. Attach an easing curve
with `:ease=`:

```sh
auto-editor video.mp4 -w:1 zoom:1..1.5:ease=inout
```

`:ease=curve[:duration]`
- **curve** — `linear`, `in`, `out`, or `inout`
- **duration** — optional; e.g. `2sec` or a bare frame count. Once it elapses,
  the value holds at its end. Omitted, the animation spans the whole section.

```sh
# Ease in over the first 2 seconds, then hold
auto-editor video.mp4 -w:1 opacity:0..1:ease=in:2sec
```

You can also write the curve as a standalone `ease:` token. It applies to every
animated action that follows it (until another `ease` overrides it), which is
handy for giving several effects the same curve:

```sh
# Both zoom and brightness ease out
auto-editor video.mp4 -w:1 ease:out,zoom:1..1.3,brightness:0..0.3
```

## Setting Actions for a Time Range

Use `--set-action` to apply an action to a specific time range, overriding the default actions:

```sh
# Keep a section unchanged from 0 to 5 seconds
auto-editor video.mp4 --set-action nil,0,5sec

# Apply speed + varispeed from 30 seconds to the end
auto-editor video.mp4 --set-action speed:1.5,varispeed:1.5,30sec,end
```

The format is `ACTION,START,END` where `ACTION` can be any action or comma-separated list of actions.

## Common Use Cases

### Fast-Forward Through Silence
```sh
auto-editor video.mp4 -w:0 speed:8
```

### Subtle Speed Variations
```sh
# Slightly slow down normal sections for emphasis
auto-editor video.mp4 -w:1 speed:0.9
```

### Duck Audio During Silence
```sh
# Keep silent sections but reduce volume
auto-editor video.mp4 -w:0 volume:0.3
```

### Podcast Editing
```sh
# Cut silence, slightly speed up speech
auto-editor podcast.mp3 -w:0 cut -w:1 speed:1.15
```

### Music Editing
```sh
# Keep everything but boost quiet parts
auto-editor song.mp3 -w:0 volume:1.8 -w:1 volume:1.0
```

### Creative Effects
```sh
# Nightcore effect: speed up and pitch up
auto-editor video.mp4 -w:1 varispeed:1.25

# Slow-mo with deep voice
auto-editor video.mp4 -w:1 varispeed:0.75

# Fast silent sections with reduced volume
auto-editor video.mp4 -w:0 speed:6,volume:0.4

# Censor a face/plate: pixelate only a rectangular region
auto-editor video.mp4 -w:1 confine:400:300:200:80,pixelate:24

# Ramp the censor up, easing into a 48px mosaic
auto-editor video.mp4 -w:1 pixelate:4..48:ease=inout
```

## See Also
- [Complete Actions Reference](/ref/actions)
- [Audio Normalization](./anorm) - Volume normalization options

<a class="next" href="./range-syntax">Next: Range Syntax</a>

---

### Src Docs Anorm (`docs/src/docs/anorm.md`)

---
title: Audio Normalizing
---

Audio normalization adjusts audio levels for consistent loudness — useful when combining sources at different volumes, or meeting a platform's loudness target.

Auto-Editor supports two kinds: **peak** scales by the highest amplitude (simple, fast, preserves dynamic range); **ebu** (EBU R128) analyzes perceived loudness over time to meet broadcast standards.

## Peak

Example:

```sh
auto-editor --audio-normalize peak:-3  # set max peak to -3dB
```

## EBU

Example:

```sh
auto-editor --audio-normalize ebu  # use default values
auto-editor --audio-normalize ebu:i=-16  # set integrated loudness target
auto-editor --audio-normalize "ebu:i=-5,lra=20,gain=5,tp=-1"  # customize all parameters
```

### Parameters

- **i** (integrated loudness): Target integrated loudness in LUFS (Loudness Units Full Scale)
  - Default: `-24.0`
  - Range: `-70.0` to `5.0`
  - Common values: `-23` (EBU R128), `-16` (streaming), `-14` (podcasts)

- **lra** (loudness range): Target loudness range in LU
  - Default: `7.0`
  - Range: `1.0` to `50.0`
  - Describes the variation between soft and loud passages

- **tp** (true peak): Maximum true peak level in dBTP
  - Default: `-2.0`
  - Range: `-9.0` to `0.0`
  - Prevents clipping during digital-to-analog conversion

- **gain**: Additional gain offset in dB
  - Default: `0.0`
  - Range: `-99.0` to `99.0`
  - Applied on top of the loudness normalization

### How It Works

EBU normalization uses a two-pass process:

1. **Analysis Pass**: Measures the integrated loudness, loudness range, and true peak of the entire audio
2. **Normalization Pass**: Applies the FFmpeg `loudnorm` filter with the measured values to normalize the audio to your target levels

---

### Src Docs Cookbook (`docs/src/docs/cookbook.md`)

---
title: Cookbook
---

Short, practical recipes for getting started with auto-editor. Each one is a
command you can copy, paste, and tweak. Replace `video.mp4` with your own file.

## The simplest edit

Cut out the silent "dead space" automatically. This is all you need to start:

```sh
auto-editor video.mp4
```

The result is written to `video_ALTERED.mp4`. To name it yourself, use `-o`:

```sh
auto-editor video.mp4 -o trimmed.mp4
```

## Smooth the cuts with dissolves

Blend each kept section into the next instead of jump-cutting, with a fade in
at the start and a fade out at the end:

```sh
auto-editor video.mp4 --transition dissolve:0.5sec
```

By default, cuts that removed less than a second of material stay hard so
short silence trims don't stutter. Use `:0` to dissolve at every cut:

```sh
auto-editor video.mp4 --transition dissolve:0.5sec:0
```

Transitions survive editor exports too — see [Transitions](./transition).

## Record and edit a microphone

Use `:mic` in place of an input file to capture from a microphone. Press
Ctrl-C when you are done recording; auto-editor will then remove the quiet
sections and write `mic_ALTERED.wav`:

```sh
auto-editor :mic
```

All normal editing and output options apply. For example:

```sh
auto-editor :mic --edit audio:threshold=6% -o trimmed.m4a
```

Use `--sample-rate` to resample the recording before it is edited:

```sh
auto-editor :mic --sample-rate 44.1kHz
```

Timeline and editor exports save the microphone capture as a lossless FLAC
stream in `*_RECORDING.mka`. Use `-c:a` to choose a different codec supported
by Matroska:

```sh
auto-editor :mic --export resolve -c:a opus -o interview.fcpxml
```

Live microphone capture is supported on macOS, Windows, and Linux. Timeline
and editor exports keep the original capture in a sibling
`*_RECORDING.mka` file so the exported project can still reference it.

## Look before you render

See how much will be cut without producing a file yet:

```sh
auto-editor video.mp4 --preview
```

## Make the pace feel natural

By default auto-editor keeps `0.2` seconds of padding around each kept section
so cuts don't feel abrupt. Widen it to let speech breathe, or use different
padding before and after:

```sh
# 0.5 seconds of padding on both sides
auto-editor video.mp4 --margin 0.5sec

# 0.3s before, 1.5s after
auto-editor video.mp4 --margin 0.3sec,1.5sec
```

## Cut more (or less) aggressively

`--edit` decides what counts as "loud enough" to keep. Raise the threshold to
cut more, lower it to keep more. You can use a percentage or a `dB` value:

```sh
# Keep only louder audio (cuts more)
auto-editor video.mp4 --edit audio:threshold=6%

# The same idea in decibels
auto-editor video.mp4 --edit audio:-18dB
```

To analyze one channel instead of the loudest sample across all channels, use
its layout name:

```sh
auto-editor video.mp4 --edit audio:channel=left
```

Channel names are layout-aware (`left`, `right`, `center`, `lfe`,
`back-left`, and so on). A mono channel acts as left, right, and center. With
`stream=all`, streams without the requested channel are skipped as long as at
least one stream contains it.

## Cut by motion instead of sound

Useful for screen recordings or silent footage — drop the still parts:

```sh
auto-editor video.mp4 --edit motion:threshold=2%
```

## Speed through silence instead of cutting it

Keep every moment, but fast-forward the quiet parts:

```sh
auto-editor video.mp4 -w:0 speed:8
```

See the [Actions Cookbook](./actions) for volume, zoom, overlays, and more.

## Trim the beginning or end

```sh
# Drop the first and last 30 seconds, on top of the automatic edit
auto-editor video.mp4 --cut-out start,30sec -30sec,end
```

More in [Range Syntax](./range-syntax).

## Edit by what was said

Transcribe speech, then cut on the words. First make subtitles, then edit with
them:

```sh
auto-editor whisper video.mp4 ggml-medium.en.bin --format srt -o video.srt
auto-editor video.mp4 --edit subtitle
```

Auto-Editor understands `video.srt` is related to `video.mp4`. See the [whisper command](./subcommands/whisper) for more details.

## Hand off to your video editor

Instead of rendering, export a project you can open in your editor:

```sh
auto-editor video.mp4 --export premiere
```

Auto-editor can also export to `resolve`, `final-cut-pro`, `shotcut`, and
`kdenlive`. To get each kept section as its own file, use `clip-sequence`:

```sh
auto-editor video.mp4 --export clip-sequence
```

## Edit straight from a URL

If [yt-dlp](https://github.com/yt-dlp/yt-dlp) is installed, pass a link as the
input:

```sh
auto-editor "https://www.youtube.com/watch?v=kcs82HnguGc"
```

## See Also
- [How to Shrink File Size](./file-size)
- [All the Options (and What They Do)](/ref/options)

<a class="next" href="./actions">Next: Actions Cookbook</a>

---

### Src Docs File Size (`docs/src/docs/file-size.md`)

---
title: How to Shrink File Size
---

## Auto-Editor Makes Files That Are Too Big!
This is generally good since auto-editor tries to preserve video quality as much as possible. However, there are tricks you can use to shrink file size with little to no quality loss.

## Video Bitrate
Change the video bitrate to a lower value. By default, the video bitrate is set to `auto`, which lets the encoder choose. The encoder might set a bitrate too high for your liking, so you can set it manually based on the file size you expect.

Assuming the video is 2 minutes, the video stream will be about 27,600 kbits (2 * 60 * 230), or about 3.45 MB, not including audio size.
```sh
auto-editor my-video.mp4 -b:v 230k
```

Examples:
```sh
auto-editor my-huge-h264-video.mp4 -b:v 10M  # Maximum quality, big file size
auto-editor my-h264-video.mp4 -b:v auto  # Let ffmpeg chose, efficient and good looking quality
auto-editor i-want-this-tiny.mp4 -b:v 125k  # Set bitrate to 125 kilobits per second, quality may vary
auto-editor my-video.mp4 -c:v h264 -b:v 0  # Set a variable bitrate
```

## Audio Streams
Your audio contributes to size too, if you use the AAC encoder, it should always be a reasonable size.

| Encoder               | Type             | Quality   | Speed     |
|-----------------------|------------------|-----------|-----------|
| opus (libopus)        | Software         | best      | fast      |
| aac (ffmpeg 9+)       | Software         | excellent | fast      |
| fdk_aac               | Software         | great     | fast      |
| aac_at (AudioToolBox) | Hardware (Apple) | good      | very fast |
| aac (ffmpeg <9)       | Software         | meh       | fast      |

## Using Better Video Encoders
Your file size depends on the encoder used. h264 is great but not the best. hevc (also known as h265) can achieve much smaller sizes with about the same quality. One trade-off is that various software, such as media players and NLEs, doesn't understand next-gen encoders.

The table below compares different video codecs:

| Codecs  | Compression | Encoder Speed | Compatibility |
|---------|-------------|---------------|---------------|
| h264    | high        | very fast     | best          |
| hevc    | very high   | fast          | high          |
| av1     | very high   | fast          | high          |
| vp9     | very high   | meh           | high          |
| gif     | okay to bad | superfast     | high          |
| mpeg4   | very low    | superfast     | so-so         |
| av2     | super       | fast?         | experimental  |
| vvc     | super       | fast?         | experimental  |

Auto-Editor's static builds do not include AV2 or VVC encoders.

Example:
```sh
ffmpeg -i my-video.mp4 -c:a copy -c:v hevc -b:v 0 my-video-h265.mp4
```

<a class="next" href="./subcommands">Next: Subcommands</a>

---

### Src Docs Range Syntax (`docs/src/docs/range-syntax.md`)

---
title: Range Syntax
---

## How Do I Cut the Beginning or End Segment in My Video?

Range syntax is useful for making manual edits in addition to automatic edits. Here's how you cut out the first and last 30 seconds:
```sh
auto-editor video.mp4 --cut start,30sec -30sec,end
```

You can also guarantee those sections would be included, regardless of loudness with:
```sh
auto-editor video.mp4 --keep start,30sec -30sec,end
```

## How Range Syntax Works
The `--keep`, `--cut`, `--set-speed`, and `--set-action` options all use time range syntax.

It describes two numbers, the start and end point, separated by a singe comma `,`. The start number is inclusive, while the end number is exclusive.

```sh
# This will cut out the first frame: frame 0
auto-editor example.mp4 --cut 0,1

# This will cut out five frames: frames 0, 1, 2, 3, 4
# frame 5 will still exist because the end point is exclusive
auto-editor example.mp4 --cut 0,5

# Cuts out 60 frames
auto-editor example.mp4 --cut 10,70
```

## Variables
Time range syntax allows two variables: `start` and `end`
`start` is the same as `0`
`end` is the length of the timeline before any edits are applied.

```sh
# This will cut out everything in the beginning
auto-editor example.mp4 --cut start,300

# This will keep everything besides the beginning, overriding other edits
auto-editor example.mp4 --keep 300,end

# This will cut out everything
auto-editor example.mp4 --cut start,end
```

## Units
The default unit is the timeline's timebase. Since specifying the range in this unit can sometimes be annoying. You can use the `sec` unit to specify the range in seconds. (Note that the seconds range will be rounded to the nearest timebase to you don't have any more precision than usual).

```sh
# Cut out the first 10 seconds.
auto-editor example.mp4 --cut start,10secs
```
You can also use `s`, `sec`, `second`, or `seconds`, depending on your preference.

## Negative Indexes
Negative numbers can be used to count down starting from the end.
 * `-60,end` selects the last 60 frames
 * `1sec,-30secs` selects from the first second, to the last 30 seconds from the end.

## Speed for Range
The `--set-speed-for-range` option has a slight twist on time range syntax. It accepts three numbers. `speed`, `start`, and `end`, separated by commas. `speed` can be a decimal number, but not negative. `start` and `end` work as described above.

```sh
# Set the speed to 2x from frame 0 to frame 29
auto-editor example.mp4 --set-speed-for-range 2,0,30

# Set the speed to 0.5x
auto-editor example.mp4 --set-speed-for-range 0.5,start,end
```

<a class="next" href="./file-size">Next: File Size</a>

---

### Src Docs Supported Media (`docs/src/docs/supported-media.md`)

---
title: Supported Media
---

Auto-Editor supports a wide range of media formats thanks to ffmpeg. Listed below is what is and is not allowed.

## What's allowed
 * Media with only audio streams
 * Media with only video streams
 * Media with video, audio, subtile, embedded images, and data streams
 * Media with over 1000 streams

## What isn't
 * Media with only subtitle/data streams.
 * Media with video or audio streams longer than 24 hours
 * Video streams whose total number of frames exceeds a 60fps 24 hour video
 * Audio streams whose total number of samples exceeds a 192kHz 24 hour video

Using specific codecs/containers depends on which ffmpeg program auto-editor uses.

---
### Footnotes
The terms "stream" and "track" are used interchangeably.

---

### Src Docs Transition (`docs/src/docs/transition.md`)

---
title: Transitions
---

Transitions smooth over the cuts auto-editor makes. Instead of a hard jump
from one kept section to the next, the two sections blend into each other
with a cross-dissolve, and the timeline fades in at the start and fades out
at the end.

## Basic Syntax

```sh
# 1 second dissolves at eligible cuts, plus fades at the timeline ends
auto-editor video.mp4 --transition dissolve:1sec
```

The full form is `dissolve:DURATION[:MIN-CUT]`:

- `DURATION` — how long each transition lasts. Accepts the usual time units
  (`0.5sec`, `20` for a bare frame count, etc.).
- `MIN-CUT` — skip cuts whose *removed source interval* is shorter than this
  (default: `1sec`). Dissolving across a tiny silence trim reads as a stutter,
  so short cuts stay hard by default. Use `0` to dissolve at every cut:

```sh
auto-editor video.mp4 --transition dissolve:1sec:0
```

Dissolves are linked: video cross-dissolves and audio cross-fades cover the
same span. A dissolve needs source material on both sides of the cut
(the material that was cut out serves as the handle), so a transition may be
shortened or skipped when a clip is too short to support it.

## Where transitions survive

The native render and every editor export carry transitions:

| Export | Result |
|---|---|
| default (rendered media) | Rendered directly |
| `v3` | Stored in the `transitions` key |
| `premiere`, `resolve-fcp7` (FCP7 XML) | Cross Dissolve / Cross Fade transition items |
| `premiere-otio` | `SMPTE_Dissolve` transitions |
| `final-cut-pro`, `resolve` (FCPXML) | Cross Dissolve spine transitions |
| `shotcut` | Same-track transitions (luma + mix), fade filters at the ends |
| `kdenlive` | Same-track mixes, fade filters at the ends |

## Where transitions are dropped

- `v1` and `v2` timeline files have no way to represent transitions; exporting
  to them silently drops the transitions and keeps the cuts.
- `clip-sequence` does not carry transitions **by design**: it renders each
  kept section as an independent media file, and a cross-dissolve has no
  meaning between separate files.

---

### Src Docs V1 (`docs/src/docs/v1.md`)

---
title: The v1 format
---

## Overview
The v1 format is the simplest way to represent a timeline. It supports cutting and changing speed from `0.0` to `99999.0` inclusive. v1 is a stable format. Developers are welcome to use it to make cuts for auto-editor and to use it for their own programs.

You can generate a v1 timeline file with `auto-editor example.mp4 --export v1` and it would look something like this:

```json
{
  "version": "1",
  "source": "example.mp4",
  "timebase": "30/1",
  "chunks": [
    [0, 26, 1],
    [26, 34, 0],
    [34, 396, 1],
    [396, 410, 0],
    ...
  ],
}
```
v1 is a subset of [JSON](https://www.json.org/). `...` is used to show that a variable amount of elements are allowed.


Auto-Editor can use the v1 format as input:
```sh
auto-editor input.v1 -o output.mkv
```

## Limitations
Only a single file (source) is allowed. Additionally, v1 only supports "linear" timelines. That means sections further in the media cannot be put ahead in the timeline than sections before.

v1 cannot represent [transitions](./transition); exporting a timeline that has them drops the transitions and keeps the cuts.

## The Spec
There are only three keys that are required: `"version"`, `"source"`, and `"chunks"`. The `"timebase"` key is optional. If there are more keys present in the JSON, the parser should ignore them.

Shown using TypeScript notation, the keys can be set to the following values.
```ts
interface v1 {
  version: "1";      // Must always be set as "1".

  source: string;    // Path to a media file. The path can be relative or absolute,
                     // but must be valid for the given platform.

  timebase?: string; // Optional. The timebase as a rational number, e.g. "30/1"
                     // or "30000/1001". If absent, it is derived from the source.

  chunks: Chunk[];   // We'll cover this in the next section.
}
```

## Chunks
Each `Chunk` element has 3 parts:
 * start: When from the media to start playing
 * end: When from the media to stop playing
 * speed: How fast to play (or cut) the section.

`start` (inclusive) and `end` (exclusive) represent a time range: selecting a segment from the original source. There is no hard limit how big `start` and `end` can be.

The speed 1.0 means to play the media at its normal rate. The speeds 99999.0 and 0.0 always mean to cut a section out.

It is valid for `chunks` to be an empty array. The first `chunk` must start with 0. All other `chunk`s must have their `start` set be the preceding `end`'s value (there can be no gaps).

## The Timebase
`start` and `end` are in the timebase unit. Timebase determines how much actual time a length occurs.

If the `timebase` key is present, it sets the timebase directly. For example, with `"timebase": "30/1"` a chunk of `[0, 1, 1.0]` has a length of 1/30 of a second.

If the key is absent, the timebase is derived from the source: the average framerate of its video track, snapped to a common rate when it is close to one (for example, `29.97` becomes `30000/1001`). If the source has no video track, `30/1` is used. Older files without the key remain valid.

## See Also
If you need more than v1 can express, there's also [the v2 format](./v2). Instead of a `speed` per chunk, v2 uses an explicit `tb` (timebase) and a list of `clips` that reference `effects`, so you can apply actions beyond just changing speed. It's still a single-source, linear format.

---

### Src Docs V2 (`docs/src/docs/v2.md`)

---
title: The v2 format
---

## Overview
The v2 format is a linear timeline format, like [v1](./v1), but instead of a single `speed` value per section it lets each section reference a group of [actions](./actions) (speed, volume, zoom, etc.). It also records an explicit timebase, so it does not need to probe the source for its framerate.

Like v1, v2 only supports a single source and a "linear" timeline: sections must be laid down in order, and sections later in the source cannot be placed ahead of earlier ones. Like v1, it cannot represent [transitions](./transition); exporting drops them and keeps the cuts.

You can generate a v2 timeline file with `auto-editor example.mp4 --export v2` and it would look something like this:

```json
{
  "version": "2",
  "source": "example.mp4",
  "tb": "30/1",
  "effects": [
    [],
    ["speed:2.0"]
  ],
  "clips": [
    [0, 26, 0],
    [34, 396, 1]
  ]
}
```
v2 is a subset of [JSON](https://www.json.org/). Here, the range `26`–`34` is cut simply because no clip covers it; the second clip plays `34`–`396` at 2x speed.

Auto-Editor can use the v2 format as input:
```sh
auto-editor input.v2 -o output.mkv
```

## The Spec
There are four required keys: `"version"`, `"source"`, `"tb"`, and `"effects"`, plus `"clips"`. If there are more keys present in the JSON, the parser should ignore them.

shown using TypeScript notation, the keys can be set to the following values.
```ts
interface v2 {
  version: "2";      // Must always be set as "2".

  source: string;    // Path to a media file. The path can be relative or absolute,
                     // but must be valid for the given platform.

  tb: string;        // The timebase as a rational number, e.g. "30/1" or "30000/1001".

  effects: Effect[]; // The table of effects that clips reference by index.

  clips: Clip[];     // The sections of the source to lay down, in order.
}
```

## Effects
`effects` is an array of effect groups. A `Clip` refers to one of these by its index in this array.

```ts
type Effect = string[]; // A list of action strings.
```

Each effect group is a list of [action](./actions) strings:
 * `[]` — an empty list means "do nothing"; play the section unaltered at normal speed.
 * `["cut"]` — cut the section out (don't include it).
 * `["speed:2.0"]`, `["volume:0.5"]`, ... — apply one or more actions. Each string is an action name with its arguments, the same syntax used by `--set-action`.

## Clips
Each `Clip` is a 3-element array:

```ts
type Clip = [start: number, end: number, effect: number];
```

 * `start` (inclusive) and `end` (exclusive) select a time range from the source, in timebase units.
 * `effect` is an index into the `effects` array.

Clips are processed in order. Each non-cut clip is appended to the end of the timeline, so the output is the concatenation of all the selected (non-cut) ranges. Cutting a range out is normally done by simply not covering it with a clip (leaving a gap), but you can also point a clip at a `["cut"]` effect to the same end.

## The Timebase
`start` and `end` are in the timebase unit set by `tb`. For example, with `"tb": "30/1"` a clip of `[0, 1, 0]` has a length of 1/30 of a second.

## See Also
[The v1 format](./v1) is simpler if you only need cutting and a single speed per section. [The v3 format](./v3) is nonlinear and supports multiple sources and overlapping layers.

---

### Src Docs V3 (`docs/src/docs/v3.md`)

---
title: The v3 format
---

## Overview
The v3 format is a nonlinear timeline file format. It supports multiple overlapping video and audio layers. The v3 format is a subset of [JSON](https://www.json.org/), and the proper extension is `.v3`.

Auto-Editor can generate v3 timelines from media files (instructed with `--edit`),
```sh
auto-editor example.mp4 --export v3 -o input.v3
```

render media files from the v3 format,
```sh
auto-editor input.v3 -o output.mkv
```

and translate other timeline formats to v3:
```sh
auto-editor input-fcp7.xml --export v3 -o output.v3
```

## Stability
This format is considered partially-stable. Breaking changes can be made to feature level changes, but not patch level changes.

## The Spec
shown using TypeScript notation, the format can be described:

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Compositing layers
When more than one video track has a clip active at the same timeline frame, the tracks are composited bottom-to-top: `v[0]` is the base layer and later tracks (`v[1]`, `v[2]`, ...) are painted on top. The base layer fills the canvas (its source is fit to `resolution`). Each higher layer is placed by a `pos:x:y[:scale]` effect in its `effects` array — `x`/`y` are the top-left corner in canvas pixels and `scale` (default `1.0`) multiplies the source's native size. Without a `pos` effect, an overlay is scaled to fit the canvas (preserving aspect ratio) and centered, like a full-frame layer. Other per-clip `effects` are applied to each clip before it is composited.

Still images (PNG, JPG, BMP, TIFF, ...) may be used as a `src`; the single image is held for the clip's whole `dur`, which is convenient for logos and watermarks. Overlay transparency (e.g. a PNG alpha channel) is preserved.

```json
"v": [
  [ { "src": "example.mp4", "start": 0, "dur": 60, "offset": 0, "stream": 0 } ],
  [ { "src": "pip.mp4", "start": 0, "dur": 60, "offset": 0, "stream": 0, "effects": ["pos:900:60:0.25"] } ],
  [ { "src": "logo.png", "start": 0, "dur": 60, "offset": 0, "stream": 0, "effects": ["pos:40:40"] } ]
]
```

For best results, the base track (`v[0]`) should span every frame you intend to render; a frame where only a higher track is active is treated as a single full-frame layer.

## Effects
A clip may carry an optional `effects` key: an array of action strings applied to that clip. Each string is either a bare action like `"invert"` or an action with arguments like `"speed:8.0"`, `"volume:0.5"`, or `"zoom:2.0"`. The single-element array `["cut"]` means the clip is cut (not included). When `effects` is absent, the clip plays unaltered at normal speed. See the [Actions reference](/ref/actions) for the full list.

The v3 format looks something like this:
```json
{
  "version": "3",
  "templateFile": "example.mp4",
  "timebase": "30/1",
  "background": "#000",
  "resolution": [1280, 720],
  "samplerate": 48000,
  "layout": "stereo",
  "langs": ["eng", "eng"],
  "v": [
    [
      {
        "src": "example.mp4",
        "start": 0,
        "dur": 26,
        "offset": 0,
        "stream": 0
      },
      {
        "src": "example.mp4",
        "start": 26,
        "dur": 362,
        "offset": 34,
        "stream": 0
      }
    ]
  ],
  "a": [
    [
      {
        "src": "example.mp4",
        "start": 0,
        "dur": 26,
        "offset": 0,
        "stream": 0
      },
      {
        "src": "example.mp4",
        "start": 26,
        "dur": 362,
        "offset": 34,
        "stream": 0
      }
    ]
  ]
}
```

---

### Src Ref Actions (`docs/src/ref/actions.md`)

---
title: Actions Reference
---

{{ exec gen_actions.nims }}

---

### Src Ref Options (`docs/src/ref/options.md`)

---
title: Options
---

{{ exec gen_options.nims }}

---

### Src Docs Subcommands Cache (`docs/src/docs/subcommands/cache.md`)

---
title: cache
---

The `cache` command stores the `audio` and `motion` levels, saving time at the cost of space. The cache will go up to 10 entires, and will delete the oldest after.


## Examples
To list the cache files:

```sh
auto-editor cache
```

To remove the cache files:

```sh
auto-editor cache clear
```

<a class="next" href="./desc">Next: desc</a>

---

### Src Docs Subcommands Desc (`docs/src/docs/subcommands/desc.md`)

---
title: desc
---

`desc` displays the video's description. If there is none, `No description.` will be displayed.

Examples:

```
% yt-dlp --add-metadata -f "bestvideo[ext=mp4]" "https://www.youtube.com/watch?v=jNQXAC9IVRw" -o out.mp4
% auto-editor desc out.mp4

Chapters:

00:00 Intro
00:05 The cool thing
00:17 End

Interesting.... https://www.youtube.com/watch?v=VaLXzI92t9M
```

```
% auto-editor desc example.mp4

No description.
```

<a class="next" href="./info">Next: info</a>

---

### Src Docs Subcommands Info (`docs/src/docs/subcommands/info.md`)

---
title: info
---

`info` is a utility program that displays media information relevant to auto-editor.

Here is an example. Note that you can use multiple files at once.
```
auto-editor info example.mp4 resources/only-video/man-on-green-screen.gif

example.mp4:
 - recommendedTimebase: 30/1
 - video:
   - track 0:
     - codec: h264
     - fps: 30
     - resolution: 1280x720
     - aspect ratio: 16:9
     - pixel aspect ratio: 1
     - duration: 42.4
     - pix fmt: yuv420p
     - color range: 1 (tv)
     - color space: 1 (bt709)
     - color primaries: 1 (bt709)
     - color transfer: 1 (bt709)
     - timebase: 1/30000
     - bitrate: 240958
     - lang: eng
 - audio:
   - track 0:
     - codec: aac
     - layout: stereo
     - samplerate: 48000
     - duration: 42.4
     - bitrate: 317375
     - lang: eng
 - container:
   - duration: 42.4
   - bitrate: 570335

resources/only-video/man-on-green-screen.gif:
 - recommendedTimebase: 3333/100
 - video:
   - track 0:
     - codec: gif
     - fps: 100/3
     - resolution: 1280x720
     - aspect ratio: 16:9
     - pixel aspect ratio: 64/64
     - duration: 24.41
     - pix fmt: bgra
     - timebase: 1/100
 - container:
   - duration: 24.41
   - bitrate: 1649917
```

The default format is pseudo-yaml meant for humans. You can get a machine friendly output with the `--json` option.

```
auto-editor info example.mp4 --json

{
  "example.mp4": {
    "type": "media",
    "recommendedTimebase": "30/1",
    "video": [
      {
        "codec": "h264",
        "fps": "30",
        "resolution": [
          1280,
          720
        ],
        "aspect_ratio": [
          16,
          9
        ],
        "pixel_aspect_ratio": "1",
        "duration": 42.4,
        "pix_fmt": "yuv420p",
        "color_range": 1,
        "color_space": 1,
        "color_primaries": 1,
        "color_transfer": 1,
        "timebase": "1/30000",
        "bitrate": 240958,
        "lang": "eng"
      }
    ],
    "audio": [
      {
        "codec": "aac",
        "layout": "stereo",
        "samplerate": 48000,
        "duration": 42.4,
        "bitrate": 317375,
        "lang": "eng"
      }
    ],
    "subtitle": [],
    "image": [],
    "container": {
      "duration": 42.4,
      "bitrate": 570335
    }
  }
}
```

<a class="next" href="./levels">Next: levels</a>

---

### Src Docs Subcommands Levels (`docs/src/docs/subcommands/levels.md`)

---
title: levels
---

`levels` displays individual "edit method" stream values before the threshold procedure (if any) is applied. It mainly exists to be used by other programs so they can build on auto-editor's media analysis.

Because typical levels output is so long, it won't be displayed verbatim.

```
auto-editor levels example.mp4

@start
0.00008813678829543451
0.00026441036488630354
0.00026441036488630354
0.00017627357659086903
0.00775603736999823726
0.04794641283271637577
0.14604265820553499755
0.44368059227921735621
0.52362065926317646891
0.46201304424466771437
0.47611493037193725053
0.51427815970386037137
0.86162524237616777700
0.76291203948528119039
0.70853164110699806688
(Continues for 1000 more lines)
0.18905341089370703012
0.02793936188965273973
0.01401374933897408734
0.01189846641988365900
0.00493566014454433280
0.00317292437863564251
0.00105764145954521417
0.00008813678829543451
0.00008813678829543451
0.00000000000000000000
0.00000000000000000000
(30 more lines)
0.00000000000000000000
0.00000000000000000000
0.00000000000000000000
0.00000000000000000000

```

levels uses `--edit` to determine what is being analyzed, which by default is `audio`.

<a class="next" href="./subdump">Next: subdump</a>

---

### Src Docs Subcommands Subdump (`docs/src/docs/subcommands/subdump.md`)

---
title: subdump
---

`subdump` is a utility program that displays the textual representation of subtitle streams in media files.

Here's an example:

```
auto-editor subdump resources/subtitle.mp4

file: resources/subtitle.mp4 (0:und:srt)
1
00:00:00,523 --> 00:00:01,016
oop

2
00:00:01,523 --> 00:00:01,916
boop


------
```

subdump won't work if the subtitle stream is internally represented as a bitmap image instead of formatted text.

<a class="next" href="./whisper">Next: whisper</a>

---

### Src Docs Subcommands Whisper (`docs/src/docs/subcommands/whisper.md`)

---
title: whisper
---

`whisper` transcribes the audio of a media file using [whisper.cpp](https://github.com/ggerganov/whisper.cpp) `ggml` models. It is useful both on its own and for generating subtitles that `--edit subtitle` can then cut on.

Usage:
```
auto-editor whisper <file> <model> [options]
```

`<model>` is a path to a `ggml` whisper model. You can download them from [huggingface.co/ggerganov/whisper.cpp](https://huggingface.co/ggerganov/whisper.cpp).

Example:
```
% auto-editor whisper example.mp4 ggml-medium.en.bin

 And so my fellow Americans, ask not what your country can do for you,
 ask what you can do for your country.
```

By default the transcript is written to stdout as plain text. Use `--output` to write to a file and `--format` to choose the representation:
```sh
auto-editor whisper example.mp4 ggml-medium.en.bin --format srt -o out.srt
```

## Options

### `<file>`
The input media file. Only the first audio stream is used; the audio is resampled to 16kHz (whisper's preferred rate) before transcription.

### `<model>`
Path to a `ggml` whisper model, e.g. `ggml-small.en.bin` or `ggml-large-v2.bin`.

### `-l, --language LANG`
Set the spoken language instead of letting whisper auto-detect it. Examples: `en`, `ja`. (default `auto`)

### `--format FORMAT`
Set the output format. Choices are `text`, `srt`, and `json`. (default `text`)

### `-o, --output FILE`
Where to write the transcript. (defaults to stdout)

### `-tr, --translate`
Translate from the source language to English.

### `-sw, --split-words`
Split the output so that each token is at most one word long.

### `--queue SECS`
The maximum amount of audio (in seconds) queued before processing. Must be between 1 and 86400. (default 30)

### `--vad-model VAD-MODEL`
Set a Voice Activity Detection (VAD) model.

### `--threads N`
Number of CPU threads to use for whisper processing. (default 4)

---
### Notes
The `whisper` filter must be enabled in the ffmpeg auto-editor is using. If it isn't, whisper will report that it `Could not find whisper filter`.

<a class="next" href="/docs/v1">Next: The v1 timeline format</a>

---

--- METRICS ---
- Files Extracted: 26
- Estimated Token Budget: ~15357 tokens
- Canonical Reference: https://codewiki.google/github.com/WyattBlue/auto-editor
