I couldn't find a great way to set up streaming to Discord or Twitch from Linux, so I wrote this.
The script included below, streaming.sh
, is meant to be used in tandem with the PulseAudio Volume
Control application (pavucontrol
, which is available in repositories for most distributions that use
Pulse but might not be installed by default). It adds two PulseAudio "sinks" (destinations) that you can
route your applications' audio to: a "null sink" and a "combined sink."
- Route your audio to the combined sink to hear it through your speakers and stream it to others.
- Route your audio to the default sink (often called something like "Built-in Audio...") to hear it through your speakers or preferred device but not stream it to others.
- Route your audio to the null sink to not hear the audio through your speakers but still stream it to others. If you're streaming via browser-based application, you'll need to route microphone audio to this sink to be able to stream game or app audio and your voice simultaneously (details below).
To get started, grab streaming.sh
below, optionally remove the .sh
extension (Github requires it for
syntax highlighting, but you don't need it), put it somewhere convenient (for example, a directory on your
PATH
), and mark it as executable. Then run:
streaming
to set up for streaming to a service like Twitch via an application like OBS. This is the most basic setup, and only adds the two sinks mentioned above.streaming discord
to add the two sinks and an additional loopback from a microphone to the null sink. This allows you to combine mic input with game or app audio, since Discord and other browser-based streaming apps (Jitsi, Hangouts, etc.) currently don't seem to capture application audio in Linux (unlike in Windows or macOS).streaming capture
to add the two sinks and an additional loopback from an A/V capture device to the combined sink. This allows you to monitor a capture device's audio output on your speakers or headphones while streaming it. (It may be a quirk of my own setup that this is the best way to hear game audio that I'm capturing from a device, but maybe you'll find it useful too.)- You can combine both of the options above, ie.
streaming discord capture
orstreaming capture discord
. streaming off
will tear down and remove all added sinks and loopbacks. Note that this assumes you're not already using any of the above PulseAudio modules (null-sink
,combine-sink
, orloopback
)! If you are, you'll have to adjust this script to teardown by name instead of module.
Once the sinks are added, you'll need to start your streaming application — in the case of Discord or
another browser-based app, this means actually joining a voice channel or call! Then open pavucontrol
and go to the Recording tab. You should see the application in question. Set its input source to "Monitor
of OBS Null Sink":
That should do it. In the Playback tab, you can now route applications' audio to your sinks of choice as described above.
Capturing a monitor of your computer's audio — everything that is sent to your speakers — via PulseAudio is fairly straightforward, but oftentimes you need something a little more complex than that. This script aims to solve the following problems:
-
Currently, neither OBS nor browser-based screensharing (Discord, Jitsi, Hangouts, etc) appear to allow you to select a specific application's audio as a source. Browser-based screenshare applications at the moment simply don't seem to capture application audio at all in Linux, despite doing so in Windows and macOS. You can work around this by routing your desktop audio to the browser (via
pavucontrol
or a similar application), but while you're doing this the people you're streaming to won't be able to hear you speak via your mic. -
OBS fares a bit better in that it can capture microphone audio and desktop audio and combine them into a single stream, but there's still no way to exclude desktop audio sources when doing this. (And while streaming from OBS to Discord or other browser-based screenshare apps is possible, it requires building a custom plugin against the OBS sources and installing a kernel module, which if you're like me sounds like way too much work even if this partial solution works for you.)
-
An alternate solution floating around is to use a PulseAudio loopback module to capture and playback your microphone input, so that it's included when you record your desktop audio. This is somewhat less than ideal for streaming, since it means you'll hear yourself in the mix.
-
More generally, if you're streaming to other people via something like Discord or Hangouts, you might want to hear other people talking, but you probably don't want to stream their audio back to them! So capturing all desktop audio isn't a good general solution.
Ultimately, what we need is some way to selectively select playback sources for inclusion or exclusion in a stream. It might be possible to do this with JACK, but for most people that would require installing and running an extra sound daemon alongside what they already have.
For folks running a system with PulseAudio, pavucontrol
is almost a good enough solution to this problem:
it's a GUI that gives you a list of applications playing audio, applications recording audio, input devices, and
output devices, and lets you route them to each other. The only thing missing is some extra sinks — extra
destinations to point output towards. This script provides the latter, and sets them up so that they're opt-in:
by default no audio is output to the streaming sink, avoiding mishaps like feeding back Discord voice participants'
back to them.
This approach is inspired by this guide (and associated discussion) from the OBS forum from 2014, as well as this blog post. (The latter might also have some troubleshooting tips if you're having trouble getting this method to work.)