Created
April 13, 2021 17:46
-
-
Save fboender/6cb646a04d79940460b4f3a477fd2e33 to your computer and use it in GitHub Desktop.
Audio / Video profile switcher script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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