# Opus

Canonical URL: https://encode.wiki/codecs/audio/opus/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): f9105752d54c46a4476df916bc0aed6e878cd1103c2bc7865b2cda8ca1354ef3

Opus is an open, royalty-free lossy audio codec standardised as [RFC 6716](https://datatracker.ietf.org/doc/rfc6716/). It combines Skype's SILK (speech) and Xiph's CELT (general audio) and switches between them automatically, so one codec covers voice calls, podcasts and music. It is the default recommendation for lossy audio unless you need MP4/Apple-device compatibility, where [AAC](/codecs/audio/aac/) is still the safe choice. For web video it is the standard companion to [VP9](/codecs/video/vp9/) and [AV1](/codecs/video/av1/) in WebM.

At the same bitrate Opus generally sounds better than AAC-LC, Vorbis and MP3, and it stays usable far lower. Stereo music is near-transparent at around 128 kbit/s VBR. It is lossy: encode from the lossless original, never from another lossy file.

## Recommended bitrates

Bitrates are for the whole stream, not per channel. These are the [Xiph recommended settings](https://wiki.xiph.org/Opus_Recommended_Settings):

| Content | Channels | kbit/s |
| --- | --- | --- |
| Voice over IP | Mono | 10–24 |
| Podcast / audiobook | Mono | 24 |
| Podcast / audiobook | Stereo | 32 |
| Music streaming | Stereo | 64–96 |
| Music archive / storage | Stereo | 96–128 |
| Music | 5.1 | 128–256 |
| Music | 7.1 | 256–450 |

Below about 19 kbit/s the encoder starts folding stereo to mono. Opus covers 6–510 kbit/s. For archiving, keep a lossless copy ([FLAC](/codecs/audio/flac/)) instead.

## Encoding with opusenc

`opusenc` (from [opus-tools](https://gitlab.xiph.org/xiph/opus-tools)) is the reference encoder. Its defaults are already the right ones for stored audio: VBR, complexity 10, 20 ms frames, automatic speech/music detection. It reads WAV, AIFF and FLAC and resamples 44.1 kHz material itself.

```sh
opusenc --bitrate 128 input.flac output.opus
opusenc --speech --downmix-mono --bitrate 24 interview.wav interview.opus
```

`--bitrate` is in kbit/s, unlike FFmpeg's bit/s. `--speech` and `--music` override the automatic speech/music detection and only matter at low bitrates. `--cvbr` and `--hard-cbr` exist for transports with a strict rate limit; leave VBR on for files.

## Encoding with FFmpeg

```sh
ffmpeg -i input.flac -c:a libopus -b:a 128k output.opus
```

Everything else defaults sensibly: `-vbr on`, `-application audio`, 20 ms frames, complexity 10. The options worth knowing:

| Option | Use |
| --- | --- |
| `-application voip` | Speech intelligibility tuning for voice recordings. `audio` (default) is right for music; `lowdelay` is only for real-time work. |
| `-vbr constrained` | Limits rate swings for streaming. `-vbr off` is hard CBR. |
| `-frame_duration` | Leave at 20. Longer frames only help at very low bitrates; shorter ones cost quality and are for latency. |
| `-mapping_family 1` | Surround layouts, see below. |
| `-ac 1` | Mono downmix for speech. |

`-q:a` is not supported by `libopus`; control quality with `-b:a`. `-packet_loss` and `-fec` are for real-time links and do nothing useful in a stored file.

### Sample rate

Opus works at 48 kHz internally, and players and FFmpeg decode to 48 kHz (8, 12, 16 and 24 kHz are also accepted as input rates). A 44.1 kHz source is resampled by `opusenc` or FFmpeg automatically; do not force `-ar 44100`. The original rate is stored only as informational metadata. Audible bandwidth tops out around 20 kHz regardless of the input rate.

### Surround

Opus carries mono and stereo directly (mapping family 0). For 3–8 channels it uses mapping family 1, which defines the channel order and enables surround-specific bit allocation. FFmpeg writes a family 1 header by default but only uses libopus's surround-aware encoder when you ask for it:

```sh
ffmpeg -i surround.mkv -c:a libopus -b:a 256k -mapping_family 1 output.mka
```

`libopus` rejects the `5.1(side)` layout that many Blu-ray and AC-3 sources use ("Invalid channel layout 5.1(side) for specified mapping family"). Convert it to plain 5.1 first:

```sh
ffmpeg -i input.mkv -af aformat=channel_layouts=5.1 -c:a libopus -b:a 256k -mapping_family 1 output.mka
```

`aformat` relabels the side channels as back channels; nothing is downmixed. `-af` applies to every audio output stream, so when a command encodes several audio tracks, target the surround one with `-filter:a:N` instead (see [audio and subtitles](/guides/audio-and-subtitles/)). To handle unknown inputs in one command, offer several layouts and let FFmpeg pick the closest: `-af aformat=channel_layouts=7.1|5.1|stereo -mapping_family 1`. More than 8 channels needs mapping family 255 (unmapped channels), which most players will not render as surround.

`opusenc` handles 5.1 WAV files directly.

### FFmpeg's native encoder

FFmpeg also has its own `opus` encoder (CELT-only, mono/stereo, 48 kHz). It is experimental, needs `-strict -2`, and is not better than libopus; the only reason to reach for it is a build without libopus.

## Containers and playback

**Opus container mappings**

| Relationship | Project or format | Evidence and scope | Status |
| --- | --- | --- | --- |
| Carried By | [Ogg](/containers/ogg/) | Ogg Opus uses OpusHead and OpusTags headers with 48 kHz granule-position semantics. Scope: Container Mapping. Sources: [RFC 7845: Ogg Encapsulation for the Opus Audio Codec](https://datatracker.ietf.org/doc/rfc7845/). | Normative |
| Carried By | [Matroska](/containers/matroska/) | Uses the A_OPUS Codec ID and stores the Opus identification header in CodecPrivate. Scope: Container Mapping. Sources: [Matroska codec mappings](https://www.matroska.org/technical/codec_specs.html). | Normative |
| Carried By | [WebM](/containers/webm/) | Opus is one of the audio codecs listed by the WebM Project. Scope: Container Mapping. Sources: [WebM container guidelines](https://www.webmproject.org/docs/container/). | Documented |
| Carried By | [ISO Base Media File Format](/containers/isobmff/) | The public Opus binding defines the Opus sample entry and dOps box, but remains an old incomplete draft. Scope: Container Mapping. Sources: [Encapsulation of Opus in ISO Base Media File Format](https://www.opus-codec.org/docs/opus_in_isobmff.html), [MP4 Registration Authority codec registry](https://mp4ra.org/registered-types/codecs). | Registered |

[Open the complete typed relationship catalog](/api/v1/catalog.json).

- **Ogg Opus** (`.opus`, [RFC 7845](https://datatracker.ietf.org/doc/rfc7845/)) is the standard file format for audio. Safari supports it from 18.4 (macOS 15.4, iOS 18.4).
- **WebM / Matroska** is the usual choice with video; `-c:a copy` between them is lossless.
- **MP4** can carry Opus, but player support is patchier than for the other two.

Opus is also one of the codecs IAMF/Eclipsa Audio can use; see [spatial audio](/codecs/audio/spatial-audio/#iamf-and-eclipsa-audio).

## Full option reference

Every option of `opusenc` 0.2 (with libopus 1.6.1 and libopusenc 0.3) and of FFmpeg 9.0.2's two Opus encoders. Defaults are what you get when the option is omitted.

### Complete `opusenc` 0.2 parameter reference

#### Rate, signal, and latency

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `--bitrate N` | Auto: 64 kbit/s mono, 96 stereo | kbit/s for the whole stream, decimals allowed; 6–256 per channel is the useful range | Target bitrate. The automatic value is 64 kbit/s per stream plus 32 per coupled pair (5.1 gets 320), scaled down for inputs below 44.1 kHz (16 kHz mono gets 33). Capped at 256 kbit/s per channel. |
| `--vbr` | On | Flag | Unconstrained VBR: the bitrate follows the content around the target. The right mode for files. |
| `--cvbr` | Off | Flag | Constrained VBR: packet sizes vary but stay close to the target, like CBR with a small reservoir. For streaming over constant-rate links. |
| `--hard-cbr` | Off | Flag | Every packet the same size, at a quality cost. Only for transports that need it. The last of `--vbr`, `--cvbr` and `--hard-cbr` wins. |
| `--music` | Auto-detected | Flag | Treat the input as music, overriding speech/music detection. Mainly matters at low bitrates. |
| `--speech` | Auto-detected | Flag | Treat the input as speech, favouring the SILK modes at low bitrates. The last of `--music` and `--speech` wins. |
| `--comp N`, `--complexity N` | `10` | `0`–`10` | Encoder effort; 10 is slowest and best. Lower it only for real-time encoding on weak CPUs. |
| `--framesize N` | `20` | `2.5`, `5`, `10`, `20`, `40`, `60` ms | Maximum frame duration. 20 ms suits almost everything; 40 or 60 ms save a little overhead for low-bitrate speech. Frames under 10 ms can only use CELT and cost efficiency. |
| `--expect-loss N` | `0` | `0`–`100` % | Expected packet loss. Makes frames more robust to loss at some quality cost. It does not turn on in-band FEC; add `--set-ctl-int 4012=1` for that. |
| `--downmix-mono` | Off | Flag | Downmix to mono before encoding. |
| `--downmix-stereo` | Off | Flag | Downmix inputs with more than two channels to stereo. |
| `--no-downmix` | Off | Flag | Disable the automatic downmix: with more than two channels and `--bitrate` below 16 kbit/s per channel, opusenc otherwise downmixes to stereo (3–8 channels) or mono (more than 8). Not listed by `--help`. |
| `--no-phase-inv` | Off | Flag | Disable intensity-stereo phase inversion. Slightly lowers stereo quality, but avoids artefacts if the decoded audio is later downmixed to mono. |
| `--max-delay N` | `1000` | `0`–`1000` ms | Maximum Ogg muxing delay: how long packets may wait before a page is written. Lower it for live streaming. |

#### Input interpretation

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `--raw` | Off | Flag | Read headerless PCM instead of detecting WAV, AIFF or FLAC. Any `--raw-*` option implies it. |
| `--raw-bits N` | `16` | `8`, `16`, `24` | Raw sample size; 8-bit is unsigned, 16- and 24-bit are signed. |
| `--raw-rate N` | `48000` | Hz, `100`–`768000` | Raw sample rate. Opus always codes at 48 kHz internally; opusenc resamples any other input rate. |
| `--raw-chan N` | `2` | `1`–`255` | Raw channel count. More than eight channels are coded as discrete channels (mapping family 255). |
| `--raw-endianness N` | `0` | `0` little, `1` big | Raw byte order. |
| `--ignorelength` | Off | Flag | Ignore the WAV data-chunk length, for WAV piped from tools that write a placeholder length. |

#### Tags, pictures, and padding

Tags and pictures from the input file are copied unless you discard them; command-line tags are added to them.

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `--title TEXT` | Copied from input | Text | Title. |
| `--artist TEXT` | Copied from input | Text; repeatable | Artist. |
| `--album TEXT` | Copied from input | Text | Album. |
| `--tracknumber N` | Copied from input | Text | Track number. |
| `--genre TEXT` | Copied from input | Text; repeatable | Genre. |
| `--date TEXT` | Copied from input | `YYYY`, `YYYY-MM` or `YYYY-MM-DD` | Date. |
| `--comment TAG=VALUE` | — | `NAME=value`; repeatable | Add any Vorbis comment. |
| `--picture FILE` | Input pictures copied | JPEG, PNG or GIF file, or `[TYPE]\|[MIME]\|[DESC]\|[WxHxD]\|FILE`; repeatable | Attach cover art. The type defaults to `3` (front cover); `--help-picture` lists the types. |
| `--padding N` | `512` | Bytes | Spare room in the comment header so tags can be edited later without rewriting the file. |
| `--discard-comments` | Off | Flag | Don't copy tags or pictures from the input (implies `--discard-pictures`). Tags given on the command line are still written. |
| `--discard-pictures` | Off | Flag | Don't copy pictures from the input. |

#### Diagnostics and advanced controls

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `-h`, `--help` | — | Flag | Print help and exit. |
| `-V`, `--version` | — | Flag | Print the opus-tools and libopus versions and exit. |
| `--version-short` | — | Flag | Same output as `--version` in 0.2. Not listed by `--help`. |
| `--help-picture` | — | Flag | Print the `--picture` syntax and picture types `0`–`20`. |
| `--quiet` | Off | Flag | Suppress progress and the final statistics. |
| `--serial N` | Random | Integer | Ogg stream serial number. |
| `--save-range FILE` | Off | Filename | Write per-frame range-coder check values, for decoder conformance testing. |
| `--set-ctl-int [S:]X=Y` | — | `X=Y`, or `S:X=Y` to target stream `S` of a multistream file; repeatable | Pass an integer encoder control, applied after all other settings. Only the requests in the next table are accepted. |

#### Allowed advanced integer requests

`--set-ctl-int` accepts only these requests. Numbers are from the [libopus 1.6.1 headers](https://github.com/xiph/opus/blob/v1.6.1/include/opus_defines.h) and [libopusenc 0.3](https://github.com/xiph/libopusenc/blob/v0.3/include/opusenc.h); defaults are what opusenc sets, which differ from bare libopus in places. Use the named option where one exists.

| Request X | opusenc default | Values Y | Control |
| --- | --- | --- | --- |
| `4000` | `2049` (audio) | `2048` VoIP, `2049` audio, `2051` low delay | Application. |
| `4002` | From `--bitrate` | bit/s; `-1000` auto, `-1` maximum | Bitrate. Without `S:` it is the total for all streams; with `S:` it sets one stream. |
| `4004` | `1105` (fullband) | `1101`–`1105` = 4, 6, 8, 12, 20 kHz | Maximum bandwidth the encoder may choose. |
| `4006` | `1` | `0`/`1` | VBR. |
| `4008` | `-1000` (auto) | `-1000` or `1101`–`1105` | Force a bandwidth. |
| `4010` | `10` | `0`–`10` | Complexity. |
| `4012` | `0` | `0` off, `1` on, `2` on without forcing SILK for music | In-band FEC; also set `--expect-loss`. |
| `4014` | `0` | `0`–`100` % | Expected packet loss. |
| `4016` | `0` | `0`/`1` | DTX. |
| `4020` | `0` (unconstrained) | `0`/`1` | Constrained VBR; ignored with hard CBR. Bare libopus defaults to `1`. |
| `4022` | `-1000` (auto) | `-1000`, `1` mono, `2` stereo | Force the coded channel count of a stream. |
| `4024` | `-1000` (auto) | `-1000`, `3001` voice, `3002` music | Signal type. |
| `4036` | Input bit depth, clamped to `8`–`24` | `8`–`24` | Significant bits in the input. |
| `4042` | `0` | `0`/`1` | Disable inter-frame prediction. |
| `4046` | `0` | `0`/`1` | Disable intensity-stereo phase inversion. |
| `14000` | `96000` (2 s) | 48 kHz samples, at most `96000` | libopusenc decision lookahead. |
| `14002` | `48000` (1 s) | 48 kHz samples | Ogg muxing delay; `--max-delay` sets the same thing in ms. |
| `14004` | `512` | Bytes | Comment padding. |
| `14006` | Random | Integer | Ogg stream serial. |
| `14010` | `0` | 1/256 dB, signed 16-bit | Output gain stored in the Opus header and applied by the player. |

### Complete FFmpeg `libopus` private options

The private options of the [FFmpeg 9.0.2 `libopus` wrapper](https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/libopusenc.c).

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `-application` | `audio` | `audio`, `voip`, `lowdelay` | `audio` for music and general content; `voip` favours speech intelligibility; `lowdelay` uses CELT only for minimum latency. Frames under 10 ms force `lowdelay`. |
| `-frame_duration` | `20` | `2.5`, `5`, `10`, `20`, `40`, `60`, `80`, `100`, `120` ms | Frame length. Other values are rejected, although help shows a continuous 2.5–120 range. 80–120 ms need libopus 1.2 or later. |
| `-packet_loss` | `0` | `0`–`100` % | Expected packet loss. Makes frames more loss-robust and sets how much FEC to send when `-fec 1`. |
| `-fec` | `0` | `0`/`1` | In-band forward error correction (SILK and hybrid modes). Needs `-packet_loss` above 0. |
| `-vbr` | `on` | `off`, `on`, `constrained` | Hard CBR, VBR or constrained VBR. `on` is the right choice for files. |
| `-mapping_family` | `-1` | `-1`, `0`, `1`, `255` | `-1`: family 0 for mono/stereo; for 3–8 channels a family 1 header, but without libopus's surround analysis. `1`: the surround encoder with inter-channel masking, up to 8 channels; use it for 5.1 and 7.1. `0`: mono/stereo only. `255`: up to 254 discrete channels. |
| `-dtx` | `0` | `0`/`1` | Discontinuous transmission: send almost nothing during silence. For VoIP. |
| `-apply_phase_inv` | `1` | `0`/`1` | Intensity-stereo phase inversion. Set `0` if the output will be downmixed to mono. Only present when built against libopus 1.2 or later. |

Generic FFmpeg options the wrapper also reads:

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `-b:a` | 64k per stream + 32k per coupled pair (64k mono, 96k stereo) | `500`–`256000 × channels` bit/s | Total bitrate. Unlike opusenc, the default does not drop for low input sample rates. |
| `-compression_level` | `10` | `0`–`10` | Complexity. |
| `-cutoff` | `0` (auto) | `4000`, `6000`, `8000`, `12000`, `20000` Hz | Maximum coded bandwidth. Other values are ignored with a warning. |
| `-ar` | Input rate if supported | `8000`, `12000`, `16000`, `24000`, `48000` | Other input rates, such as 44.1 kHz, are resampled. |
| `-ac`, `-ch_layout` | Input layout | Channel count or layout name | Output channels. |
| `-q:a` | — | Not supported | Rejected; use `-b:a` with `-vbr`. |

### FFmpeg native `opus`: a separate interface

FFmpeg's own [Opus encoder](https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/opus/enc.c) is experimental (`-strict -2`), CELT-only, and takes 48 kHz mono or stereo. Its default bitrate is 48k mono or 96k stereo. The `libopus` options above don't apply; it has two of its own.

| Parameter | Default | Values / units | Effect |
| --- | --- | --- | --- |
| `-opus_delay` | `360` | `2.5`–`360` ms | Maximum encoder delay. Values below 20 ms also shorten the frame size. |
| `-apply_phase_inv` | `1` | `0`/`1` | Intensity-stereo phase inversion; set `0` if the output will be downmixed to mono. |
