Skip to content

Opus

currentMigrated from docs/audio/Opus.mdx at 37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0

Opus is an open, royalty-free lossy audio codec standardised as RFC 6716. 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 is still the safe choice. For web video it is the standard companion to VP9 and 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.

Bitrates are for the whole stream, not per channel. These are the Xiph recommended settings:

ContentChannelskbit/s
Voice over IPMono10–24
Podcast / audiobookMono24
Podcast / audiobookStereo32
Music streamingStereo64–96
Music archive / storageStereo96–128
Music5.1128–256
Music7.1256–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) instead.

opusenc (from 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.

Terminal window
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.

Terminal window
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:

OptionUse
-application voipSpeech intelligibility tuning for voice recordings. audio (default) is right for music; lowdelay is only for real-time work.
-vbr constrainedLimits rate swings for streaming. -vbr off is hard CBR.
-frame_durationLeave at 20. Longer frames only help at very low bitrates; shorter ones cost quality and are for latency.
-mapping_family 1Surround layouts, see below.
-ac 1Mono 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.

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.

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:

Terminal window
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:

Terminal window
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). 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 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.

Opus container mappings
RelationshipProject or formatEvidence and scopeStatus
Carried ByOggOgg Opus uses OpusHead and OpusTags headers with 48 kHz granule-position semantics.Scope: Container Mapping · Sources: RFC 7845: Ogg Encapsulation for the Opus Audio CodecNormative
Carried ByMatroskaUses the A_OPUS Codec ID and stores the Opus identification header in CodecPrivate.Scope: Container Mapping · Sources: Matroska codec mappingsNormative
Carried ByWebMOpus is one of the audio codecs listed by the WebM Project.Scope: Container Mapping · Sources: WebM container guidelinesDocumented
Carried ByISO Base Media File FormatThe 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, MP4 Registration Authority codec registryRegistered
  • Ogg Opus (.opus, RFC 7845) 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.

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.

ParameterDefaultValues / unitsEffect
--bitrate NAuto: 64 kbit/s mono, 96 stereokbit/s for the whole stream, decimals allowed; 6–256 per channel is the useful rangeTarget 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.
--vbrOnFlagUnconstrained VBR: the bitrate follows the content around the target. The right mode for files.
--cvbrOffFlagConstrained VBR: packet sizes vary but stay close to the target, like CBR with a small reservoir. For streaming over constant-rate links.
--hard-cbrOffFlagEvery packet the same size, at a quality cost. Only for transports that need it. The last of --vbr, --cvbr and --hard-cbr wins.
--musicAuto-detectedFlagTreat the input as music, overriding speech/music detection. Mainly matters at low bitrates.
--speechAuto-detectedFlagTreat the input as speech, favouring the SILK modes at low bitrates. The last of --music and --speech wins.
--comp N, --complexity N100–10Encoder effort; 10 is slowest and best. Lower it only for real-time encoding on weak CPUs.
--framesize N202.5, 5, 10, 20, 40, 60 msMaximum 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 N00–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-monoOffFlagDownmix to mono before encoding.
--downmix-stereoOffFlagDownmix inputs with more than two channels to stereo.
--no-downmixOffFlagDisable 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-invOffFlagDisable intensity-stereo phase inversion. Slightly lowers stereo quality, but avoids artefacts if the decoded audio is later downmixed to mono.
--max-delay N10000–1000 msMaximum Ogg muxing delay: how long packets may wait before a page is written. Lower it for live streaming.
ParameterDefaultValues / unitsEffect
--rawOffFlagRead headerless PCM instead of detecting WAV, AIFF or FLAC. Any --raw-* option implies it.
--raw-bits N168, 16, 24Raw sample size; 8-bit is unsigned, 16- and 24-bit are signed.
--raw-rate N48000Hz, 100–768000Raw sample rate. Opus always codes at 48 kHz internally; opusenc resamples any other input rate.
--raw-chan N21–255Raw channel count. More than eight channels are coded as discrete channels (mapping family 255).
--raw-endianness N00 little, 1 bigRaw byte order.
--ignorelengthOffFlagIgnore the WAV data-chunk length, for WAV piped from tools that write a placeholder length.

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

