wf-shadow/wf-shadow

173 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Copyright (C) 2023 Skylar Widulski
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/>.
#
RUNTIME="${XDG_RUNTIME_DIR:-/run}/wf-shadow"
MONITOR=1
AUDIO_DEV=""
VIDEO_DEV=""
VERBOSE=""
trap 'kill $(jobs -p) 2>/dev/null' EXIT
trap 'exit' INT
set -m
if [ ! -d "$RUNTIME" ]; then
mkdir -p "$RUNTIME" 2>/dev/null
fi
if [ ! -d /tmp/wf-shadow ]; then
mkdir -p /tmp/wf-shadow 2>/dev/null
fi
if [ ! -d "$HOME"/Videos/wf-shadow ]; then
mkdir -p "$HOME"/Videos/wf-shadow 2>/dev/null
fi
if ! command -v wf-recorder &>/dev/null; then
printf "Need wf-recorder\n"
exit 1
fi
if ! command -v wofi &>/dev/null; then
printf "Need wofi\n"
exit 1
fi
print_help() {
cat << EOF
wf-shadow: A Wayland shadow recorder using wf-recorder and wofi
USAGE: wf-shadow OPTION [OPTIONS...]
OPTIONS:
-s MONITOR, --start MONITOR Start a wf-shadow instance with display number MONITOR
-r MONITOR, --record MONITOR Record the last few moments of video using a wofi menu
-e MONITOR, --end MONITOR End wf-shadow instance with display number MONITOR
-a DEVICE, --audio DEVICE Use DEVICE for audio recording. Passed to wf-recorder -a
-V DEVICE, --video DEVICE Use DEVICE for video encoding. Passed to wf-recorder -d
-v, --verbose Verbose output
-h, --help Show this menu
VARIABLES:
\$WF_SHADOW_SAVE The directory to save clips in
\$WF_SHADOW_FORMAT The date format to save clips in
EOF
exit $1
}
record() {
local FILE="${WF_SHADOW_SAVE:-"$HOME"/Videos/wf-shadow/}""$(date +"${WF_SHADOW_FORMAT:-%Y%m%d_%H:%M:%S}")__$2".mp4
if [ $VERBOSE ]; then
if ffmpeg -nostdin -y -sseof -"$2" -i "$1" "$FILE" &>/dev/null; then
notify-send "Clip saved" "$2 second clip saved to $FILE"
else
notify-send "Error saving clip" "Start a new session with --verbose to see ffmpeg output"
fi
else
if ffmpeg -nostdin -y -sseof -"$2" -i "$1" "$FILE"; then
notify-send "Clip saved" "$2 second clip saved to $FILE"
else
notify-send "Error saving clip" "Start a new session with --verbose to see ffmpeg output"
fi
fi
}
start() {
local WOFI_STRING="5 seconds\n10 seconds\n15 seconds\n30 seconds\n1 minute\n5 minutes\n10 minutes\nCancel\n"
while true; do
for i in /tmp/wf-shadow/tmp{00..10}.mp4; do
touch "$i"
if [ $VERBOSE ]; then
wf-recorder ${VIDEO_DEV:+-d "$VIDEO_DEV"} -a $AUDIO_DEV -f "$i" <<< y$'\n'$MONITOR &
else
wf-recorder ${VIDEO_DEV:+-d "$VIDEO_DEV"} -a $AUDIO_DEV -f "$i" <<< y$'\n'$MONITOR &>/dev/null &
fi
printf "%s" "$!" > "$RUNTIME"/"$MONITOR".pid
fg || exit
case "$(if [ $VERBOSE ]; then printf "$WOFI_STRING" | wofi --dmenu -i -H 500 -W 250 -x 0 -y 0; else printf "$WOFI_STRING" | wofi --dmenu -i -H 500 -W 250 -x 0 -y 0 &> /dev/null; fi)" in
'5 seconds') record "$i" 5 ;;
'10 seconds') record "$i" 10 ;;
'15 seconds') record "$i" 15 ;;
'30 seconds') record "$i" 30 ;;
'1 minute') record "$i" 60 ;;
'5 minutes') record "$i" 300 ;;
'10 minutes') record "$I" 600 ;;
*) ;;
esac &
done
done
}
until [ -z "$1" ]; do
case "$1" in
'-h' | '--help') print_help ;;
'-e' | '--end')
END=1
MONITOR="$2"
shift 2 ;;
'-r' | '--record')
RECORD=1
MONITOR="$2"
shift 2 ;;
'-s' | '--start')
START=1
MONITOR="$2"
shift 2 ;;
'-a' | '--audio')
AUDIO_DEV="$2"
shift 2 ;;
'-V' | '--video')
VIDEO_DEV="$2"
shift 2 ;;
'-v' | '--verbose')
VERBOSE="1"
shift 1 ;;
*) print_help ;;
esac
done
if [ "$START" == 1 ]; then
if [ "$MONITOR" ]; then
if [ ! -e "$RUNTIME"/"$MONITOR"_host.pid ]; then
printf "%s" "$$" > "$RUNTIME"/"$MONITOR"_host.pid
start
else
printf "A wf-shadow instance is already running on display %d\n" "$MONITOR"
fi
else
print_help 1
fi
fi
if [ "$RECORD" == 1 ]; then
if [ "$MONITOR" ]; then
kill -2 "$(<"$RUNTIME"/"$MONITOR".pid)"
else
print_help 1
fi
fi
if [ "$END" == 1 ]; then
if [ "$MONITOR" ]; then
kill "$(<"$RUNTIME"/"$MONITOR"_host.pid)" &&
rm -f "$RUNTIME"/"$MONITOR"_host.pid
else
print_help 1
fi
fi