Last active
February 24, 2016 22:14
-
-
Save DanielFGray/334168827097f2d11729 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
declare file="$(date +%F-%s).webm" | |
declare window=false | |
declare region=false | |
declare duration | |
declare delay=0 | |
declare verbose | |
declare -A dimensions | |
usage() { | |
more <<'HELP' | |
'Usage: record [OPTIONS] | |
-h this help | |
-f specify file name [defaults to "$(date +%F-%s).webm"] | |
-F specify file name and overwrite if exists | |
-d specify duration | |
-D specify delay | |
-w select window | |
-s draw selectable region | |
-v show verbose output from ffmpeg' | |
HELP | |
} | |
err() { | |
echo -e "\e[31m$1\e[0m" >&2 | |
} | |
die() { | |
if [[ -n "$1" ]]; then | |
err "$1" | |
fi | |
exit 1 | |
} | |
has() { | |
command -v "$1" &> /dev/null | |
} | |
ask() { | |
read -n1 -p "$* " ans | |
echo | |
[[ "${ans^}" == 'Y' ]] | |
} | |
delay() { | |
for (( i=delay; i>0; --i )) ; do | |
echo -ne "$i.. \r" | |
sleep 1 | |
done | |
echo -ne "recording \r" | |
} | |
getdimensions() { | |
if [[ "$window" == true ]]; then | |
local xwininfo x y w h | |
echo -ne 'click a window\r' | |
xwininfo=$(xwininfo) | |
read -r x y w h < <(awk -F':' '/Absolute upper-left X/ { x=$2 } | |
/Absolute upper-left Y/ { y=$2 } | |
/Width/ { w=$2 } | |
/Height/ { h=$2 } | |
END { print x, y, w, h }' <<< "$xwininfo") | |
dimensions=( ['x']="$x" ['y']="$y" ['w']="$w" ['h']="$h" ) | |
elif [[ "$region" == true ]]; then | |
has xrectsel || die 'xrectsel required for -s' | |
echo -ne 'select a region\r' | |
#TODO: don't use eval | |
eval "dimensions=( $(xrectsel "['x']='%x' ['y']='%y' ['w']='%w' ['h']='%h'") )" | |
else | |
scrsize=$(xdpyinfo | awk '/dimensions/{print $2}') | |
dimensions=( ['x']='0' ['y']='0' ['w']="${scrsize%%x*}" ['h']="${scrsize#*x}" ) | |
fi | |
} | |
record-byzanz() { | |
#TODO: remove byzanz altogether in favor of plain ffmpeg | |
byzanz-record \ | |
--duration="${duration:-10}"\ | |
--x="${dimensions['x']}"\ | |
--y="${dimensions['y']}"\ | |
--width="${dimensions['w']}"\ | |
--height="${dimensions['h']}"\ | |
"$file" && | |
echo "saved as $file" | |
} | |
record-ffmpeg() { | |
local loglevel size offset | |
loglevel='panic' | |
[[ -n $verbose ]] && loglevel='panic' | |
size="${dimensions['w']}x${dimensions['h']}" | |
offset="${DISPLAY}.0+${dimensions['x']},${dimensions['y']}" | |
ffmpeg -y -loglevel "$loglevel" -f x11grab -s "$size" -i "$offset" ${duration:+-t $duration} \ | |
-c:v libvpx -crf 12 -s "$size" -b:v 1200k \ | |
-preset veryslow \ | |
-b 1000k -threads 4 \ | |
-f webm "$file" && | |
echo "saved as $file" | |
} | |
OPTERR=0 | |
while getopts "f:F:d:D:swh" opt; do | |
case "$opt" in | |
f) file="$OPTARG"; overwrite=false ;; | |
F) file="$OPTARG"; overwrite=true ;; | |
w) window=true; region=false ;; | |
s) window=false; region=true ;; | |
v) verbose=true ;; | |
d) duration="$OPTARG" ;; | |
D) delay="$OPTARG" ;; | |
h) usage; exit 0 ;; | |
esac | |
done | |
[[ -z "$DISPLAY" ]] && die 'could not grab DISPLAY' | |
if [[ -f "$file" && "$overwrite" == false ]] && ! ask "overwrite ${file}? "; then | |
die | |
fi | |
getdimensions | |
case "$file" in | |
*gif) | |
has byzanz-record || die 'need byzanz-record for recording gifs' | |
delay | |
record-byzanz ;; | |
*webm) | |
has ffmpeg || die 'need ffmpeg for recording webms' | |
delay | |
record-ffmpeg ;; | |
*) die 'unknown file type, must be gif or webm' ;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment