#!/bin/sh
### recx.sh  -*- Sh -*-
## Record animations with XTerm, Xvfb and Ffmpeg.

### Ivan Shmakov, 2020

## To the extent possible under law, the author(s) have dedicated
## all copyright and related and neighboring rights to this software
## to the public domain worldwide.  This software is distributed
## without any warranty.

## You should have received a copy of the CC0 Public Domain Dedication
## along with this software.  If not, see
## <http://creativecommons.org/publicdomain/zero/1.0/>.

### Example:

##  $ DISPLAY= sh -- recx.sh  10 "$(date +%s.%N)".  jimsh anim.tcl 

## (That is: 10 s duration, output file prefix, and the command line.)

## Set XRESOURCES (default: ~/.Xresources) to the resource file to load
## with xrdb(1) upon Xvfb(1) startup.

## Set XTERMOPTS (default: -ah) to pass additional arguments to xterm(1).
## (Say, "-ah -geometry 80x30+0+0 -xrm XTerm.vt100.initialFont:5" for
## a 720x540 window with default XTerm.VT100.font5 9x15 or -misc-fixed-
## font.)

## Set FFMPEGOPTS (default: -v fatal -framerate 23 -r 23 -draw_mouse 0)
## to pass additional arguments to ffmpeg(1).

## Set XVFBOPTS (default: -nolisten tcp) to pass additional arguments
## to Xvfb(1).

### Code:

set -e
set -C -u

## NB: we only start our own X server if no DISPLAY is provided

: "${XVFBOPTS=-nolisten tcp}"

xpid=
if [ -z "${DISPLAY-}" ] ; then
    ## FIXME: too much hardcoding
    DISPLAY=:15
    Xvfb "$DISPLAY" -noreset ${XVFBOPTS} &
    xpid=$!
    ## NB: wait for Xvfb to start
    sleep 1s
    export DISPLAY
    : "${XRESOURCES:=${HOME}/.Xresources}"
    test -r "$XRESOURCES" \
        && xrdb -merge < "$XRESOURCES"
fi

: "${FFMPEGOPTS=-v fatal -framerate 23 -r 23 -draw_mouse 0}"
: "${XTERMOPTS=-ah}"

## FIXME: xwininfo does seem to only give the relevant data
##        (and in the convenient format) with -children
## FIXME: apparently -ss is of little use with x11grab, so ensure
##        that ffmpeg gets started after the animation itself
xterm ${XTERMOPTS} -e sh -Ceuc '\
    sleep 1s ; \
    dur=${1} ; p=${2} ; shift 2 ; \
    geom=$(xwininfo -id "$WINDOWID" -children \
               | sed -e "/.*\s\([0-9]\+x[0-9]\++[0-9]\++[0-9]\+\)\>.*/!d; s//\1/; q;") ; \
    "$@" & \
    sleep .5s ; \
    ffmpeg ${FFMPEGOPTS} -f x11grab -t "$dur" \
        -video_size "${geom%%+*}" -i "${DISPLAY}+${geom#*+}" \
        -pix_fmt yuv420p -an "$p"webm ; \
    sleep .5s ; \
    xwd -id "$WINDOWID" | lzip -3c > "$p"xwd.lz & \
    wait ; ' dummy.sh "$@"

test -z "$xpid" \
    || kill -- "$xpid"

### recx.sh ends here
