summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2022-11-18 18:23:24 +0100
committerRobert Günzler <r@gnzler.io>2022-11-18 18:38:23 +0100
commit8b0dc4835248397303ba932235394a726ad05309 (patch)
treed01429e99af207c87a67696afa00a8d6560bbc7f
parent0227628fbffc6dd8be20e197a98807c099c3be4f (diff)
bin/wfez: refactor
-rwxr-xr-xbin/wfez163
1 files changed, 83 insertions, 80 deletions
diff --git a/bin/wfez b/bin/wfez
index eac1b55..45ef438 100755
--- a/bin/wfez
+++ b/bin/wfez
@@ -2,98 +2,101 @@
 set -e
 [ -n "$DEBUG" ] && set -x
 
-# check requirements
-for tool in wf-recorder wshowkeys pactl swq; do
-	if ! command -v "$tool" >/dev/null; then
-		printf "%s: %s not installed but required\n" "$(basename "$0")" "$tool" >&2
-		exit 1
-	fi
-done
-
-
-
-audio_output=${WF_AOUT}
-audio_input=${WF_AIN}
-video_output=${WF_VOUT}
-showkeys=${WF_KEYS}
-mux_sink=${WF_AMUX}
-no_mux=
+audio="$(pactl info | grep "Default Sink" | cut -d':' -f2 | xargs -L1).monitor"
+output=$(swq current output)
+showkeys=
+ask=
+crop=
+hwacc=
+output_file="${HOME}/Videos/wf_$(date +%FT%T).mkv"
 
-while getopts i:o:m:v:kMh opt; do
-	case "$opt" in
-	i)	# audio in
-		audio_input="${OPTARG}" ;;
-	o)	# audio out
-		audio_output="${OPTARG}" ;;
-	m)	# mux
-		mux_sink="${OPTARG}" ;;
-	v)	# output to record
-		video_output="${OPTARG}" ;;
-	k)	# showkeys
-		showkeys=1 ;;
-	M)	# no mux
-		no_mux=1 ;;
-	h|?)
-		printf "usage: %s [-iomvkM] [FILE]\n" "$(basename "$0")"
-		printf "\n"
-		printf " Launches wf-recorder(1) with optimized settings.\n"
-		printf " When FILE is omitted, \$HOME/Videos/rec_TIMESTAMP.mkv is used.\n"
-		printf "\n"
-		printf " -o \t\taudio output; defaults to default pulseaudio sink\n"
-		printf " -i \t\taudio input; defaults to default pulseaudio source, can be 'none'\n"
-		printf " -m \t\taudio mux sink; override creation of an pulseaudio sink for muxing\n"
-		printf " -v \t\toutput to record; limit to output, defaults to focused output (swq current output)\n"
-		printf " -k \t\tlaunches wshowkeys(1)\n"
-		printf " -M \t\tdon't create a audio mux sink\n"
-		printf "\n"
-		exit 2 ;;
+optstring="a:o:kAcHnh"
+while getopts "${optstring}" opt; do
+	case "${opt}" in
+	a) audio="${OPTARG}" ;;
+	o) output="${OPTARG}" ;;
+	k) showkeys=1 ;;
+	A) ask=1 ;;
+	c) crop=1 ;;
+	H) hwacc=1 ;;
+	h | ?)
+		printf 'usage: %s [-%s] [FILE]\n' "$(basename "$0")" "$(printf '%s' "${optstring}" | tr -d ':')"
+		printf '\n'
+		printf ' Launches wf-recorder(1) with optimized settings.\n'
+		printf ' When FILE is omitted, use %s.\n' "${output_file}"
+		printf '\n'
+		printf ' -a  audio to record (default: %s)\n' "${audio}"
+		printf ' -o  output to record (default: %s)\n' "${output}"
+		printf ' -k  show keypresses; using wshowkeys(1)\n'
+		printf ' -A  select audio/output interactively\n'
+		printf ' -c  select an area of the screen to be recorded; using slurp(1)\n'
+		printf ' -H  enable hardware-accelerated recording (usually reduces quality)\n'
+		printf '\n'
+		exit 2
+		;;
 	esac
 done
 shift $((OPTIND - 1))
 
-output_file=${1:-"${HOME}/Videos/rec_$(now).mkv"}
+[ -n "${1}" ] && output_file=$1
 
-# setup defaults
-[ -z "${audio_output}" ] && audio_output=$(pactl info | grep "Default Sink" | cut -d':' -f2 | xargs -L1)
-[ -z "${audio_input}" ] && audio_input=$(pactl info | grep "Default Source" | cut -d':' -f2 | xargs -L1)
-[ -z "${video_output}" ] && video_output=$(swq current output)
-
-if [ "${audio_input}" = "none" ] && [ -z "${mux_sink}" ]; then
-	echo "mux: ${audio_output}"
-	mux_sink="${audio_output}"
+# select audio sink to record
+if [ ! "${audio}" = "none" ] && [ -n "${ask}" ]; then
+	audio=$(MENU_PROMPT="wfez: choose audio:" soundswitch -j -O)
+	audio="${audio}.monitor"
 fi
 
