Skip to content

Instantly share code, notes, and snippets.

@fboender
Created April 13, 2021 17:46
Show Gist options
  • Save fboender/6cb646a04d79940460b4f3a477fd2e33 to your computer and use it in GitHub Desktop.
Save fboender/6cb646a04d79940460b4f3a477fd2e33 to your computer and use it in GitHub Desktop.
Audio / Video profile switcher script
#!/bin/bash
# A script for setting audio video profiles and launching applications. For
# example, since my webcam is in my laptop. I'd like my Google Meet window to
# be on the laptop too, so I can look at the webcam.
set -e
declare -A SCREEN_LAYOUTS
declare -A SCREEN_COORDS
declare -A SOUND_OUTPUTS
# Use arandr to setup your displays and then export the profile
SCREEN_LAYOUTS[external_only]="
--output HDMI-2 --off
--output DP-1 --off
--output DP-2 --off
--output eDP-1 --off
--output HDMI-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal
"
SCREEN_LAYOUTS[external_left]="
--output HDMI-2 --off
--output DP-1 --off
--output DP-2 --off
--output HDMI-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal
--output eDP-1 --mode 1920x1080 --pos 1920x0 --rotate normal
"
# Screen coordinates for moving windows to a different screen. These are
# coordinates on a virtual desktop that is stretched over all monitors; either
# vertically or horizontally, depending on the screen layout.
SCREEN_COORDS[laptop]="0,1920,0,500,500"
SCREEN_COORDS[external]="0,0,0,500,500"
# This requires a bit of a PhD in pulse audio. There has to be a better way
# Mike!
SOUND_OUTPUTS[headphones]="
pacmd set-card-profile alsa_card.usb-Logitech_Logitech_USB_Headset-00 output:analog-stereo+input:analog-mono;
pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo;
pacmd set-default-sink alsa_output.usb-Logitech_Logitech_USB_Headset-00.analog-stereo;
"
SOUND_OUTPUTS[external_monitor]="
pacmd set-card-profile alsa_card.usb-Logitech_Logitech_USB_Headset-00 off;
pacmd set-card-profile 0 output:hdmi-stereo;
pacmd set-default-sink alsa_output.pci-0000_00_1f.3.hdmi-stereo;
"
# Return the X11 window ID for a window who's title matches
get_win_id () {
TITLE="$1"
echo "$(xdotool search "$TITLE" 2>/dev/null| head -n1)"
}
# Switch to one of the predefined layout screens
screen_layout () {
LAYOUT="$1"
echo "Switching screen layout to $LAYOUT"
xrandr ${SCREEN_LAYOUTS[$LAYOUT]}
}
# Switch the sound output to the given profile
sound_output () {
PROFILE="$1"
eval ${SOUND_OUTPUTS[$PROFILE]}
}
# Kill a window
win_kill () {
TITLE="$1"
XWINID="$(get_win_id "$TITLE")"
if [ -n "$XWINID" ]; then
echo "Killing window $XWINID ($TITLE)"
wmctrl -ic $XWINID
fi
}
# Move a window to a particalar virtual desktop
win_to_desktop () {
TITLE="$1"
DESKTOP="$(expr $2 - 1)" # Indexed from 0
XWINID="$(get_win_id "$TITLE")"
echo "Moving window $XWINID ($TITLE) to desktop $DESKTOP"
wmctrl -ir $XWINID -t $DESKTOP
}
# Move a window to a different screen
win_to_screen () {
set -x
TITLE="$1"
SCREENNAME="$2"
XWINID="$(get_win_id "$TITLE")"
echo "Moving window $XWINID ($TITLE) to screen $SCREENNAME"
# Unmaximize the window so we can move it
wmctrl -ir $XWINID -b remove,maximized_vert,maximized_horz
# Move window to requested screen
wmctrl -ir $XWINID -e ${SCREEN_COORDS[$SCREENNAME]}
# Maximize the window
wmctrl -ir $XWINID -b add,maximized_vert,maximized_horz
set +x
}
# Keep a window on the current virtual desktop. This is useful for dual screen,
# when you don't want both screens to switch virtualdesktop. Kinda. It
# simulates it by making a window sticky.
win_sticky () {
TITLE="$1"
XWINID="$(get_win_id "$TITLE")"
echo "Making window $XWINID ($TITLE) sticky"
wmctrl -ir $XWINID -b add,sticky
}
# See above
win_unsticky () {
TITLE="$1"
XWINID="$(get_win_id "$TITLE")"
echo "Making window $XWINID ($TITLE) unsticky"
wmctrl -ir $XWINID -b remove,sticky
}
# Switch to, raise and focus window
win_focus () {
TITLE="$1"
XWINID="$(get_win_id "$TITLE")"
echo "Focussing window $XWINID ($TITLE)"
wmctrl -ia $XWINID
}
if [ "$1" = "" ]; then
PROFILE="default"
else
PROFILE="$1"
fi
echo "Setting profile $PROFILE..."
if [ "$PROFILE" = "default" ]; then
win_kill "Google Meet"
screen_layout "external_only"
elif [ "$PROFILE" = "radio" ]; then
win_kill "Google Meet"
screen_layout "external_only"
sound_output "external_monitor"
firefox -P webapp --new-window https://www.skyradio.nl/player
win_to_desktop "www.skyradio.nl" 1
elif [ "$PROFILE" = "conference" ]; then
win_kill "www.skyradio.nl"
sound_output "headphones"
screen_layout "external_left"
firefox --new-window https://meet.google.com/landing?authuser=1
sleep 1 # give firefox a moment
win_to_screen "Google Meet" "laptop"
win_sticky "Google Meet"
win_focus "Google Meet"
elif [ "$PROFILE" = "conference-present" ]; then
screen_layout "external_only"
win_to_screen "Google Meet" "external"
win_unsticky "Google Meet"
win_to_desktop "Google Meet" 3
win_focus "Google Meet"
else
echo "Invalid profile: $PROFILE" >&2
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment