refactor: turn sc to posix script

This commit is contained in:
Klesh Wong 2022-08-28 22:37:00 +08:00
parent 2bbc7df77e
commit 25d1800294

336
bin/sc
View File

@ -1,215 +1,191 @@
#!/bin/fish #!/bin/sh
set VIRTMON virtmon set -e
set -q SC_FONT; or set SC_FONT 'WenQuanYi-Micro-Hei' VIRTMON=virtmon
SC_FONT=${SC_FONT:-'WenQuanYi-Micro-Hei'}
PID_FILE="/tmp/recording.pid"
OUTPUT_DIR="/home/klesh/Videos"
function _stop _stop_recording() {
killall screenkey 2>/dev/null killall screenkey 2>/dev/null || true
if test -f /tmp/recording.pid if [ -f "$PID_FILE" ]; then
read recpid < /tmp/recording.pid PID=$(cat "$PID_FILE")
kill -SIGTERM $recpid; [ -n "$PID" ] && kill -s 15 $PID || true
# pkill --signal 15 -g $recpid rm "$PID_FILE"
and rm /tmp/recording.pid fi
end }
end
function _start -a x y w h fps _start_video_recording() {
if test (count $argv) -ne 5 _stop_recording
if [ "$#" -ne 5 ]; then
echo "expected x y w h fps , got $argv" echo "expected x y w h fps , got $argv"
exit 1 exit 1
end fi
set outfile "$HOME/recording/screencast-"(date '+%y%m%d-%H%M-%S')".mp4" X=$1
touch /tmp/recording.pid Y=$2
sleep 1 W=$3
ffmpeg \ H=$4
-f x11grab -s $w'x'$h -i "$DISPLAY+$x,$y" \ FPS=${5:-30}
-f alsa -i default \
-r $fps -c:v h264 -crf 0 -preset ultrafast \
-c:a aac \
$outfile > /dev/null 2>&1 </dev/null &
echo $last_pid > /tmp/recording.pid
echo $outfile
end
set --append subcmds audio OUTPUT_FILE="$OUTPUT_DIR/screencast-$(date '+%y%m%d-%H%M-%S').mp4"
set audio_help '' 'record audio only' touch "$PID_FILE"
function audio sleep 1
set outfile "$HOME/recording/audio-"(date '+%y%m%d-%H%M-%S')".aac" echo recording to $OUTPUT_FILE
touch /tmp/recording.pid # 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 </dev/null &
echo "$!" > "$PID_FILE"
}
audio() {
_stop_recording
OUTPUT_FILE="$OUTPUT_DIR/audio-$(date '+%y%m%d-%H%M-%S').aac"
touch "$PID_FILE"
sleep 1 sleep 1
ffmpeg \ ffmpeg \
-f alsa -i default \ -f alsa -i default \
-c:a aac \ -c:a aac \
$outfile > /dev/null 2>&1 </dev/null & $OUTPUT_FILE > /dev/null 2>&1 </dev/null &
echo $last_pid > /tmp/recording.pid echo "$!" > "$PID_FILE"
echo $outfile echo $OUTPUT_FILE
end }
theend() {
_stop_recording
}
set --append subcmds prepare prepare() {
set prepare_help '[w=1920] [h=1080]' 'create virtual monotors if physical size is higher than specified' # wanted size
function prepare -a pw ph WW=${1:-1920}
test -z $pw && set pw 1920 WH=${2:-1080}
test -z $ph && set ph 1080
set moninfo (xrandr | grep ' primary')
if not set whxy (string match -r '([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)' $moninfo) # actual size
echo 'unable to find geometry info of the primary monitor' >&2 # 0: +*DP-1 3440/797x1440/333+0+0 DP-1
exit 1 # resolution / physical
end WHXY=$(xrandr --listmonitors | awk '$2 ~ /\*/ {
set w $whxy[2] split($3, WHXY, /x|+|\//)
set h $whxy[3] match($2, /\*(.+)$/, name)
set x $whxy[4] print WHXY[1] " " WHXY[2] " " WHXY[3] " " WHXY[4] " " WHXY[5] " " WHXY[6] " " name[1]
set y $whxy[5] }')
if test $w -le $pw -a $h -le $ph W=$(echo "$WHXY" | awk '{print $1}')
return PW=$(echo "$WHXY" | awk '{print $2}')
end 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}')
if not set wmhm (string match -r '([0-9]+)mm x ([0-9]+)mm' $moninfo) # rest size
echo 'unable to find physical size of the primary monitor' RW=$(( $W - $WW ))
exit 1 RH=$(( $H - $WH ))
end if [ "$RW" -lt 0 ] && [ "$RH" -lt 0 ]; then
set wm $wmhm[-2] return 0
set hm $wmhm[-1] fi
if not set pn (string match -r '^([A-Za-z0-9_-]+)' $moninfo) # adjust rest size, either split horizontally or vertically
echo 'unable to find name of the primary monitor name' >&2 # physical size for wanted monitor
exit 1 PWW=$(echo "scale=3; r = $WW / $W * $PW; scale=0; r / 1" | bc)
end PWH=$(echo "scale=3; r = $WH / $H * $PH; scale=0; r / 1" | bc)
set name $pn[1] 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
set pwm (math "round($pw / $w * $wm)") # create virtual monitors
set phm (math "round($ph / $h * $hm)") echo xrandr --setmonitor $VIRTMON-1 "${WW}/${PWW}x${WH}/${PWH}+0+0" $NAME
set rwm (math "$wm - $pwm") echo xrandr --setmonitor $VIRTMON-2 "${RW}/${PRW}x${RH}/${PRH}+${RX}+${RY}" none
set rw (math "$w - $pw") echo nitrogen --restore
}
xrandr --setmonitor $VIRTMON-1 $pw/$pwm'x'$ph/$phm+0+0 $name finish() {
xrandr --setmonitor $VIRTMON-2 $rw/$rwm'x'$h/$hm+$pw+0 none
nitrogen --restore
end
set --append subcmds finish
set finish_help 'remove all virtual monitors'
function finish
xrandr --delmonitor $VIRTMON-1 xrandr --delmonitor $VIRTMON-1
xrandr --delmonitor $VIRTMON-2 xrandr --delmonitor $VIRTMON-2
nitrogen --restore nitrogen --restore
end }
set --append subcmds window window() {
set window_help '[fps=5]' 'record clicked window' FPS=${1:-5}
function window -a fps
_stop
test -z $fps && set fps 5
set wininfo (xwininfo)
for line in $wininfo
set -l kv (string split ":" $line)
set -l k (string trim $kv[1])
set -l v (string trim $kv[2])
switch $k
case 'Absolute upper-left X'
set x $v
case 'Absolute upper-left Y'
set y $v
case 'Width'
set w $v
case 'Height'
set h $v
end
end
if not set -q x
echo 'unable to find geometry of the window'
exit 1
end
_start $x $y $w $h $fps
end
set --append subcmds desktop notify-send "Please click the window that you want to record"
set desktop_help 'record desktop' WININFO=$(xwininfo)
function desktop -a fps X=$(echo "$WININFO" | awk -F: '$1 ~ /Absolute upper-left X/ { print $2 }')
_stop Y=$(echo "$WININFO" | awk -F: '$1 ~ /Absolute upper-left Y/ { print $2 }')
test -z $fps && set fps 30 W=$(echo "$WININFO" | awk -F: '$1 ~ /Width/ { print $2 }')
set monsinfo (xrandr --listmonitors) H=$(echo "$WININFO" | awk -F: '$1 ~ /Height/ { print $2 }')
#0: virtmon-1 1920/445x1080/250+0+0 DP-2 _start_video_recording $X $Y $W $H $FPS
if not set m (string match -r ' ([0-9]+)/[0-9]+x([0-9]+)/\d+\+([0-9]+)\+([0-9]+) ' $monsinfo[2]) }
echo 'unable to find geometry of the first monitor'
exit 1
end
#micvol 15000
pacmd set-source-volume noechosource 52000
_start $m[4] $m[5] $m[2] $m[3] $fps
end
set --append subcmds theend desktop() {
set theend_help 'end recording' FPS=${1:-30}
function theend # INPUT 0: +*DP-1 3440/797x1440/333+2560+80 DP-1
_stop # OUTPUT 2560 80 3440 1440
end 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
set --append subcmds togif }
set togif_help '<infile> <outfile>' 'convert video file to gif'
function togif -a infile outfile
convert -set delay 10 -layers Optimize $infile -ordered-dither o8x8,23 +map $outfile
end
set --append subcmds cover togif() {
set cover_help '<infile> <text> [gravity=center] [outfile=cover.png]' 'add text to infile(image) and output a cover' IN_FILE=$1
function cover -a infile text gravity outfile OUTPUT_FILE=$1
set x 50 convert -set delay 10 -layers Optimize $IN_FILE -ordered-dither o8x8,23 +map $OUTPUT_FILE
test -z $outfile && set outfile 'cover.png' }
test -z $gravity && set gravity 'center' && set x 0 && set y 0
magick convert $infile -thumbnail 1146x -background black -gravity $gravity -extent 1146x717 resized.png 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 \ magick convert resized.png \
-blur 0x8 \ -blur 0x8 \
-gravity $gravity \ -gravity $GRAVITY \
-fill black \ -fill black \
-pointsize 120 -font $SC_FONT \ -pointsize 120 -font $SC_FONT \
-interline-spacing 20 \ -interline-spacing 20 \
-stroke '#e1e1e1' -strokewidth 40 \ -stroke '#e1e1e1' -strokewidth 40 \
-annotate +$x+0 "$text" \ -annotate +$X+0 "$TEXT" \
-stroke '#000000' -strokewidth 5 \ -stroke '#000000' -strokewidth 5 \
-annotate +$x+0 "$text"\ -annotate +$X+0 "$TEXT"\
$outfile $OUTPUT_FILE
end }
set --append subcmds keep_mic_vol if [ "$#" -eq 0 ]; then
function keep_mic_vol -a volume
while true
pacmd set-source-volume noechosource $volume
sleep 0.1
end
end
set --append subcmds micvol
set micvol_help '<volume>' '0~65535'
function micvol -a volume
set kmvpid (ps aux | grep ' keep_mic_vol ' | head -n -1 | awk '{print $2}')
if test -n "$kmvpid"
echo killing $kmvpid
kill $kmvpid
end
set sc (status filename)
$sc keep_mic_vol $volume &
end
set --append subcmds help
set help_help '[subcmd]' 'print this menu'
function help -a subcmd
if test -z $subcmd
echo "Usage "(basename (status filename))" <subcmd> [...args]"
for subcmd in $subcmds
set -l help_name $subcmd'_help'
set -l help_list $$help_name
printf " %-45s %s\n" "$subcmd $help_list[-2]" "$help_list[-1]"
end
exit
end
end
if contains $argv[1] $subcmds
$argv
else if test (count $argv ) -eq 0
desktop desktop
else else
help $@
end fi