Skip to content

Instantly share code, notes, and snippets.

@mbarkley
Last active April 2, 2020 13:30
Show Gist options
  • Save mbarkley/5f6901739c2978b88460e9e9b6dce65e to your computer and use it in GitHub Desktop.
Save mbarkley/5f6901739c2978b88460e9e9b6dce65e to your computer and use it in GitHub Desktop.
Script for sharing application audio and mic input over Zoom on Linux
#!/usr/bin/env bash
# Copyright 2020 Max Barkley
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Creates virtual sinks with pulseaudio for using microphone
# and sharing application audio over a screensharing program (example Zoom, Hangouts).
#
# To use run: `screenshare-audio <input-device> <output-device>`
# Running with no arguments will show the available devices.
#
# After running, use `pavucontrol` to change specific applications to output
# to `Video-Sink` to share sound. Your default input device will be changed
# to a virtual sink that receives sounds from your selected input device,
# and from the any applications using `Video-Sink`.
#
# On exit, this script removes all created virtual sinks.
inputDevice=$1
outputDevice=$2
function usage() {
echo "usage: $0 {input device} {output device}"
echo "sources:"
pactl list sources | grep Name: | sed 's/^.*Name: / /'
echo "sinks:"
pactl list sinks | grep Name: | sed 's/^.*Name: / /'
}
if [[ -z "${inputDevice}" ]] || [[ -z "${outputDevice}" ]]; then
usage
exit 1
fi
function cleanup() {
set -ex
local moduleTmpFile=$1
for id in $(cat "${moduleTmpFile}" | sort -r); do
pactl unload-module "${id}"
done
}
set -ex
moduleTmpFile=/tmp/$(basename "$0")-$$
touch "${moduleTmpFile}"
pactl load-module module-null-sink sink_name=input_sink sink_properties=device.description=Input-Sink >> "${moduleTmpFile}"
pactl load-module module-null-sink sink_name=video_sink sink_properties=device.description=Video-Sink >> "${moduleTmpFile}"
pactl set-default-sink "${outputDevice}"
pactl set-default-source input_sink.monitor
pactl load-module module-loopback source=video_sink.monitor sink=input_sink >> "${moduleTmpFile}"
pactl load-module module-loopback source=video_sink.monitor sink="${outputDevice}" >> "${moduleTmpFile}"
pactl load-module module-loopback source="${inputDevice}" sink=input_sink >> "${moduleTmpFile}"
set +ex
echo "Set video players to output to Video-Sink"
echo "Set teleconference software to use default input (Input-Sink)"
trap 'cleanup "${moduleTmpFile}"' EXIT SIGTERM
sleep inf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment