#!/bin/sh # record - record an area of the screen lock="/tmp/record.lock" # dependencies: ffmpeg, hacksaw (part), xwininfo & lsw (window), xdotool (active) # optional: # - hacksaw: part # - xwininfo, lsw, commander: window # - xdotool: active # - xdg-user-dir audio= # $1: width # $2: height # $3: x # $4: y # $5: output dir # $6: output name record_cmd() { if [ -f "$lock" ] then >&2 printf 'already recording, please stop recording first\n' exit 1 else touch "$lock" fi herbe "started recording." & w=$(($3 + $3 % 2)) h=$(($4 + $4 % 2)) ffmpeg $audio \ -v 16 \ -r 30 \ -f x11grab \ -s "${w}x${h}" \ -i ":0.0+$1,$2" \ -preset slow \ -c:v h264 \ -pix_fmt yuv420p \ -crf 20 \ "$5/$6.mp4" printf '%s\n' "$5/$6.mp4" rm -f "$lock" herbe "stopped recording." & } if [ -d "$1" ] then dir="$1" shift else dir="$(which xdg-user-dir > /dev/null 2>&1 && xdg-user-dir VIDEOS)" [ "$dir" ] && dir="$dir/records" || dir="$HOME/vids/records" fi mkdir -p "$dir" if [ "$1" = "-a" ] then audio="-f pulse -ac 2 -i default" shift fi if [ "$1" = "-l" ] then find vids/records/ -type f | sort | tail -n 1 exit fi current=$(date +%F_%H-%M-%S) [ "$1" ] && option="$1" || option="$(printf 'active\nwindow\npart\nstop\nfull\naudio' | commander -c)" case "$option" in active) record_cmd $(xwininfo -id "$(xdotool getactivewindow)" | sed -e '/Absolute\|Width:\|Height:/!d;s/.*:\s*//' | tr '\n' ' ') $dir $current ;; window) winid="$(lsw | commander -cxl | cut -d' ' -f1)" [ "$winid" ] || exit 1 values="$(xwininfo -id "$winid" | sed -e '/Absolute\|Width:\|Height:/!d;s/.*:\s*//' | tr '\n' ' ')" [ "$values" ] || exit 1 record_cmd $values $dir $current ;; part) hacksaw | { IFS=+x read -r w h x y record_cmd $w $h $x $y $dir $current } ;; stop) kill "$(pgrep ffmpeg | xargs ps | grep 'x11grab' | awk '{print $1}')"; rm -f "$lock" ;; full) record_cmd 0 0 1920 1080 $dir $current ;; audio) $0 -a; exit ;; help|*) >&2 printf 'record [dir] (active|window|part|stop|full)\n' ;; esac