Skip to content

Instantly share code, notes, and snippets.

@koleror
Last active February 16, 2025 11:06
Show Gist options
  • Save koleror/7bb1095407609339c90f9973e75d57dd to your computer and use it in GitHub Desktop.
Save koleror/7bb1095407609339c90f9973e75d57dd to your computer and use it in GitHub Desktop.
Sleep timer - Auto pause music after given amount of time
#!/bin/bash -e
#############
# CONSTANTS #
#############
DIM_SCREEN_DELAY=5
FADE_OUT_STEP=3
MUSIC_APPLICATION_NAME="Spotify"
FADE_OUT_LIMIT=15
#############
# FUNCTIONS #
#############
function print_usage() {
echo "usage: $(basename "${0}") number[unit]"
echo "Unit can be 's' (seconds, the default), m (minutes), h (hours), or d (days)."
}
function usage_exit_error() {
print_usage 1>&2;
exit 1;
}
function convert_to_seconds() {
digits=$(echo "${1}" | tr -cd '[:digit:]');
if [[ "${1}" == *"s" ]]; then
# seconds
echo "$digits";
elif [[ "${1}" == *"m" ]]; then
# minutes
echo "$((digits * 60))";
elif [[ "${1}" == *"h" ]]; then
# hours
echo "$((digits * 60 * 60))";
elif [[ "${1}" == *"d" ]]; then
# days
echo "$((digits * 60 * 60 * 24))";
elif [ "${1}" == "$digits" ]; then
# seconds (default)
echo "$digits";
else
usage_exit_error;
fi
}
function print_verbose() {
digits=$(echo "${1}" | tr -cd '[:digit:]');
[ "$digits" -gt "1" ] && plural="s" || plural=""
if [[ "${1}" == *"s" ]]; then
# seconds
echo "Sleeping in $digits second${plural}...";
elif [[ "${1}" == *"m" ]]; then
# minutes
echo "Sleeping in $digits minute${plural}...";
elif [[ "${1}" == *"h" ]]; then
# hours
echo "Sleeping in $digits hour${plural}...";
elif [[ "${1}" == *"d" ]]; then
# days
echo "Sleeping in $digits day${plural}...";
elif [ "${1}" == "$digits" ]; then
# seconds
echo "Sleeping in $digits second${plural}...";
else
usage_exit_error;
fi
}
function get_volume() {
osascript -e "output volume of (get volume settings)"
}
#########
# USAGE #
#########
if [ $# -eq 0 ] ; then
# Missing parameter
usage_exit_error;
elif [ "${1}" == "-h" ] || [ "${1}" == "--help" ]; then
# Help requested
print_usage;
exit 0;
fi
########
# ALGO #
########
print_verbose "${1}";
time_in_seconds=$(convert_to_seconds "${1}")
remaining_time=$time_in_seconds;
# $DIM_SCREEN_DELAY seconds sleep if possible to let the user read the verbose message
if [ "${time_in_seconds}" -gt ${DIM_SCREEN_DELAY} ]; then
sleep ${DIM_SCREEN_DELAY};
remaining_time=$((time_in_seconds - DIM_SCREEN_DELAY))
fi
# Turn off screen
pmset displaysleepnow;
sleep "$remaining_time";
initial_volume=$(get_volume)
# Fade-out volume
while [ "$(get_volume)" -gt "${FADE_OUT_LIMIT}" ] ; do
osascript -e "set volume output volume (output volume of (get volume settings) - ${FADE_OUT_STEP})"
done
# Pause music
osascript -e "tell application \"${MUSIC_APPLICATION_NAME}\" to pause"
# Restore volume then mute
osascript -e "set volume output volume ${initial_volume}";
osascript -e "set volume with output muted";
# Sleep computer
pmset sleepnow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment