diff --git a/README.md b/README.md index 9c15b83..900e40e 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,9 @@ # Dependencies This script depends on `wf-recorder`, `wofi`, and, obviously, `bash`. -# Running -Put this script somewhere in your $PATH, and run `wf-shadow --help` +# Installation +## Package Manager +Currently, no distributions include `wf-shadow` as a package. See "Manual Installation". + +## Manual Installation +Put this script somewhere in your $PATH. To find which directories are in your $PATH, run `sed 's/:/\n/g' <<< "$PATH"`. diff --git a/wf-shadow b/wf-shadow index 8f48948..80b9497 100755 --- a/wf-shadow +++ b/wf-shadow @@ -16,12 +16,26 @@ # RUNTIME="${XDG_RUNTIME_DIR:-/run}/wf-shadow" +CONFIG="${WF_SHADOW_CONFIG:-${XDG_CONFIG_HOME:-$HOME/.config}/wf-shadow/config.sh}" + +if [ ! -d "${CONFIG%/*}" ]; then + mkdir -p "${CONFIG%/*}" 2>/dev/null +fi + +if [ ! -f "$CONFIG" ]; then + printf '' >> "$CONFIG" +fi MONITOR=1 AUDIO_DEV="" VIDEO_DEV="" VERBOSE="" -trap 'kill $(jobs -p) 2>/dev/null' EXIT +WF_SHADOW_DIR="${WF_SHADOW_DIR:-"$HOME"/Videos/wf-shadow}" +WF_SHADOW_FORMAT="${WF_SHADOW_FORMAT:-%Y%m%d_%H:%M:%S}" + +. "$CONFIG" + +trap 'kill $(jobs -p) 2>/dev/null' EXIT trap 'exit' INT set -m @@ -33,8 +47,8 @@ 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 +if [ ! -d "$WF_SHADOW_DIR" ]; then + mkdir -p "$WF_SHADOW_DIR" 2>/dev/null fi if ! command -v wf-recorder &>/dev/null; then @@ -54,32 +68,35 @@ 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 + -s, --start [MONITOR] Start a wf-shadow instance with display number MONITOR. + -r, --record [MONITOR] Record the last few moments of video using a wofi menu. + -e, --end [MONITOR] End wf-shadow instance with display number MONITOR. + -a, --audio DEVICE Use DEVICE for audio recording. Passed to wf-recorder -a. + -V, --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 +For a more in-depth guide, see wf-shadow(1) 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" + local SAVE_FILE + if [ ! $WF_SHADOW_SAVE ]; then + SAVE_FILE="$WF_SHADOW_DIR"/"$(date +"$WF_SHADOW_FORMAT")__$2".mp4 + else + SAVE_FILE="$(eval "$WF_SHADOW_SAVE")" + fi + if [ -n "$VERBOSE" ]; then + if ffmpeg -nostdin -y -sseof -"$2" -i "$1" "$SAVE_FILE" &>/dev/null; then + notify-send "Clip saved" "$2 second clip saved to $SAVE_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" + if ffmpeg -nostdin -y -sseof -"$2" -i "$1" "$SAVE_FILE"; then + notify-send "Clip saved" "$2 second clip saved to $SAVE_FILE" else notify-send "Error saving clip" "Start a new session with --verbose to see ffmpeg output" fi @@ -90,8 +107,8 @@ 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 + printf '' >> "$i" + if [ -n "$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 & @@ -99,7 +116,12 @@ start() { 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 + case "$(if [ -n "$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 ;; @@ -114,20 +136,33 @@ start() { } until [ -z "$1" ]; do + re="[0-9]+" case "$1" in '-h' | '--help') print_help ;; '-e' | '--end') END=1 - MONITOR="$2" - shift 2 ;; + if [[ "$2" =~ $re ]]; then + MONITOR="$2" + shift 2 + else + shift 1 + fi ;; '-r' | '--record') RECORD=1 - MONITOR="$2" - shift 2 ;; + if [[ "$2" =~ $re ]]; then + MONITOR="$2" + shift 2 + else + shift 1 + fi ;; '-s' | '--start') START=1 - MONITOR="$2" - shift 2 ;; + if [[ "$2" =~ $re ]]; then + MONITOR="$2" + shift 2 + else + shift 1 + fi ;; '-a' | '--audio') AUDIO_DEV="$2" shift 2 ;; diff --git a/wf-shadow.1 b/wf-shadow.1 index 46128f6..c0fb70f 100644 --- a/wf-shadow.1 +++ b/wf-shadow.1 @@ -24,12 +24,13 @@ and wofi(1) in order to accomplish the task.\& .P .SH OPTIONS .P -\fB-s, --start\fR \fIMONITOR\fR +\fB-s, --start\fR [\fIMONITOR\fR] .RS 4 -Starts a wf-shadow instance on monitor number \fIMONITOR\fR.\& +Starts a wf-shadow instance on monitor number \fIMONITOR\fR, if no \fIMONITOR\fR +is specified, then use monitor #1.\& .P .RE -\fB-r, --record\fR \fIMONITOR\fR +\fB-r, --record\fR [\fIMONITOR\fR] .RS 4 Record the last few moments of video using a wofi(1) menu.\& .P @@ -37,7 +38,7 @@ This will use the same \fIMONITOR\fR number as any running session of \fBwf-shadow\fR.\& .P .RE -\fB-e, --end\fR \fIMONITOR\fR +\fB-e, --end\fR [\fIMONITOR\fR] .RS 4 End the current instance running on monitor \fIMONITOR\fR.\& .P @@ -66,7 +67,7 @@ Show a simple help menu .RE .SH ENVIRONMENT .P -\fBWF_SHADOW_SAVE\fR +\fBWF_SHADOW_DIR\fR .RS 4 The path to the directory used to save clips.\& .P @@ -76,6 +77,49 @@ The path to the directory used to save clips.\& The date(1) \fI-d\fR format used by \fBwf-shadow\fR to save clips.\& .P .RE +\fBWF_SHADOW_SAVE\fR +.RS 4 +The bash(1) command to run to get the save file for clips.\& The output of +the command is used as the path.\& Overrides \fBWF_SHADOW_DIR\fR and +\fBWF_SHADOW_FORMAT\fR.\& +.P +.RE +\fBWF_SHADOW_CONFIG\fR +.RS 4 +The path to the configuration file used by \fBwf-shadow\fR.\& +See \fBCONFIGURATION\fR for how to configure \fBwf-shadow\fR.\& +.P +.RE +.SH CONFIGURATION +.P +The configuration file takes the form of a bash(1) script.\& This file is sourced +after default variables are set.\& Use standard bash variable definitions in order +to set either environment variables found in \fBENVIRONMENT\fR, or the following +variables.\& +.P +\fBMONITOR\fR +.RS 4 +The monitor number to use to start, end, or record on.\& Default is 1.\& +.P +.RE +\fBAUDIO_DEV\fR +.RS 4 +This variable is the same as what is passed to \fI-a\fR.\& See \fBOPTIONS\fR for +more information.\& +.P +.RE +\fBVIDEO_DEV\fR +.RS 4 +This variable is the same as what is passed to \fI-V\fR.\& See \fBOPTIONS\fR for +more information.\& +.P +.RE +\fBVERBOSE\fR +.RS 4 +This variable is non-empty if verbose output should be enabled.\& Same as +\fI-v\fR.\& +.P +.RE .SH EXAMPLES .P \fBwf-shadow\fR \fI-s\fR \fI1\fR @@ -109,7 +153,7 @@ Other See output.\& .P .SH SEE ALSO .P -wf-recorder(1) wofi(1) ffmpeg(1) pactl(1) date(1) +wf-recorder(1) wofi(1) ffmpeg(1) pactl(1) date(1) bash(1) .P .SH AUTHOR Skylar "The Cobra" Widulski diff --git a/wf-shadow.1.scd b/wf-shadow.1.scd index a9cc00c..2a2664d 100644 --- a/wf-shadow.1.scd +++ b/wf-shadow.1.scd @@ -17,16 +17,17 @@ and wofi(1) in order to accomplish the task. # OPTIONS -*-s, --start* _MONITOR_ - Starts a wf-shadow instance on monitor number _MONITOR_. +*-s, --start* [_MONITOR_] + Starts a wf-shadow instance on monitor number _MONITOR_, if no _MONITOR_ + is specified, then use monitor #1. -*-r, --record* _MONITOR_ +*-r, --record* [_MONITOR_] Record the last few moments of video using a wofi(1) menu. This will use the same _MONITOR_ number as any running session of *wf-shadow*. -*-e, --end* _MONITOR_ +*-e, --end* [_MONITOR_] End the current instance running on monitor _MONITOR_. *-a, --audio* _DEVICE_ @@ -45,12 +46,43 @@ and wofi(1) in order to accomplish the task. # ENVIRONMENT -*WF_SHADOW_SAVE* +*WF_SHADOW_DIR* The path to the directory used to save clips. *WF_SHADOW_FORMAT* The date(1) _-d_ format used by *wf-shadow* to save clips. +*WF_SHADOW_SAVE* + The bash(1) command to run to get the save file for clips. The output of + the command is used as the path. Overrides *WF_SHADOW_DIR* and + *WF_SHADOW_FORMAT*. + +*WF_SHADOW_CONFIG* + The path to the configuration file used by *wf-shadow*. + See *CONFIGURATION* for how to configure *wf-shadow*. + +# CONFIGURATION + +The configuration file takes the form of a bash(1) script. This file is sourced +after default variables are set. Use standard bash variable definitions in order +to set either environment variables found in *ENVIRONMENT*, or the following +variables. + +*MONITOR* + The monitor number to use to start, end, or record on. Default is 1. + +*AUDIO_DEV* + This variable is the same as what is passed to _-a_. See *OPTIONS* for + more information. + +*VIDEO_DEV* + This variable is the same as what is passed to _-V_. See *OPTIONS* for + more information. + +*VERBOSE* + This variable is non-empty if verbose output should be enabled. Same as + _-v_. + # EXAMPLES *wf-shadow* _-s_ _1_ @@ -76,7 +108,7 @@ Other See output. # SEE ALSO -wf-recorder(1) wofi(1) ffmpeg(1) pactl(1) date(1) +wf-recorder(1) wofi(1) ffmpeg(1) pactl(1) date(1) bash(1) # AUTHOR Skylar "The Cobra" Widulski