-if [ -z "${mux_sink}" ] && [ -z "${no_mux}" ]; then
-	mux_sink=wf-mux
-	mux_sink_id=
-	output_loopback_id=
-	input_loopback_id=
-	prepare_mux_sink() {
-		mux_sink_id=$(pactl load-module module-null-sink sink_name="${mux_sink}" channels=2)
-		output_loopback_id=$(pactl load-module module-loopback sink="${mux_sink}" source="${audio_output}.monitor" remix=true)
-		input_loopback_id=$(pactl load-module module-loopback sink="${mux_sink}" source="${audio_input}" channels=1 remix=true)
-	}
-	teardown_mux_sink() {
-		pactl unload-module "${mux_sink_id}"
-		pactl unload-module "${output_loopback_id}"
-		pactl unload-module "${input_loopback_id}"
-	}
-	trap '{ teardown_mux_sink >/dev/null; }' EXIT
-	prepare_mux_sink >/dev/null
-	echo "mux: ${mux_sink}"
-fi
+[ ! "${audio}" = "none" ] && audio_arg="-a ${audio}"
 
-if [ -n "${no_mux}" ]; then
-	mux_sink="${audio_output}.monitor"
-fi
+# select output to record
+[ -n "${ask}" ] && output=$(slurp -o)
 
 if [ -n "${showkeys}" ]; then
-	echo "Starting wshowkeys on ${video_output}"
-	echo "WARNING: currently the -o flag to force display to a specific output is not implemented" >&2
-	#  -o ${video_output}
-	sway exec "wshowkeys -a bottom -a left -F 'Iosevka Sparkle 25' -t 1" >/dev/null
+	printf "Starting wshowkeys on %s\n" "${output}"
+	pritnf "WARNING: currently the -o flag to force display to a specific output is not implemented\n" >&2
+	#  -o ${output}
+	sway exec "wshowkeys -a bottom -a left -F 'Iosevka Aile 25' -t 1" >/dev/null
 	trap '{ pkill wshowkeys; }' EXIT
 fi
 
+if [ -n "${crop}" ]; then
+	selection=
+	case $(printf "manual\nworkspace\ncontainer\n" | MENU_PROMPT="wfez: crop mode" menu -l5) in
+	manual)
+		geom=$(slurp -f "%o:%x,%y %wx%h")
+		;;
+	container)
+		selection=$(swq list con | jq -r '.[]|select(.name? and .visible?==true)|[.id, .name, (.type=="floating_con")]|join("\t")' | awk '{c="swq locate output-for-con "$1" | jq -r \"first | .name\""; c|getline o; close(c); printf "%3s\t%10s\t%8s\t%s\n", $1, $2, ($3 == "true" ? "floating" : "normal"), o}' | MENU_PROMPT="wfez: select container" menu -l5)
+		con_id=$(printf '%s' "$selection" | awk '{print $1}')
+		con_pos=$(swq has id "$con_id" | swq geometry)
+		con_out=$(swq | jq -r --argjson a "{\"id\":$con_id}" '..|select(.type?=="workspace" and (([.floating_nodes[], .nodes[]])|..|select(.id?==$a.id)))|.output')
+		geom="${con_out}:${con_pos}"
+		;;
+	*)
+		printf "not implemented\n" >&2
+		exit 1
+		;;
+	esac
+	output="$(printf '%s' "${geom}" | cut -d: -f1)"
+	geometry_arg="-g $(printf '%s' "${geom}" | cut -d: -f2-)"
+fi
+
+if [ -n "${hwacc}" ]; then
+	hwacc_arg='-c h264_vaapi -d /dev/dri/renderD128'
+fi
+
+makoctl set-mode off
+
 set -x
-wf-recorder -c h264_vaapi -d /dev/dri/renderD128 -x nv12 -o "${video_output}" -a "${mux_sink}.monitor" -f "${output_file}"
+wf-recorder -o "${output}" "${audio_arg}" "${geometry_arg}" "${hwacc_arg}" -f "${output_file}"
+set +x
+
+if [ ! "${audio}" = "none" ]; then
+	# correct mono audio in stereo channel
+	mv "${output_file}" /tmp/wfrec_tmp.mkv
+	trap '{ rm /tmp/wfrec_tmp.mkv; }' EXIT
+	ffmpeg -hide_banner -i /tmp/wfrec_tmp.mkv -vcodec copy -af "pan=mono|c0=c0" "${output_file}"
+fi
+
+makoctl set-mode ''
+notify-send wfez "$output_file"