diff --git a/wf-shadow-tui b/wf-shadow-tui new file mode 100755 index 0000000..d60e694 --- /dev/null +++ b/wf-shadow-tui @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +RUNTIME="${XDG_RUNTIME_DIR:-/run}/wf-shadow" +CONFIG="${WF_SHADOW_CONFIG:-${XDG_CONFIG_HOME:-$HOME/.config}/wf-shadow/config.sh}" + +AUDIO_DEV="" +AUDIO_CODEC="" +NO_AUDIO="" +VIDEO_DEV="" +VIDEO_CODEC="" +NO_VIDEO="" +: "${WF_SHADOW_DIR:="$HOME"/Videos/wf-shadow}" +: "${WF_SHADOW_FMT:=%Y%m%d_%H:%M:%S}" +: "${WF_SHADOW_EXT:=mp4}" + +. "$CONFIG" + +TITLE='--title wf-shadow-tui' + +if command -v tput &>/dev/null; then + tput smcup +fi + +trap 'if command -v tput &>/dev/null; then tput rmcup; fi' EXIT + +get_output() { + RANDR="$(wlr-randr)" + i=0 + while read -r line; do + if [[ "$line" =~ - ]]; then + ((i++)) + fi + done <<< "$RANDR" + OUTPUT="$(eval "dialog $TITLE --menu 'Output:' 24 64 24 $(while read -r line; do + if [[ "$line" =~ - ]]; then + tmp="${line#*(}" + tmp="${tmp%)*}" + printf "$i '(%s) \t" "$tmp" + + tmp=${line#*\"} + tmp="${tmp% (*}" + printf "%s' " "$tmp" + + ((i--)) + fi + done <<< "$RANDR") 3>&1 1>&2 2>&3")" +} + +get_action() { + ACTION="$(eval "dialog $TITLE --menu 'Action for output $OUTPUT:' 24 64 24 $([ ! -f "$RUNTIME/${OUTPUT}_host.pid" ] && printf "'Start' 'Start a session of wf-shadow on this output'") $([ -f "$RUNTIME/${OUTPUT}_host.pid" ] && printf "'Record' 'Clip the last few seconds of video' 'End' 'End the wf-shadow session'") 3>&1 1>&2 2>&3")" +} + +get_seconds() { + TIME="$(eval "dialog $TITLE --inputbox 'Seconds to clip:' 0 0 30 3>&1 1>&2 2>&3")" +} + +get_seconds_wrap() { + unset TIME + get_seconds + if [ -z "$TIME" ]; then + get_action_wrap + else + wf-shadow -R "$OUTPUT" "$(<"$RUNTIME/${OUTPUT}_current")" "$TIME" + fi +} + +get_output_wrap() { + unset OUTPUT + get_output + if [ -z "$OUTPUT" ]; then + get_main_wrap + else + get_action_wrap + fi + +} + +get_action_wrap() { + unset ACTION + get_action + if [ -z "$ACTION" ]; then + get_output_wrap + else + case "$ACTION" in + Start) + wf-shadow --start "$OUTPUT" &>/dev/null & disown + get_action_wrap ;; + End) + wf-shadow --end "$OUTPUT" + get_action_wrap ;; + Record) get_seconds_wrap ;; + esac + fi +} + +get_option() { + OPTION="$(eval "dialog $TITLE --menu "Configuration" 24 125 24 'AUDIO_DEV' 'PulseAudio device to record' 'AUDIO_CODEC' 'FFmepg audio codec' 'NO_AUDIO' 'Whether or not no audio should be recorded' 'VIDEO_DEV' 'DRI render device (/dev/dri/renderDxxx) to use to encode video' 'VIDEO_CODEC' 'FFmpeg video codec' 'NO_VIDEO' 'Whether or not no video should be encoded into the final clips' 'WF_SHADOW_DIR' 'Directory to store clips in' 'WF_SHADOW_FMT' '\`date\` format to use in file names of clips' 'WF_SHADOW_EXT' 'Container and file extension to use in clip file names' 'WF_SHADOW_SAVE' 'Command used to get the path to the file in which clips should be saved. Overrides the last 3 options.' 3>&1 1>&2 2>&3")" +} + +option_inputbox() { + eval "dialog $TITLE --inputbox '$1' 0 '$2' $3 3>&1 1>&2 2>&3" +} + +option_yesno() { + eval "dialog $TITLE --yesno 'NO_$1' 5 24 3>&1 1>&2 2>&3" + case $? in + 0) printf 1 ;; + esac +} + +option_dir() { + eval "dialog $TITLE --dselect $HOME 60 80 3>&1 1>&2 2>&3" +} + +config_to_file() { + declare -p AUDIO_DEV > "$CONFIG" + declare -p AUDIO_CODEC >> "$CONFIG" + declare -p NO_AUDIO >> "$CONFIG" + declare -p VIDEO_DEV >> "$CONFIG" + declare -p VIDEO_CODEC >> "$CONFIG" + declare -p NO_VIDEO >> "$CONFIG" + declare -p WF_SHADOW_DIR >> "$CONFIG" + declare -p WF_SHADOW_FMT >> "$CONFIG" + declare -p WF_SHADOW_EXT >> "$CONFIG" + declare -p WF_SHADOW_SAVE >> "$CONFIG" +} + +get_option_wrap() { + unset OPTION + get_option + case "$OPTION" in + AUDIO_DEV) AUDIO_DEV="$(option_inputbox AUDIO_DEV 120 $(pactl list sources | sed -n 's/\s*Name:\s*\(.*\)/\1/p' | tail -1 2>/dev/null))" ;; + AUDIO_CODEC) AUDIO_CODEC="$(option_inputbox AUDIO_CODEC 24 aac)" ;; + NO_AUDIO) NO_AUDIO="$(option_yesno AUDIO)" ;; + VIDEO_DEV) VIDEO_DEV="$(option_inputbox VIDEO_DEV 64 /dev/dri/renderD128)" ;; + VIDEO_CODEC) VIDEO_CODEC="$(option_inputbox VIDEO_CODEC 24 libx264)" ;; + NO_VIDEO) NO_VIDEO="$(option_yesno VIDEO)" ;; + WF_SHADOW_DIR) WF_SHADOW_DIR="$(option_dir)" ;; + WF_SHADOW_FMT) WF_SHADOW_FMT="$(option_inputbox WF_SHADOW_FMT 24 %Y%m%d_%H:%M:%S)" ;; + WF_SHADOW_EXT) WF_SHADOW_EXT="$(option_inputbox WF_SHADOW_EXT 24 mp4)" ;; + WF_SHADOW_SAVE) WF_SHADOW_SAVE="$(option_inputbox WF_SHADOW_SAVE 120 '')" ;; + *) config_to_file; get_main_wrap; exit ;; + esac + get_option_wrap +} + +get_main() { + MAIN="$(eval "dialog $TITLE --menu 'Main Menu' 9 64 9 'Outputs' 'Start, record, or end a wf-shadow session' 'Config' 'Configure wf-shadow' 3>&1 1>&2 2>&3")" +} + +get_main_wrap() { + unset MAIN + get_main + case "$MAIN" in + Outputs) get_output_wrap ;; + Config) get_option_wrap ;; + esac +} + +get_main_wrap