tldr: skip to the bottom

I’ve been working on a project called PlaySpaceTV, which allows gamers and friends to live-stream their gameplay to others in the web browser. For this, we of course decided to use WebRTC. Ever since we launched the platform Beta back in June of this year, users have complained about low quality desktop audio.

For some reason, desktop audio quality can sound echoy (I wish that was a real word). My first thought, was that I might be using the wrong codec. So I did some research into how to change WebRTC’s default codec to Opus, and learned that it’s actually the default. My next thought was that the Peer Connection’s (connection between streamer and viewer) audio channel was being limited in some way. Nope.

After a while, I kind of gave up looking as no one on the internet seemed to ever run into this problem. There seems to be a lot of those problem types in the WebRTC space. Anyways, one day I had a backlogged task in my Trello board for trying to figure out desktop audio quality. So once again, after multiple failures, I tried to fix it.

Many google searches, stack overflow posts, and google groups later… nothing. I must have gotten up to use the bathroom or get a drink, and when I came back it just sorta hit me. I remembered having a similar issue with microphone quality. Sometimes, browsers like Chrome would use Echo Cancellation and Auto Gain Control. Basically, I was handing quality control of the sound over to the browser to handle, when I should probably just have faith that the raw stream is ok.

So, to solve this, instead of passing in audio: true when calling getUserMedia(), I passed in the constraints below, and that did the trick.

So I had an idea, that maybe this same strategy would work for getDisplayMedia(). So I tried something similar, and it worked!

I don’t understand why browsers would apply echo cancellation to a desktop audio track, but they do. It’s kind of frustrating how simple this solution was, and how long it took me to find. I feel like something like this would be in documentation somewhere, but I never ran into it anywhere.

Anyways, I hoped this helped you with your problem. If you ever have any more questions or things you want help with, you can always ask on my twitter: TrystonPerry