diff options
| author | Robert Günzler <r@gnzler.io> | 2022-11-18 18:23:24 +0100 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2022-11-18 18:38:23 +0100 |
| commit | 8b0dc4835248397303ba932235394a726ad05309 (patch) | |
| tree | d01429e99af207c87a67696afa00a8d6560bbc7f | |
| parent | 0227628fbffc6dd8be20e197a98807c099c3be4f (diff) | |
bin/wfez: refactor
| -rwxr-xr-x | bin/wfez | 163 |
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" |