Skip to content

Instantly share code, notes, and snippets.

@rkmax
Created August 27, 2024 00:16
Show Gist options
  • Save rkmax/8f573be2bec44857c2053060ef615940 to your computer and use it in GitHub Desktop.
Save rkmax/8f573be2bec44857c2053060ef615940 to your computer and use it in GitHub Desktop.
A Bash script for screen recording, daemon mode, and customizable frame rate and duration.
#!/bin/bash
output_dir="$HOME/Videos/Replays"
rate=30
pipe_path="/tmp/record_control_pipe"
pid_file="/tmp/record_screen.pid"
daemon_pid_file="/tmp/record_screen_daemon.pid"
daemon_log_file="/tmp/record_screen_daemon.log"
record_extension="mp4"
timeout=60
usage() {
echo "Usage: $0 [-r rate] [-d output_dir]"
echo " -r rate Frames per second (default: $rate)"
echo " -t timeout Set a time limit for recording (in seconds, default: $timeout)"
echo " -x Toggle recording on or off"
echo " -D Run script as a daemon"
echo " -k Stop the daemonized script"
echo " (only one of -D or -k options can be used)"
echo " -d output_dir Directory to save recordings (default: $output_dir)"
exit 1
}
action=''
while getopts "r:d:t:Dkxh" opt; do
case ${opt} in
r ) rate=$OPTARG ;;
d ) output_dir=$OPTARG ;;
t ) timeout=$OPTARG ;;
x ) action='toggle_record' ;;
D ) action='daemonize' ;;
k ) action='kill_daemon' ;;
h ) usage ;;
* ) usage ;;
esac
done
trap 'cleanup' SIGINT SIGTERM
cleanup() {
if [ -e "$pipe_path" ]; then rm -f "$pipe_path"; fi
if [ -f "$pid_file" ]; then
kill -SIGINT $(cat "$pid_file")
rm -f "$pid_file"
fi
pkill -P $$
exit 0
}
send_notification() {
local message=$1
notify-send "Screen Recording" "$message"
}
start_recording() {
mkdir -p "$output_dir"
local filename="$output_dir/replay-$(date +'%Y-%m-%d_%H-%M-%S').$record_extension"
ffmpeg \
-video_size "3840x2160" \
-framerate "$rate" \
-f x11grab \
-i :0.0+2160,840 \
-f alsa \
-i pulse \
-vf "scale=1920:1080" \
-draw_mouse 1 \
"$filename" &
echo $! > "$pid_file"
send_notification "Recording started in $filename"
( sleep "$timeout" && [ -f "$pid_file" ] && toggle_recording ) &
}
stop_recording() {
if [ -f "$pid_file" ]; then
kill -SIGINT $(cat "$pid_file")
rm -f "$pid_file"
send_notification "Recording stopped"
else
echo "No recording in progress."
fi
}
toggle_recording() {
if [ -f "$pid_file" ]; then
stop_recording
else
start_recording
fi
}
stop_daemon() {
if [ -f "$daemon_pid_file" ]; then
echo "Stopping daemon process..."
kill -SIGTERM $(cat "$daemon_pid_file")
rm -f "$daemon_pid_file"
exit 0
else
echo "No running daemon process found."
exit 1
fi
}
if [ "$action" == "kill_daemon" ]; then
stop_daemon
fi
if [ "$action" == "daemonize" ]; then
if [ -f "$daemon_pid_file" ]; then
echo "Error: A daemon process is already running. Stop the daemon before running the script normally."
exit 1
fi
nohup "$0" -r "$rate" -d "$output_dir" > $daemon_log_file 2>&1 &
echo $! > "$daemon_pid_file"
exit 0
fi
if [ "$action" == "toggle_record" ]; then
if [ ! -p "$pipe_path" ]; then
echo "Error: Cannot toggle recording; this script must first be running first without flags or the -D flag."
exit 1
fi
echo "toggle_recording" > "$pipe_path"
exit 0
fi
if [ ! -p "$pipe_path" ]; then
if [ -e "$pipe_path" ]; then
echo "Error: A non-pipe file exists at $pipe_path. Please remove or rename that file."
exit 1
fi
mkfifo "$pipe_path"
fi
echo "Listening for recording commands..."
while true; do
if read -r command <"$pipe_path"; then
case $command in
toggle_recording) toggle_recording ;;
*) echo "Unrecognized command: $command" ;;
esac
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment