Media Playback on Discord
Streaming is still hard in 2021
So what I wanted to do seemed simple enough, I wanted to watch some of my favorite albums with my favorite people. Unfortunately, it didn’t end up being that simple. BUT, it did end up being fairly uncomplicated, if difficult to explain.
There are many, many ways to visualize the flow that the audio goes through. Especially due to the many moving parts, it’s hard to keep them in your head all at the same time. So here are a couple of concepts to be aware of going into this:
Moving Parts
Sinks and Sources
Sources are what produce audio. Sinks are what consume audio.
Null Sinks
These are Sinks that we can create on the fly. They ALSO come with corresponding Sources. These sources contain the OUTPUT of what we’re sending to the Sinks.
Loopback Devices
These are connections. They hardcode a connection from a Source to a Sink.
Workflow
We want our Mic and Media to go to Discord, and we want our Media to also go to our headphones. It will look something like this:
Microphone ===== \\
\\
<Loopback Device> \\
\\
===== DiscordSink <Null Sink> -- DiscordMonitor <Null Sink Monitor>
\\
<Loopback Device> \\
\\
Media ========== MediaSink <Null Sink> -- MediaMonitor <Null Sink Monitor>
\\
<Loopback Device> \\
\\
Headphones
//
Discord Output =============================== //
So, from this, we can see that we will be creating two Null Sinks (DiscordSink and MediaSink), and three Loopback Devices.
Commands
A part of this is done on the CLI. Actually, the raw creation of these devices is done on the CLI:
pactl load-module module-null-sink sink_name=DiscordSink
pactl load-module module-null-sink sink_name=MediaSink
pactl load-module module-loopback sink=DiscordSink
pactl load-module module-loopback sink=DiscordSink
pactl load-module module-loopback sink=MediaSink
pacmd update-sink-proplist MediaSink device.description="MediaSink"
pacmd update-sink-proplist DiscordSink device.description="DiscordSink"
pacmd update-source-proplist MediaSink.monitor device.description="MediaMonitor"
pacmd update-source-proplist DiscordSink.monitor device.description="DiscordMonitor"
So we create the two sink devices, and create the loopback devices, and attach them to the appropriate sinks to start off with. Then, we rename them so that they make sense.
Pavucontrol
From here on out, we are going to be doing things in the GUI.
Basically, we are going to be connecting the Loopback Devices to their respective inputs/outputs. There are two tabs that we need to be aware of:
Playback
These are the things that are PRODUCING audio. The GUI gives you grammatical hints. It will give you the name of the Source, and the word “on”, and then a selection box with which to select the Sink to attach it to.
I’m just going to list off what should be there, and go from there:
- Loopback of Microphone on DiscordSink
- Loopback of MediaMonitor on DiscordSink
- Loopback of MediaMonitor on Headphones
- VLC/Media Player/etc. on MediaSink
- Discord/Anything Else/etc. on Headphones
Recording
These are the things that are CONSUMING audio. Similar to Playback, there are a couple there that need to be attached to their appropriate Sources:
- Loopback to Discord from Microphone
- Loopback to Discord from MediaMonitor
- Loopback to Headphones from MediaMonitor
Before freaking out about not hearing audio, make sure these are not turned all the way down to “Silence”. Try turning these up if you’re not able to hear stuff.
Confirmation
That’s really all the setup that’s needed. At that point, everything should be hooked up and transmitting. Feel free to check around by pausing the video and speaking through the mic, and watching the levels in the pavucontrol screen. Also, Discord will highlight your video when your audio is transmitting.
If your audio is choppy or dropping out, go to you Settings –> Voice & Video –> Input Sensitivity and unselect the “Automatically determine input sensitivity” option, and set the threshold low enough to not drop out when the audio gets quiet.
Saving this
Once you get this dialed in, you can save the commands to ~/.config/pulse/default.pa
, to have it run automatically on startup.
Bonus: Making stereo input mono
Because I, like most humans, have two ears.
For me, the audio out of my microphone was coming in as Stereo by default, but I only had Mic 1 plugged in, so the left ear was the only thing that was coming through.
First I had to get the sink name:
$ pacmd list-sinks | grep name:
name: <alsa_output.usb-PreSonus_Audio_AudioBox_USB-01.analog-stereo>
And then I had to remap the sink to mono
pacmd load-module module-remap-sink sink_name=Mono master=alsa_output.usb-PreSonus_Audio_AudioBox_USB-01.analog-stereo channels=2 channel_map=mono,mono
At that point, I had to remap the Playback and Recording settings that had Microphone to the new sink that was denoted as Remapped Microphone