diff --git a/README.md b/README.md index 77dc1cb..4abe5af 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,10 @@ OPTIONS: -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. - -n, --no-audio Disable audio recording. Overrides -a. + -A, --acodec CODEC Use CODEC as the audio codec in ffmpeg encoding. + -c, --vcodec CODEC Use CODEC as the video codec in ffmpeg encoding. + -n, --no-audio Disable audio recording. Overrides audio options. + -N, --no-video Disable video recording. Overrides video options. -v, --verbose Verbose output. -h, --help Show this menu. diff --git a/doc/wf-shadow.1 b/doc/wf-shadow.1 index 1f9f4e5..1b35ad7 100644 --- a/doc/wf-shadow.1 +++ b/doc/wf-shadow.1 @@ -24,10 +24,48 @@ and wofi(1) in order to accomplish the task.\& .P .SH OPTIONS .P -\fB-s, --start\fR [\fIMONITOR\fR] +\fB-A, --acodec\fR \fICODEC\fR .RS 4 -Starts a wf-shadow instance on monitor number \fIMONITOR\fR, if no \fIMONITOR\fR -is specified, then use monitor #1.\& +This option is passed directly to ffmpeg(1)'\&s \fI-acodec\fR.\& +.P +.RE +\fB-a, --audio\fR \fIDEVICE\fR +.RS 4 +This option is used in order to set the pulseaudio/pipewire-pulse device +that is recorded by \fBwf-shadow\fR.\& +.P +.RE +\fB-c, --vcodec\fR \fICODEC\fR +.RS 4 +This option is passed directly to ffmpeg(1)'\&s \fI-vcodec\fR.\& +.P +.RE +\fB-d, --debug\fR +.RS 4 +Sets the bash(1) \fI-x\fR option.\& +.P +.RE +\fB-e, --end\fR [\fIMONITOR\fR] +.RS 4 +End the current instance running on monitor \fIMONITOR\fR.\& +.P +.RE +\fB-h, --help\fR +.RS 4 +Shows a simple help menu.\& +.P +.RE +\fB-N, --no-video\fR +.RS 4 +By default, \fBwf-shadow\fR enables video recording.\& Saved between clips +over the course of a session'\&s lifetime.\& +.P +.RE +\fB-n, --no-audio\fR +.RS 4 +By default, \fBwf-shadow\fR enables the -a option of wf-recorder(1).\& This +option disables it.\& Saved between clips over the course of a session'\&s +lifetime.\& .P .RE \fB-r, --record\fR [\fIMONITOR\fR] @@ -38,21 +76,10 @@ 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-s, --start\fR [\fIMONITOR\fR] .RS 4 -End the current instance running on monitor \fIMONITOR\fR.\& -.P -.RE -\fB-a, --audio\fR \fIDEVICE\fR -.RS 4 -This option is used in order to set the pulseaudio/pipewire-pulse device -that is recorded by \fBwf-shadow\fR.\& -.P -.RE -\fB-n, --no-audio\fR -.RS 4 -By default, \fBwf-shadow\fR enables the -a option of wf-recorder(1).\& This -option disables it.\& +Starts a wf-shadow instance on monitor number \fIMONITOR\fR, if no \fIMONITOR\fR +is specified, then use monitor #1.\& .P .RE \fB-V, --video\fR \fIDEVICE\fR @@ -62,12 +89,7 @@ This option is passed directly to wf-recorder(1)'\&s \fI-d\fR option.\& .RE \fB-v, --verbose\fR .RS 4 -Show the output of wf-recorder(1), ffmpeg(1), and wofi(1) -.P -.RE -\fB-h, --help\fR -.RS 4 -Show a simple help menu +Show the output of wf-recorder(1), ffmpeg(1), and wofi(1).\& .P .RE .SH ENVIRONMENT @@ -77,16 +99,21 @@ Show a simple help menu The path to the directory used to save clips.\& .P .RE -\fBWF_SHADOW_FORMAT\fR +\fBWF_SHADOW_FMT\fR .RS 4 The date(1) \fI-d\fR format used by \fBwf-shadow\fR to save clips.\& .P .RE +\fBWF_SHADOW_EXT\fR +.RS 4 +The file extension of the saved clips.\& Matches the container +.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.\& +the command is used as the path.\& Overrides \fBWF_SHADOW_DIR\fR, +\fBWF_SHADOW_FMT\fR, and \fBWF_SHADOW_EXT\fR.\& .P .RE \fBWF_SHADOW_CONFIG\fR @@ -113,6 +140,12 @@ This variable is the same as what is passed to \fI-a\fR.\& See \fBOPTIONS\fR for more information.\& .P .RE +\fBAUDIO_CODEC\fR +.RS 4 +This variable is the same as what is passed to \fI-A\fR.\& See \fBOPTIONS\fR for +more information.\& +.P +.RE \fBNO_AUDIO\fR .RS 4 When this variable is set, audio recording will be disabled.\& @@ -124,6 +157,18 @@ This variable is the same as what is passed to \fI-V\fR.\& See \fBOPTIONS\fR for more information.\& .P .RE +\fBVIDEO_CODEC\fR +.RS 4 +This variable is the same as what is passed to \fI-c\fR.\& See \fBOPTIONS\fR for +more information.\& +.P +.RE +\fBNO_VIDEO\fR +.RS 4 +When this variable is set, video recording will be disabled in outputted +clips.\& +.P +.RE \fBVERBOSE\fR .RS 4 This variable is non-empty if verbose output should be enabled.\& Same as diff --git a/doc/wf-shadow.1.scd b/doc/wf-shadow.1.scd index 3331ea0..907bab1 100644 --- a/doc/wf-shadow.1.scd +++ b/doc/wf-shadow.1.scd @@ -17,9 +17,33 @@ and wofi(1) in order to accomplish the task. # OPTIONS -*-s, --start* [_MONITOR_] - Starts a wf-shadow instance on monitor number _MONITOR_, if no _MONITOR_ - is specified, then use monitor #1. +*-A, --acodec* _CODEC_ + This option is passed directly to ffmpeg(1)'s _-acodec_. + +*-a, --audio* _DEVICE_ + This option is used in order to set the pulseaudio/pipewire-pulse device + that is recorded by *wf-shadow*. + +*-c, --vcodec* _CODEC_ + This option is passed directly to ffmpeg(1)'s _-vcodec_. + +*-d, --debug* + Sets the bash(1) _-x_ option. + +*-e, --end* [_MONITOR_] + End the current instance running on monitor _MONITOR_. + +*-h, --help* + Shows a simple help menu. + +*-N, --no-video* + By default, *wf-shadow* enables video recording. Saved between clips + over the course of a session's lifetime. + +*-n, --no-audio* + By default, *wf-shadow* enables the -a option of wf-recorder(1). This + option disables it. Saved between clips over the course of a session's + lifetime. *-r, --record* [_MONITOR_] Record the last few moments of video using a wofi(1) menu. @@ -27,38 +51,31 @@ and wofi(1) in order to accomplish the task. This will use the same _MONITOR_ number as any running session of *wf-shadow*. -*-e, --end* [_MONITOR_] - End the current instance running on monitor _MONITOR_. - -*-a, --audio* _DEVICE_ - This option is used in order to set the pulseaudio/pipewire-pulse device - that is recorded by *wf-shadow*. - -*-n, --no-audio* - By default, *wf-shadow* enables the -a option of wf-recorder(1). This - option disables it. +*-s, --start* [_MONITOR_] + Starts a wf-shadow instance on monitor number _MONITOR_, if no _MONITOR_ + is specified, then use monitor #1. *-V, --video* _DEVICE_ This option is passed directly to wf-recorder(1)'s _-d_ option. *-v, --verbose* - Show the output of wf-recorder(1), ffmpeg(1), and wofi(1) - -*-h, --help* - Show a simple help menu + Show the output of wf-recorder(1), ffmpeg(1), and wofi(1). # ENVIRONMENT *WF_SHADOW_DIR* The path to the directory used to save clips. -*WF_SHADOW_FORMAT* +*WF_SHADOW_FMT* The date(1) _-d_ format used by *wf-shadow* to save clips. +*WF_SHADOW_EXT* + The file extension of the saved clips. Matches the container + *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*. + the command is used as the path. Overrides *WF_SHADOW_DIR*, + *WF_SHADOW_FMT*, and *WF_SHADOW_EXT*. *WF_SHADOW_CONFIG* The path to the configuration file used by *wf-shadow*. @@ -78,6 +95,10 @@ variables. This variable is the same as what is passed to _-a_. See *OPTIONS* for more information. +*AUDIO_CODEC* + This variable is the same as what is passed to _-A_. See *OPTIONS* for + more information. + *NO_AUDIO* When this variable is set, audio recording will be disabled. @@ -85,6 +106,14 @@ variables. This variable is the same as what is passed to _-V_. See *OPTIONS* for more information. +*VIDEO_CODEC* + This variable is the same as what is passed to _-c_. See *OPTIONS* for + more information. + +*NO_VIDEO* + When this variable is set, video recording will be disabled in outputted + clips. + *VERBOSE* This variable is non-empty if verbose output should be enabled. Same as _-v_. diff --git a/wf-shadow b/wf-shadow index e5c2187..7b554d5 100755 --- a/wf-shadow +++ b/wf-shadow @@ -28,11 +28,15 @@ fi MONITOR=1 AUDIO_DEV="" +AUDIO_CODEC="" NO_AUDIO="" VIDEO_DEV="" +VIDEO_CODEC="" +NO_VIDEO="" VERBOSE="" : "${WF_SHADOW_DIR:="$HOME"/Videos/wf-shadow}" -: "${WF_SHADOW_FORMAT:=%Y%m%d_%H:%M:%S}" +: "${WF_SHADOW_FMT:=%Y%m%d_%H:%M:%S}" +: "${WF_SHADOW_EXT:=mp4}" . "$CONFIG" @@ -40,6 +44,10 @@ if [ -n "$NO_AUDIO" ]; then NO_AUDIO=" " fi +if [ -n "$NO_VIDEO" ]; then + NO_VIDEO=" " +fi + trap 'kill $(jobs -p) 2>/dev/null' EXIT trap 'exit' INT set -m @@ -78,7 +86,10 @@ OPTIONS: -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. - -n, --no-audio Disable audio recording. Overrides -a. + -A, --acodec CODEC Use CODEC as the audio codec in ffmpeg encoding. + -c, --vcodec CODEC Use CODEC as the video codec in ffmpeg encoding. + -n, --no-audio Disable audio recording. Overrides audio options. + -N, --no-video Disable video recording. Overrides video options. -v, --verbose Verbose output. -h, --help Show this menu. @@ -90,18 +101,18 @@ EOF record() { local SAVE_FILE if [ ! $WF_SHADOW_SAVE ]; then - SAVE_FILE="$WF_SHADOW_DIR"/"$(date +"$WF_SHADOW_FORMAT")__$2".mp4 + SAVE_FILE="$WF_SHADOW_DIR"/"$(date +"$WF_SHADOW_FMT")__$2"."$WF_SHADOW_EXT" 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 + if ffmpeg -nostdin -y -sseof -"$2" -i "$1" ${NO_VIDEO:-${VIDEO_CODEC:+-vcodec "$VIDEO_CODEC"}} ${NO_AUDIO:-${AUDIO_CODEC:+-acodec "$AUDIO_CODEC"}} ${NO_VIDEO:+-vn} ${NO_AUDIO:+-an} "$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 else - if ffmpeg -nostdin -y -sseof -"$2" -i "$1" "$SAVE_FILE"; then + if ffmpeg -nostdin -y -sseof -"$2" -i "$1" ${NO_VIDEO:-${VIDEO_CODEC:+-vcodec "$VIDEO_CODEC"}} ${NO_AUDIO:-${AUDIO_CODEC:+-acodec "$AUDIO_CODEC"}} ${NO_VIDEO:+-vn} ${NO_AUDIO:+-an} "$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" @@ -121,6 +132,7 @@ start() { fi printf "%s" "$!" > "$RUNTIME"/"$MONITOR".pid fg || exit + . "$RUNTIME"/"$MONITOR".env case "$(if [ -n "$VERBOSE" ]; then printf "$WOFI_STRING" | wofi --dmenu -i -H 500 -W 250 -x 0 -y 0 @@ -172,12 +184,32 @@ until [ -z "$1" ]; do '-a' | '--audio') AUDIO_DEV="$2" shift 2 ;; + '-A' | '--acodec') + if [ -n "$2" ]; then + AUDIO_CODEC="$2" + shift 2 + else + print_help + fi ;; '-n' | '--no-audio') - NO_AUDIO=1 + NO_AUDIO=" " shift 1 ;; '-V' | '--video') VIDEO_DEV="$2" shift 2 ;; + '-c' | '--vcodec') + if [ -n "$2" ]; then + VIDEO_CODEC="$2" + shift 2 + else + print_help + fi ;; + '-N' | '--no-video') + NO_VIDEO=" " + shift 1 ;; + '-d' | '--debug') + set -x + shift 1 ;; '-v' | '--verbose') VERBOSE="1" shift 1 ;; @@ -185,32 +217,41 @@ until [ -z "$1" ]; do esac done +declare -p AUDIO_CODEC > "$RUNTIME"/"$MONITOR".env +declare -p NO_AUDIO >> "$RUNTIME"/"$MONITOR".env +declare -p VIDEO_CODEC >> "$RUNTIME"/"$MONITOR".env +declare -p NO_VIDEO >> "$RUNTIME"/"$MONITOR".env + +. "$RUNTIME"/"$MONITOR".env + +if [ -n "$NO_VIDEO" ] && [ -n "$NO_AUDIO" ]; then + printf "Must have either audio or video recording enabled.\n" + exit 3 +fi + 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 (%s/%d_host.pid)\n" "$MONITOR" "$RUNTIME" "$MONITOR" - fi + if [ ! -e "$RUNTIME"/"$MONITOR"_host.pid ]; then + printf "%s" "$$" > "$RUNTIME"/"$MONITOR"_host.pid + start else - print_help 1 + printf "A wf-shadow instance is already running on display %d (%s/%d_host.pid)\n" "$MONITOR" "$RUNTIME" "$MONITOR" fi fi if [ "$RECORD" == 1 ]; then - if [ "$MONITOR" ]; then + if [ -e "$RUNTIME"/"$MONITOR"_host.pid ]; then kill -2 "$(<"$RUNTIME"/"$MONITOR".pid)" else - print_help 1 + printf "No such session on monitor %d\n" "$MONITOR" fi fi if [ "$END" == 1 ]; then - if [ "$MONITOR" ]; then + if [ -e "$RUNTIME"/"$MONITOR"_host.pid ]; then kill "$(<"$RUNTIME"/"$MONITOR"_host.pid)" && rm -f "$RUNTIME"/"$MONITOR"_host.pid + rm -f "$RUNTIME"/"$MONITOR".env else - print_help 1 + printf "No such session on monitor %d\n" "$MONITOR" fi fi