Hacker News new | ask | show | jobs
by raffraffraff 1167 days ago
Opus really is great. My first choice almost all the time.

Except... I wanted to stream music across the network to another computer with the lowest possible latency. I didn't care about the extra quality you get from lossless (opus sounded fine to me at 96kbps), but chose flac because it has almost no latency. Opus (and for that matter, all other codecs) added noticeable latency.

5 comments

Opus goes down to 5ms if you customize it, and there's no point in going any lower for Internet streaming because 5ms of raw audio data is only 480 bytes at 16-bit 48khz (plus lots of UDP packet overhead). For latency-sensitive local streaming things are a lot different, and most of your latency will be from buffering to compensate for network jitter.

I used Opus for a VOIP app and I was really impressed with it. It's all I would ever use for Internet audio.

I used the both opusenc and ffmpeg, and twiddled with the configuration endlessly for about a week.

Edit: I'll elaborate here. I went all sciencey and wrote a script to test all combinations of a range of encoder settings that included ranges of comp, max delay, frame size, bitrate etc. Multiplied out, that was a lot of different combinations. I ran the script (which took ages because I had to record the startup latency for each one and capture audio on the remote end, logging ffmpeg output etc etc). Sometimes a particular setting was so bad across 5 tests (with different values for other settings) that I'd scrap that whole batch to save time. The ranges of configurations that were promising were used "in real life" to play music in our living room. I narrowed them down to a few that were "usable", but I asked myself "if I bought this thing as a product, would I send it back?". The answer was "yes".

FWIW, the sender was a Macbook Pro 2015 and the receiver was a Raspberry pi 4B

TL;DR At or below 5ms it had reliability issues (drop-outs) that would occur randomly but frequently enough to ruin music listening experience (like, even a 1s drop per song is completely unacceptable). But it also seemed to stretch audio because the delay would increase over time. Even when I got a high quality (zero drop-out steam) with acceptable latency, the latency would slowly increase over time. So about 1 hour into listening, of I paused the source to answer a call, the decoder end would continue playing for 30+ seconds.

I realised that over a LAN, streaming raw audio technically works, with almost zero latency, so I knew that it was the encode/decode that introduced the latency. That's when I switched over to flac, and noticed an immediate improvement in initial latency, but also stopped having the increasing delay over time.

An Opus frame can be as short as 2.5 ms [1] (at this packet size the effect of network buffering can be pretty obvious), but I use a frame size of 20 ms anyway when capturing on Windows, since this is what `cpal` gives me.

[1] https://opus-codec.org/docs/opus_api-1.3.1/group__opus__enco...

There is a variant of Opus called Opus Custom which is intended to support ultra low latency applications. Might be worth looking into.

There is also this product by the Nullsoft guys, no idea if it's any good though: http://cockos.com/ninjam/

Something's wrong with your setup. Typical latency for opus is only ~20ms and you can get it lower than that by changing an encoder setting. FLAC is usually more than that, but it should be negligible regardless. Maybe you are trying to decode Opus on an extremely low power device?
Whenever I went for low latency, I noticed 2 things: 1. Actual latency was not what I set in the encoder because of frame sizes, chunk sizes, tcp Windows, decided buffering 2. Forcing super low latency caused drop-outs, which is worse for music than delays.

Overall I just found flac to be rock solid and lower latency without much tweak

How did you stream it, if I may ask? ffmpeg server and VLC/mplayer client or something similar?