bin/record (view raw)
1#!/bin/sh
2# stolen from mitch weaver
3
4: "${RECORD_FRAMERATE:=30}"
5: "${RECORD_OUTPUT_DIR:=$PWD}"
6
7mkdir -p /tmp/record
8sock=/tmp/record/sock
9pidfile=/tmp/record/pidfile
10
11msg() { printf '* %s\n' "$*" ; }
12die() { >&2 msg "$*" ; exit 1 ; }
13
14usage() {
15 die "Usage: ${0##*/} [-o output dir] [-r rate] [-f foreground]"
16}
17
18isrunning() { kill -0 "$(getpid)" 2>/dev/null ; return $? ; }
19
20getpid() {
21 [ -s $pidfile ] && read -r pid <$pidfile
22 echo "${pid:-?}"
23}
24
25start() {
26 isrunning && die "Another instance already exists: $(getpid)"
27
28 file="$RECORD_OUTPUT_DIR/record-$(date "+%Y.%m.%d-%H:%M:%S").mp4"
29 :>$sock
30
31 if command -v xrectsel >/dev/null ; then
32 xrectsel -f '%x %y %w %h'
33 elif command -v slop >/dev/null ; then
34 slop -f '%x %y %w %h'
35 else
36 die 'Needs xrectsel or slop'
37 fi | {
38 read -r x y w h
39
40 <$sock ffmpeg -y -f x11grab -s "${w}x${h}" -r $RECORD_FRAMERATE \
41 -i "${DISPLAY:-:0}+${x},${y}" -vcodec libx264 \
42 -pix_fmt yuv420p -filter:v "crop=iw-mod(iw\\,2):ih-mod(ih\\,2)" \
43 "$file" >/tmp/record/log 2>&1 &
44
45 msg "recording on pid $!"
46
47 if ${FOREGROUND:-false} ; then
48 trap 'rm "$sock" /tmp/record/log 2>/dev/null ||: ; rmdir /tmp/record 2>/dev/null ||:' EXIT INT TERM
49 wait
50 else
51 echo $! >$pidfile
52 echo "$file" >/tmp/record/file
53 fi
54 }
55}
56
57end() {
58 if isrunning ; then
59 echo q >>$sock
60 read -r name </tmp/record/file
61 msg "Success! Saved as $name"
62 rm /tmp/record/* 2>/dev/null ||:
63 rmdir /tmp/record 2>/dev/null ||:
64 exit
65 else
66 die 'Nothing being recorded.'
67 fi
68}
69
70toggle() {
71 if isrunning ; then
72 end
73 else
74 start
75 fi
76}
77
78while [ "$1" ] ; do
79 case $1 in
80 -f)
81 FOREGROUND=true
82 ;;
83 -r)
84 RECORD_FRAMERATE=$1
85 ;;
86 -o)
87 [ -d "$2" ] || usage
88 RECORD_OUTPUT_DIR=$2
89 shift
90 ;;
91 *) usage
92 esac
93 shift
94done
95
96toggle