#!/bin/bash set -x set -eu set -o pipefail size="" file="" tempfile="$(basename "$0").temp.flv" keep_temp=False do_postprocessing=True function usage { retval="$1" case "$retval" in 0) ;; *) exec 1>&2 ;; esac echo "Usage: --dimensions 1366x768 --output-file output.mp4 --keep-temporary --skip-postprocessing --help" echo echo "Capture a movie of the leftmost corner of your display(s), with sound, on X11 (and Wayland?)" echo echo "--dimensions specifies the dimensions of the region you want captured." echo echo "--output-file specifies the path to the file you wish to create. Different formats can be output based on the" echo "file extension." echo echo "Hit 'q' when done recording." echo echo "Video will be written to disk as fast as possible, mostly uncompressed." echo "Then after you hit 'q', the video will be transcoded to something more practical for archival." exit "$retval" } while [ "$#" -ge 1 ] do case "$1" in --dimensions) size="$2" shift ;; --output-file) file="$2" shift ;; --keep-temporary) keep_temp=True ;; --skip-postprocessing) do_postprocessing=False ;; --help|-h) usage 0 ;; *) echo "$0: unrecognized option: $1" 1>&2 usage 1 ;; esac shift done all_good=True case "$size" in "") echo "$0: --dimensions is a required option. EG --dimensions 1366x768" 1>&2 all_good=False ;; esac case "$file" in "") echo "$0: --output-file is a required option. EG --output-file /tmp/output.mp4" 1>&2 all_good=False ;; esac case "$all_good" in True) ;; False) echo "$0: one or more required options not specified" 1>&2 usage 1 ;; *) echo "$0: internal error: \$all_good is not True or False" 1>&2 exit 1 ;; esac # Based on https://www.bogotobogo.com/FFMpeg/ffmpeg_video_screencasting_screen_recording_capture.php # Seems to work as long as you don't throw too many changes at it. # I'm using this on a 5-year-old laptop: # $ ./nbench # below cmd output started 2020 Fri Apr 03 11:53:52 AM PDT # # BYTEmark* Native Mode Benchmark ver. 2 (10/95) # Index-split by Andrew D. Balsa (11/97) # Linux/Unix* port by Uwe F. Mayer (12/96,11/97) # # TEST : Iterations/sec. : Old Index : New Index # : : Pentium 90* : AMD K6/233* # --------------------:------------------:-------------:------------ # NUMERIC SORT : 1009.5 : 25.89 : 8.50 # STRING SORT : 850.75 : 380.14 : 58.84 # BITFIELD : 3.9829e+08 : 68.32 : 14.27 # FP EMULATION : 399.68 : 191.78 : 44.25 # FOURIER : 37797 : 42.99 : 24.14 # ASSIGNMENT : 40.518 : 154.18 : 39.99 # IDEA : 8058.1 : 123.25 : 36.59 # HUFFMAN : 3630.6 : 100.68 : 32.15 # NEURAL NET : 66.155 : 106.27 : 44.70 # LU DECOMPOSITION : 1966.3 : 101.86 : 73.56 # ==========================ORIGINAL BYTEMARK RESULTS========================== # INTEGER INDEX : 113.768 # FLOATING-POINT INDEX: 77.489 # Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0 # ==============================LINUX DATA BELOW=============================== # CPU : 4 CPU GenuineIntel Intel(R) Core(TM) i3-4000M CPU @ 2.40GHz 2395MHz # L2 Cache : 3072 KB # OS : Linux 4.15.0-54-generic # C compiler : gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) # libc : libc-2.27.so # MEMORY INDEX : 32.261 # INTEGER INDEX : 25.794 # FLOATING-POINT INDEX: 42.978 # Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38 # * Trademarks are property of their respective holder. # BTW, the above machine a bunch of dust clogging its CPU. After cleaning it, the system worked much better. # As a result, I've changed the first ffmpeg below from 2Hz to 10Hz. # shellcheck disable=SC2064 case "$keep_temp" in True) ;; False) trap "rm -f \"$tempfile\"" 0 ;; *) echo "$0: Internal error: \$keep_temp has a strange value: $keep_temp" 1>&2 exit 1 ;; esac case "$do_postprocessing" in True) ;; False) case "$file" in *.flv) # Good, we've been asked to do .flv ;; *) echo "$0: Sorry, with --skip-postprocessing, you must specify an .flv --output-file" 1>&2 exit 1 esac ;; *) echo "$0: internal error: \$do_postprocessing has a strange value: $do_postprocessing" 1>&2 exit 1 ;; esac ffmpeg \ -f pulse \ -ac 2 \ -i default \ -f x11grab \ -r 10 \ -s "$size" \ -i ':0.0' \ -qmin 1 \ -qmax 1 \ -vcodec flv \ -pix_fmt yuv420p \ -preset ultrafast \ -crf 0 \ -threads 0 \ -y \ "$tempfile" case "$do_postprocessing" in True) ffmpeg \ -y \ -r 30 \ -i "$tempfile" \ -ab 128k \ -ac 2 \ -vcodec libx264 \ -preset slow \ -crf 22 \ -threads 0 \ "$file" ;; False) # Move the tempfile to the output file, knowing already that we have a .flv requested for our output mv "$tempfile" "$file" ;; *) echo "$0: internal error: \$do_postprocessing has a strange value: $do_postprocessing" 1>&2 exit 1 ;; esac