ParameterDefaultValues / unitsEffect
--title TEXTCopied from inputTextTitle.
--artist TEXTCopied from inputText; repeatableArtist.
--album TEXTCopied from inputTextAlbum.
--tracknumber NCopied from inputTextTrack number.
--genre TEXTCopied from inputText; repeatableGenre.
--date TEXTCopied from inputYYYY, YYYY-MM or YYYY-MM-DDDate.
--comment TAG=VALUE—NAME=value; repeatableAdd any Vorbis comment.
--picture FILEInput pictures copiedJPEG, PNG or GIF file, or [TYPE]|[MIME]|[DESC]|[WxHxD]|FILE; repeatableAttach cover art. The type defaults to 3 (front cover); --help-picture lists the types.
--padding N512BytesSpare room in the comment header so tags can be edited later without rewriting the file.
--discard-commentsOffFlagDon’t copy tags or pictures from the input (implies --discard-pictures). Tags given on the command line are still written.
--discard-picturesOffFlagDon’t copy pictures from the input.
ParameterDefaultValues / unitsEffect
-h, --help—FlagPrint help and exit.
-V, --version—FlagPrint the opus-tools and libopus versions and exit.
--version-short—FlagSame output as --version in 0.2. Not listed by --help.
--help-picture—FlagPrint the --picture syntax and picture types 0–20.
--quietOffFlagSuppress progress and the final statistics.
--serial NRandomIntegerOgg stream serial number.
--save-range FILEOffFilenameWrite 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; repeatablePass an integer encoder control, applied after all other settings. Only the requests in the next table are accepted.

--set-ctl-int accepts only these requests. Numbers are from the libopus 1.6.1 headers and libopusenc 0.3; defaults are what opusenc sets, which differ from bare libopus in places. Use the named option where one exists.

Request Xopusenc defaultValues YControl
40002049 (audio)2048 VoIP, 2049 audio, 2051 low delayApplication.
4002From --bitratebit/s; -1000 auto, -1 maximumBitrate. Without S: it is the total for all streams; with S: it sets one stream.
40041105 (fullband)1101–1105 = 4, 6, 8, 12, 20 kHzMaximum bandwidth the encoder may choose.
400610/1VBR.
4008-1000 (auto)-1000 or 1101–1105Force a bandwidth.
4010100–10Complexity.
401200 off, 1 on, 2 on without forcing SILK for musicIn-band FEC; also set --expect-loss.
401400–100 %Expected packet loss.
401600/1DTX.
40200 (unconstrained)0/1Constrained VBR; ignored with hard CBR. Bare libopus defaults to 1.
4022-1000 (auto)-1000, 1 mono, 2 stereoForce the coded channel count of a stream.
4024-1000 (auto)-1000, 3001 voice, 3002 musicSignal type.
4036Input bit depth, clamped to 8–248–24Significant bits in the input.
404200/1Disable inter-frame prediction.
404600/1Disable intensity-stereo phase inversion.
1400096000 (2 s)48 kHz samples, at most 96000libopusenc decision lookahead.
1400248000 (1 s)48 kHz samplesOgg muxing delay; --max-delay sets the same thing in ms.
14004512BytesComment padding.
14006RandomIntegerOgg stream serial.
1401001/256 dB, signed 16-bitOutput gain stored in the Opus header and applied by the player.

The private options of the FFmpeg 9.0.2 libopus wrapper.

ParameterDefaultValues / unitsEffect
-applicationaudioaudio, voip, lowdelayaudio for music and general content; voip favours speech intelligibility; lowdelay uses CELT only for minimum latency. Frames under 10 ms force lowdelay.
-frame_duration202.5, 5, 10, 20, 40, 60, 80, 100, 120 msFrame length. Other values are rejected, although help shows a continuous 2.5–120 range. 80–120 ms need libopus 1.2 or later.
-packet_loss00–100 %Expected packet loss. Makes frames more loss-robust and sets how much FEC to send when -fec 1.
-fec00/1In-band forward error correction (SILK and hybrid modes). Needs -packet_loss above 0.
-vbronoff, on, constrainedHard 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.
-dtx00/1Discontinuous transmission: send almost nothing during silence. For VoIP.
-apply_phase_inv10/1Intensity-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:

ParameterDefaultValues / unitsEffect
-b:a64k per stream + 32k per coupled pair (64k mono, 96k stereo)500–256000 × channels bit/sTotal bitrate. Unlike opusenc, the default does not drop for low input sample rates.
-compression_level100–10Complexity.
-cutoff0 (auto)4000, 6000, 8000, 12000, 20000 HzMaximum coded bandwidth. Other values are ignored with a warning.
-arInput rate if supported8000, 12000, 16000, 24000, 48000Other input rates, such as 44.1 kHz, are resampled.
-ac, -ch_layoutInput layoutChannel count or layout nameOutput channels.
-q:a—Not supportedRejected; use -b:a with -vbr.

FFmpeg’s own Opus encoder 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.

ParameterDefaultValues / unitsEffect
-opus_delay3602.5–360 msMaximum encoder delay. Values below 20 ms also shorten the frame size.
-apply_phase_inv10/1Intensity-stereo phase inversion; set 0 if the output will be downmixed to mono.