t004-screencasts.html - adamsgaard.dk - my academic webpage
git clone git://src.adamsgaard.dk/adamsgaard.dk
Log
Files
Refs
README
LICENSE
---
t004-screencasts.html (4532B)
---
     1 

On Monday 2020-03-16 the buildings of the danish public 2 sector were closed as an emergency response to COVID-19. This 3 includes Aarhus University where I teach two undergraduate courses. 4 The university asks lecturers to move their teaching to digital 5 platforms. As many times before, this requires creative thinking 6 for those of us who do not use Microsoft and Apple products.

7 8

I needed a way to record my pdf slideshows while talking over 9 the presentation. Ideally, I also wanted the ability to show the 10 video of my webcam as an overlay in an attempt to make the presentation 11 a bit more engaging when explaining complex parts.

12 13

Fortunately, ffmpeg(1) makes 14 it easy to record the screen and laptop audio. I want to keep the 15 fan noise low during recording by applying minimal compression and 16 encoding. The following shell script serves the purpose of starting 17 and stopping recording:

18 19
#!/bin/sh
    20 lockfile=/tmp/screenrecord.pid
    21 
    22 startrecording() {
    23     out="$HOME/screenrecord-$(date '+%Y-%m-%d_%H:%M:%S').mkv"
    24     ffmpeg -y \
    25         -f x11grab \
    26         -framerate 60 \
    27         -s "$(xdpyinfo | grep dimensions | awk '{print $2}')" \
    28         -i $DISPLAY \
    29         -f sndio -i default \
    30         -r 30 \
    31         -c:v libx264rgb -crf 0 -preset ultrafast -c:a flac \
    32         "$out" >/dev/null 2>&1 &
    33     printf '%s' "$!" > "$lockfile"
    34 
    35     sleep 1
    36     if [ ! -f "$out" ]; then
    37         echo 'error: ffmpeg recording did not start' >&2
    38         notify-send -u CRITICAL "${0##*/}" 'ffmpeg recording did not start'
    39         rm -f "$lockfile"
    40         exit 1
    41     fi
    42 }
    43 
    44 stoprecording() {
    45     kill "$(cat "$lockfile")"
    46     rm -f "$lockfile"
    47     notify-send "${0##*/}" 'recording ended'
    48 }
    49 
    50 if [ -f "$lockfile" ]; then
    51     stoprecording
    52 else
    53     startrecording
    54 fi
    55 
56 57

I have bound the above script to the key binding Alt+r which 58 makes it easy to start and stop recording in my X session.

59 60

On Linux systems, the sound driver sndio should be replaced 61 by alsa in the above ffmpeg(1) command. Audio recording is 62 disabled by default on OpenBSD, but can be permanently enabled with 63 the following commands:

64 65
# sysctl kern.audio.record=1
    66 # echo kern.audio.record=1 >> /etc/sysctl.conf
    67 
68 69

On OpenBSD I can show the webcam video feed with the video(1) command. 71 The following script toggles the video feed:

72 73

#!/bin/sh
    74 # remember to `chown $USER /dev/video0`
    75 if pgrep video >/dev/null 2>&1; then
    76     pkill video
    77 else
    78     nohup video -s 320 >/dev/null 2>&1 &
    79 fi
    80 
81 82

On Linux, the command mpv /dev/video0 can take 83 place of the video(1) command above. I have the above script bound 84 to the keybinding Alt+v so I can quickly show and hide my face while 85 recording.

86 87

I set dwm(1), my window 88 manager, to open the video feed as a floating window on the bottom 89 right of the screen. The full dwm configuration can be found here.

91 92

When I am done recording a lecture, I encode and compress the 93 video file to save bandwidth during upload. The following script 94 encodes all input files and reduces file size to roughly 15% without 95 concievable loss in quality:

96 97
#!/bin/sh
    98 
    99 encode() {
   100     ffmpeg -y -i "$1" \
   101         -c:v libx264 -threads 0 -preset faster -pix_fmt yuv420p \
   102         -c:a aac -crf 10 \
   103         "${1%.*}_out.mp4"
   104 }
   105 
   106 for f in "$@"; do
   107     encode "$f"
   108 done
   109 
110 111

If there is a delay between video and audio, this can also be 112 adjusted using ffmpeg(1). I correct for a 0.3 s delay that I 113 encounter when recording on my laptop:

114 115
#!/bin/sh
   116 
   117 synchronize() {
   118     ffmpeg -y -i "$1" \
   119         -itsoffset 0.300 \
   120         -i "$1" \
   121         -map 0:v -map 1:a \
   122         -c copy \
   123         "${1%.*}_out.${1##*.}"
   124 }
   125 
   126 for f in "$@"; do
   127     synchronize "$f"
   128 done
   129 
130 131
132 139
140 Example screen recording using ffmpeg(1) and video(1) 141 with the above scripts. 142
143
144