#!/bin/sh set -e VIRTMON=virtmon SC_FONT=${SC_FONT:-'WenQuanYi-Micro-Hei'} PID_FILE="/tmp/recording.pid" OUTPUT_DIR="$HOME/Videos" _stop_recording() { killall screenkey 2>/dev/null || true if [ -f "$PID_FILE" ]; then PID=$(cat "$PID_FILE") [ -n "$PID" ] && kill -s 15 $PID || true rm "$PID_FILE" fi } _start_video_recording() { _stop_recording if [ "$#" -ne 5 ]; then echo "expected x y w h fps , got $argv" exit 1 fi X=$1 Y=$2 W=$3 H=$4 FPS=${5:-30} OUTPUT_FILE="$OUTPUT_DIR/screencast-$(date '+%y%m%d-%H%M-%S').mp4" touch "$PID_FILE" sleep 1 echo recording to $OUTPUT_FILE # ffmpeg \ # -f x11grab -s $W'x'$H -i "$DISPLAY+$X,$Y" \ # -f alsa -i default \ # -r $FPS -c:v h264 -crf 0 -preset ultrafast \ # -c:a aac \ # $OUTPUT_FILE ffmpeg \ -f x11grab -s $W'x'$H -i "$DISPLAY+$X,$Y" \ -f alsa -i default \ -r $FPS -c:v h264 -crf 0 -preset ultrafast \ -c:a aac \ $OUTPUT_FILE > /dev/null 2>&1 "$PID_FILE" } audio() { _stop_recording OUTPUT_FILE="$OUTPUT_DIR/audio-$(date '+%y%m%d-%H%M-%S').aac" touch "$PID_FILE" sleep 1 ffmpeg \ -f alsa -i default \ -c:a aac \ $OUTPUT_FILE > /dev/null 2>&1 "$PID_FILE" echo $OUTPUT_FILE } theend() { notify-send "recording ended" _stop_recording } prepare() { # wanted size WW=${1:-1920} WH=${2:-1080} # actual size # 0: +*DP-1 3440/797x1440/333+0+0 DP-1 # resolution / physical WHXY=$(xrandr --listmonitors | awk '$2 ~ /\*/ { split($3, WHXY, /x|+|\//) match($2, /\*(.+)$/, name) print WHXY[1] " " WHXY[2] " " WHXY[3] " " WHXY[4] " " WHXY[5] " " WHXY[6] " " name[1] }') W=$(echo "$WHXY" | awk '{print $1}') PW=$(echo "$WHXY" | awk '{print $2}') H=$(echo "$WHXY" | awk '{print $3}') PH=$(echo "$WHXY" | awk '{print $4}') X=$(echo "$WHXY" | awk '{print $5}') Y=$(echo "$WHXY" | awk '{print $6}') NAME=$(echo "$WHXY" | awk '{print $7}') # rest size RW=$(( $W - $WW )) RH=$(( $H - $WH )) if [ "$RW" -lt 0 ] && [ "$RH" -lt 0 ]; then return 0 fi # adjust rest size, either split horizontally or vertically # physical size for wanted monitor PWW=$(echo "scale=3; r = $WW / $W * $PW; scale=0; r / 1" | bc) PWH=$(echo "scale=3; r = $WH / $H * $PH; scale=0; r / 1" | bc) if [ "$RW" -gt 0 ]; then # horizontally PRW=$(( $PW - $PWW )) PRH=$PH RH=$H RX=$WW RY=0 fi # echo WW $WW # echo PWW $PWW # echo WH $WH # echo PWH $PWH # echo X $X # echo Y $Y # echo RW $RW # echo PRW $PRW # echo RH $RH # echo PRH $PRH # echo RX $RX # echo RY $RY # exit # create virtual monitors echo xrandr --setmonitor $VIRTMON-1 "${WW}/${PWW}x${WH}/${PWH}+0+0" $NAME echo xrandr --setmonitor $VIRTMON-2 "${RW}/${PRW}x${RH}/${PRH}+${RX}+${RY}" none echo nitrogen --restore } finish() { xrandr --delmonitor $VIRTMON-1 xrandr --delmonitor $VIRTMON-2 nitrogen --restore } window() { FPS=${1:-5} notify-send "Please click the window that you want to record" WININFO=$(xwininfo) X=$(echo "$WININFO" | awk -F: '$1 ~ /Absolute upper-left X/ { print $2 }') Y=$(echo "$WININFO" | awk -F: '$1 ~ /Absolute upper-left Y/ { print $2 }') W=$(echo "$WININFO" | awk -F: '$1 ~ /Width/ { print $2 }') H=$(echo "$WININFO" | awk -F: '$1 ~ /Height/ { print $2 }') _start_video_recording $X $Y $W $H $FPS } desktop() { FPS=${1:-30} # INPUT 0: +*DP-1 3440/797x1440/333+2560+80 DP-1 # OUTPUT 2560 80 3440 1440 XYWH=$(xrandr --listmonitors | awk '$2 ~ /\*/ { split($3, pos, /\/|\+|x/) print pos[5] " " pos[6] " " pos[1] " " pos[3] }') # pacmd set-source-volume noechosource 52000 _start_video_recording $XYWH $FPS } togif() { IN_FILE=$1 OUTPUT_FILE=$1 convert -set delay 10 -layers Optimize $IN_FILE -ordered-dither o8x8,23 +map $OUTPUT_FILE } cover() { IN_FILE=$1 TEXT=$2 OUTPUT=${3:-'cover.png'} GRAVITY=${4:-'center'} X=50 if [ "$GRAVITY" = "50" ]; then X=0 fi magick convert $IN_FILE -thumbnail 1146x -background black -gravity $gravity -extent 1146x717 resized.png magick convert resized.png \ -blur 0x8 \ -gravity $GRAVITY \ -fill black \ -pointsize 120 -font $SC_FONT \ -interline-spacing 20 \ -stroke '#e1e1e1' -strokewidth 40 \ -annotate +$X+0 "$TEXT" \ -stroke '#000000' -strokewidth 5 \ -annotate +$X+0 "$TEXT"\ $OUTPUT_FILE } if [ "$#" -eq 0 ]; then desktop else $@ fi