Skip to content

Instantly share code, notes, and snippets.

@ShellyHerself
Last active December 22, 2019 10:35
Show Gist options
  • Save ShellyHerself/db2e2a622cbc7dfcfd2f9f24dd7420e4 to your computer and use it in GitHub Desktop.
Save ShellyHerself/db2e2a622cbc7dfcfd2f9f24dd7420e4 to your computer and use it in GitHub Desktop.
Linux OBS game and system audio separation helper
#!/usr/bin/perl
##
## VERSION 1.1 UPDATED 2019-12-22
##
## This script creates a set of audio devices that allow you to
## separate game audio and other system audio when streaming using OBS on Linux.
## After it has been executed you can simply tell your game to stream its audio to game-output-device.
## And tell obs to listen to obs-listen-device
##
## Script Does this:
##
## Create a null device:
## pactl load-module module-null-sink sink_name=obs-listen-device
## Name the device:
## pacmd update-sink-proplist obs-listen-device device.description=obs-listen-device
## Get numerical id of the default audio output and the null device:
## pactl list short sinks
## Make a combined device:
## pactl load-module module-combine-sink slaves=id,id sink_name=game-output-device
## Name that combined device:
## pacmd update-sink-proplist game-output-device device.description=game-output-device
##
##
## How to use:
##
## Set $main_audio_device_identifier to the right identifier for your audio device.
## (Current value is mine as an example)
## Do "pactl list short sinks"
## And get the name that only your wished audio device has in the output.
##
## Make sure that everything you don't want streamed still outputs
## to the right default device.
##
## Use something like pavucontrol to make the game you want to
## stream output to "game-output-device".
##
## Set OBS up to record the "obs-listen-device" device.
##
use warnings;
use strict;
use List::Util qw( first );
my $main_audio_device_identifier = "alsa_output.pci-0000_03_06.0.analog-stereo";
# Returns an array of short sink results
sub get_sinks {
open(AVAILABLE_SINKS, "pactl list short sinks|");
my @sinks = <AVAILABLE_SINKS>;
close(AVAILABLE_SINKS);
return @sinks;
}
my @sinks = get_sinks;
# Returns the index of a sink found by the given identifier
# (Needs to show up in short sinks)
sub get_sink {
my ($sink_name) = @_;
my $sink = first { index($_, $sink_name) != -1 } @sinks;
unless(defined($sink)) { return -1; }
my ($id) = ($sink =~ /^(\d*)\t/);
return $id;
}
# Don't continue if there already is a combined sink
my $badshit = get_sink "game-output-device";
die "Already found a game-output-device!" if ($badshit != -1);
# Get existing nullsink if available
my $nullsink_id = get_sink "obs-listen-device";
if ($nullsink_id == -1){
# Make the device
system "pactl load-module module-null-sink sink_name=obs-listen-device >/dev/null";
# Name the device
system "pacmd update-sink-proplist obs-listen-device device.description=obs-listen-device";
@sinks = get_sinks();
$nullsink_id = get_sink "obs-listen-device";
}
# Can't continue without a nullsink.
die "Couldn't find or create a nullsink" if ($nullsink_id == -1);
# Get the main sink for the combining.
my $main_sink_id = get_sink $main_audio_device_identifier;
die "Couldn't find main sink" if ($main_sink_id == -1);
# Create new combined sink.
system qq{pactl load-module module-combine-sink slaves=$main_sink_id,$nullsink_id sink_name=game-output-device >/dev/null};
# Name that sink something logical.
system "pacmd update-sink-proplist game-output-device device.description=game-output-device";
@sinks = get_sinks;
# Check if process was succesful by getting the index for the sink (if exists.)
my $combined_sink_id = get_sink "game-output-device";
die "Couldn't create combined sink!" if ($combined_sink_id == -1);
# Print the short sink index, return style.
print qq{Sink ID: $combined_sink_id\n};
@ShellyHerself
Copy link
Author

ShellyHerself commented Aug 27, 2019

This saves me 5 minutes on every day that I want to stream something for a little bit. It's a pretty simple task, but finding the documentation to make sure you're doing it right takes time if you're messy like me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment