diff --git a/.local/bin/scripts/blaze b/.local/bin/scripts/blaze new file mode 100644 index 0000000..16f4884 --- /dev/null +++ b/.local/bin/scripts/blaze @@ -0,0 +1,272 @@ +#!/usr/bin/env sh +# +# Blaze - record screen and audio +# Author - Cherrry9 + +deps() { + [ "$1" ] && { + md="$(for i in $deps; do printf " - \033[31m%s\033[0m\n" "$i"; done)" + printf "\033[31mYou are missing dependencies\033[0m\n" + printf "%b\n" "$md" + printf "\n" + } + printf "\033[34mRequired dependencies\033[0m\n" + printf " - \033[34mffmpeg\033[0m Actually recording\n" + printf " - \033[34mdmenu\033[0m Selecting the options\n" + printf "\n" + printf "\033[35mAt least one of these is required\033[0m\n" + printf " - \033[35mxorg-xrandr\033[0m Selecting a display to record\n" + printf " - \033[35mslop\033[0m Selecting an area to record\n" + printf "\n" + printf "\033[32mOptional dependencies\033[0m\n" + printf " - \033[32mnotify-send\033[0m Letting the user know when the recording starts/ends\n" + printf " - \033[32mxdg-desktop-dir\033[0m Use directory from xdg instead \$HOME/Videos\n" + exit +} + +# check all necessary dependencies +_() { command -v "$1" >/dev/null 2>&1; } + +_ dmenu || deps="$deps dmenu" +_ ffmpeg || deps="$deps ffmpeg" +_ xrandr || _ slop || deps="$deps xorg-xrandr/slop" + +[ "$deps" ] && deps "$deps" + +# output file, use $BLAZE_DIR and $BLAZE_FILE if they are set +if [ ! "$BLAZE_DIR" ]; then + _ xdg-user-dir && + BLAZE_DIR=$(xdg-user-dir VIDEOS 2>/dev/null) || + BLAZE_DIR="$HOME/Videos" +fi + +[ ! -d "$BLAZE_DIR" ] && mkdir -p "$BLAZE_DIR" >/dev/null 2>&1 + +output="$BLAZE_DIR/${BLAZE_FILE:-blaze-$(date '+%Y-%m-%d_%H-%M-%S').mp4}" + +# menu to use +m() { ${DMENU:-dmenu} "$@"; } + +# exit if X isn't running +[ ! "$DISPLAY" ] && { echo "Can't open display; exiting"; exit; } + +# find default audio device +audio() { + pacmd="$(pacmd list-sources | grep -i -B 1 output)" + dev="$(echo "$pacmd" | grep -i '\* index' || + echo "$pacmd" | grep -i 'index' | head -n 1)" + audio="-f pulse -i $(echo "$dev" | grep -o '[0-9]')" +} + +save() { + if [ -f "/tmp/blaze-pid" ]; then + recpid="$(cat /tmp/blaze-pid)" + # kill with SIGTERM, allowing finishing touches. + kill -15 "$recpid" + rm -f /tmp/blaze-pid + # even after SIGTERM, ffmpeg may still run, so SIGKILL it. + ( sleep 3; kill -9 "$recpid" ) >/dev/null 2>&1 & + echo "Recording Stopped" + notify-send -t 2000 "Recording Stopped" + exit + else + echo "Recording isn't active" + notify-send -t 2000 "Recording isn't active" + exit 1 + fi +} + +help() { + printf "\033[34mOptions\033[0m\n" + printf " \033[34m-o\033[0m \033[35m[]\033[0m Specify the output file\n" + printf " \033[34m-s\033[0m End the recording\n" + printf " \033[34m-h\033[0m Display what you're reading right now\n" + printf " \033[34m-d\033[0m printf dependencies\n" + printf " \033[34m-c\033[0m Don't ask if the user is ready to record\n" + printf " \033[34m-p\033[0m \033[35m[]\033[0m Save to and load from preset \n" + printf " \033[34m-r\033[0m \033[35m[]\033[0m Force framerate\n" + printf " \033[34m-b\033[0m \033[35m[]\033[0m Force bitrate (in MB)\n" + printf " \033[34m-m\033[0m \033[35m[]\033[0m Force method (slop, display)\n" + printf " \033[34m-d\033[0m \033[35m[]\033[0m Force display (Doesn't require -m)\n" + printf " \033[34m-n\033[0m Force disable NVENC\n" + printf " \033[34m-S\033[0m Options to use for slop (Needs to be quoted)\n" + printf " \033[34m-a\033[0m Record desktop audio\n" + printf "\n" + printf "To select an area, install 'slop',\n" + printf "to select a display, install 'xorg-xrandr'\n" + printf "\n" + printf "\033[35m[]\033[0m = Option requires an argument\n" + printf "\n" + printf "\033[34mVariables\033[0m\n" + printf " \033[34mBLAZE_DIR\033[0m Location to save the video\n" + printf " \033[37mDefault: xdg-user-dir VIDEOS or \$HOME/Videos\033[0m\n" + printf "\n" + printf " \033[34mBLAZE_FILE\033[0m Name of the saved video\n" + printf " \033[37mDefault: blaze-%s.mp4\033[0m\n" "\$(date +%Y-%m-%d_%H-%M-%S)" + printf "\n" + printf " \033[34mBLAZE_SLOP\033[0m Options to use for slop\n" + printf " \033[37mDefault: None\033[0m\n" + exit +} + +while getopts ':hdscb:m:r:nD:S:p:ao:' opt; do + case "$opt" in + h) + help;; + d) + deps;; + s) + save;; + c) + ready='yes';; + b) + bitrate="-b:v ${OPTARG}M";; + m) + method="$OPTARG";; + r) + rate="$OPTARG";; + n) + nvenc=' ';; + D) + display="$OPTARG" + method='display';; + S) + sloptions="$OPTARG" + method='selection';; + p) + preset="$OPTARG";; + a) + audio;; + o) + output="$OPTARG";; + \?) + echo "Invalid Option: -$OPTARG" 1>&2 + exit 1;; + :) + echo "Invalid Option: -$OPTARG requires an argument" 1>&2 + exit 1;; + esac +done +shift $((OPTIND -1)) + +# exit if blaze is running +[ -f /tmp/blaze-pid ] && { + echo "Blaze is already running, exiting." + notify-send "Blaze is already running, exiting." + exit +} + +[ "$preset" ] && { + # create preset location + mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}" + + # load preset + preset_location="${XDG_CONFIG_HOME:-$HOME/.config}"/blaze/"$preset" + [ -f "$preset_location" ] && + . "$preset_location" +} + +# ask the user what method they want to use +[ ! "$method" ] && { + # Check if the user has slop and disputils + _ slop && s=s + _ xrandr && d=d + + # if the user only has slop or disputils (But not both) use that + [ "$s" ] && method=selection + [ "$d" ] && method=display + + # if the user has both slop and disputils ask the user which one to use + [ "$s" ] && [ "$d" ] && + method="$(printf "display\nselection" | m -p "Method of recording")" +} + +if [ "$method" = display ]; then + + # get information about the display + monitors="$(xrandr --listmonitors | awk 'NR>1 { printf $NF"\n" }')" + + # if there's only one display, use that and skip asking + if [ "$(printf "%b\n" "$monitors" | wc -l)" = 1 ]; then + display="$monitors" + else # if there are other displays ask the user which one to use + [ ! "$display" ] && display="$(printf "%b" "$monitors" | m -p "Display to record")" + fi + + set -- $(xrandr -q | grep "$display" | grep -oP '\d*x\d*\+\d*\+\d*' | tr '+x' ' ') + + width="$1" + height="$2" + offX="$3" + offY="$4" + +elif [ "$method" = selection ] || [ "$method" = slop ]; then + + # select an area and make each number a separate word + set -- $(slop $sloptions -f '%w %h %x %y') + + # get information about the display + width="$1" + height="$2" + offX="$3" + offY="$4" + + [ "$(( width % 2 ))" = 1 ] && width="$(( width + 1 ))" + [ "$(( height % 2 ))" = 1 ] && height="$(( height + 1 ))" + +else + + printf "Invalid method; exiting\n" + exit 1 + +fi + +# detect if the user has a nvidia card and use nvenc +[ ! "$nvenc" ] && lspci | grep -qi nvidia && nvenc="-vcodec h264_nvenc" + +# ask the user what they want the framerate of the video to be +[ ! "$rate" ] && rate="$(printf "30\n60" | m -p "Framerate")" +[ ! "$rate" ] && exit + +# ask the user if they want to start the recording +[ ! "$ready" ] && ready="$(printf "yes\nno" | m -p "Start the recording")" + +# save preset +[ "$preset_location" ] && { + cat >"$preset_location"< /tmp/blaze-pid +}