Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ffmpeg not honoring sample rate in opus output

Tags:

ffmpeg

opus

I am capturing a live audio stream to Opus, and no matter what I choose for the audio sample rate, I get 48khz output.

This is my command line

./ffmpeg -f alsa -ar 16000 -i sysdefault:CARD=CODEC -f alsa -ar 16000 -i sysdefault:CARD=CODEC_1 -filter_complex join=inputs=2:channel_layout=stereo:map=0.1-FR\|1.0-FL,asetpts=expr=N/SR/TB -ar 16000 -ab 64k -c:a opus -vbr off -compression_level 5 output.ogg

And this is what ffmpeg responds with:

Output #0, ogg, to 'output.ogg': Metadata: encoder : Lavf57.48.100 Stream #0:0: Audio: opus (libopus), 16000 Hz, stereo, s16, delay 104, padding 0, 64 kb/s (default) Metadata: encoder : Lavc57.54.100 libopus

However, it appears that ffmpeg has lied, because when analysing the file again, I get:

Input #0, ogg, from 'output.ogg': Duration: 00:00:03.21, start: 0.000000, bitrate: 89 kb/s Stream #0:0: Audio: opus, 48000 Hz, stereo, s16, delay 156, padding 0 Metadata: ENCODER : Lavc57.54.100 libopus

I have tried so many permutations of sample rate, simplifying down to a single audio input etc etc - always with the same result.

Any ideas?

like image 660
Adam Avatar asked Feb 06 '23 06:02

Adam


1 Answers

This question should be asked and answered on Super User, since it's about using software instead of programming. But, since I know the answer, I'll post one anyway.

FFmpeg will encode Opus at the sample rate specified. You can verify this in the source code of libopusenc.c (here and here).

But FFmpeg will decode Opus at 48 kHz, even if it was encoded at a lower sample rate. You can verify this in libopusdec.c (here and here).

This is actually recommended by the Ogg Opus specification (IETF RFC 7845). Section 5.1, item 5 says:

An Ogg Opus player SHOULD select the playback sample rate according to the following procedure:

  1. If the hardware supports 48 kHz playback, decode at 48 kHz.
  2. Otherwise, if the hardware's highest available sample rate is a supported rate, decode at this sample rate.
  3. Otherwise, if the hardware's highest available sample rate is less than 48 kHz, decode at the next higher Opus supported rate above the highest available hardware rate and resample.
  4. Otherwise, decode at 48 kHz and resample.

Since FFmpeg and most hardware support 48 kHz playback, 48 kHz is used for decoding Opus in FFmpeg. The original sample rate is stored in the OpusHead packet of the Ogg container, so you can retrieve it using a parser or different player if you wish, but FFmpeg ignores it and just decodes at 48 kHz.

like image 68
Cornstalks Avatar answered Mar 04 '23 20:03

Cornstalks