273 lines
8.9 KiB
Bash
Executable file
273 lines
8.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# *** Script by Clay Gomera (Drake) ***
|
|
# Description: A simple screenshot/screencast dmenu script
|
|
# Dependencies: maim, slop, ffmpeg, dmenu, libnotify
|
|
|
|
## Define directories for saving screenshots and screencasts
|
|
SHOTDIR="$XDG_PICTURES_DIR/Screenshots"
|
|
CASTDIR="$XDG_VIDEOS_DIR/Screencasts"
|
|
mkdir -p "$SHOTDIR" "$CASTDIR"
|
|
|
|
## Define available formats for images and videos
|
|
image_formats="jpg\npng"
|
|
video_formats="mp4\nmkv"
|
|
|
|
## Define choices for the main menu
|
|
mcho1=" Take a screenshot"
|
|
mcho2=" Record the screen"
|
|
mcho3=" Stop recording"
|
|
mcho4=" Exit"
|
|
mchos="$mcho1\n$mcho2\n$mcho3\n$mcho4"
|
|
|
|
## Define choices for the screenshot submenu
|
|
mscho1=" Capture the entire screen"
|
|
mscho2=" Capture the entire screen (With delay)"
|
|
mscho3=" Capture area"
|
|
mscho4=" Capture active window"
|
|
mscho5=" Exit"
|
|
mschos="$mscho1\n$mscho2\n$mscho3\n$mscho4\n$mscho5"
|
|
|
|
## Define choices for saving screenshots
|
|
svcho1=" Copy to clipboard"
|
|
svcho2=" Save to $SHOTDIR"
|
|
svchos="$svcho1\n$svcho2"
|
|
|
|
## Define delay options for screenshots
|
|
del1=" 3 sec delay"
|
|
del2=" 5 sec delay"
|
|
del3=" 10 sec delay"
|
|
dels="$del1\n$del2\n$del3"
|
|
|
|
# Check if required dependencies are installed
|
|
check_dependencies() {
|
|
local dependencies=("maim" "ffmpeg" "dmenu" "notify-send" "xclip" "xdotool" "xdpyinfo")
|
|
for dep in "${dependencies[@]}"; do
|
|
if ! command -v "$dep" &>/dev/null; then
|
|
echo "$dep is required but not installed. Please install it and try again."
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Prompt the user to choose an action for saving the screenshot
|
|
fsvchos() {
|
|
svchoice=$(echo -e "$svchos" | dmenu -i -l 2 -p " What do you want to do with this screenshot?")
|
|
}
|
|
|
|
# Prompt the user to choose a delay option for screenshots
|
|
fdel() {
|
|
del=$(echo -e "$dels" | dmenu -i -p " Select Delay")
|
|
}
|
|
|
|
# Prompt the user to choose the image format for screenshots
|
|
fimage_format() {
|
|
image_format=$(echo -e "$image_formats" | dmenu -i -p " Choose screenshot format")
|
|
}
|
|
|
|
# Prompt the user to choose the video format for recordings
|
|
fvideo_format() {
|
|
video_format=$(echo -e "$video_formats" | dmenu -i -p " Choose video format")
|
|
}
|
|
|
|
# Capture a full-screen screenshot without delay
|
|
shot_screen() {
|
|
fimage_format
|
|
fsvchos
|
|
if [ "$svchoice" = "$svcho1" ]; then
|
|
maim -f "$image_format" | xclip -selection clipboard -t image/"$image_format" && notify-send "Screenshot saved to clipboard"
|
|
elif [ "$svchoice" = "$svcho2" ]; then
|
|
maim -f "$image_format" "$SHOTDIR/$(date +%s).$image_format" && notify-send "Screenshot saved"
|
|
else
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Capture a full-screen screenshot with a user-defined delay
|
|
shot_screen_delay() {
|
|
fimage_format
|
|
fsvchos
|
|
fdel
|
|
case $del in
|
|
"$del1")
|
|
for i in 3 2 1; do
|
|
notify-send -t 1000 "Capturing in $i.."
|
|
sleep 1
|
|
done
|
|
;;
|
|
"$del2")
|
|
for i in 5 4 3 2 1; do
|
|
notify-send -t 1000 "Capturing in $i.."
|
|
sleep 1
|
|
done
|
|
;;
|
|
"$del3")
|
|
for i in 10 9 8 7 6 5 4 3 2 1; do
|
|
notify-send -t 1000 "Capturing in $i.."
|
|
sleep 1
|
|
done
|
|
;;
|
|
esac
|
|
|
|
sleep 1
|
|
if [ "$svchoice" = "$svcho1" ]; then
|
|
maim -f "$image_format" | xclip -selection clipboard -t image/"$image_format" && notify-send "Screenshot saved to clipboard"
|
|
elif [ "$svchoice" = "$svcho2" ]; then
|
|
maim -f "$image_format" "$SHOTDIR/$(date +%s).$image_format" && notify-send "Screenshot saved to $SHOTDIR"
|
|
else
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Capture a user-defined area of the screen
|
|
shot_area() {
|
|
fimage_format
|
|
fsvchos
|
|
if [ "$svchoice" = "$svcho1" ]; then
|
|
maim -f "$image_format" -s | xclip -selection clipboard -t image/"$image_format" && notify-send "Screenshot saved to clipboard"
|
|
elif [ "$svchoice" = "$svcho2" ]; then
|
|
maim -s -f "$image_format" "$SHOTDIR/$(date +%s).$image_format" && notify-send "Screenshot saved to $SHOTDIR"
|
|
else
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Capture a screenshot of the currently active window
|
|
shot_window() {
|
|
fimage_format
|
|
fsvchos
|
|
if [ "$svchoice" = "$svcho1" ]; then
|
|
maim -f "$image_format" -i "$(xdotool getactivewindow)" | xclip -selection clipboard -t image/"$image_format" && notify-send "Screenshot saved to clipboard"
|
|
elif [ "$svchoice" = "$svcho2" ]; then
|
|
maim -i "$(xdotool getactivewindow)" -f "$image_format" "$SHOTDIR/$(date +%s).$image_format" && notify-send "Screenshot saved to $SHOTDIR"
|
|
else
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Start recording the entire screen using ffmpeg
|
|
rec_screen() {
|
|
fvideo_format
|
|
if pgrep -x "ffmpeg" > /dev/null; then
|
|
notify-send "A screen recording is already in progress."
|
|
else
|
|
filename="$CASTDIR/$(date +%s).$video_format"
|
|
resolution="$(xdpyinfo | grep dimensions | awk '{print $2}')"
|
|
ffmpeg -f x11grab -s "$resolution" -i :0.0 -c:v libx264 -preset ultrafast -qp 0 "$filename" &
|
|
notify-send "Screen recording started."
|
|
fi
|
|
}
|
|
|
|
# Start recording the entire screen with a user-defined delay
|
|
rec_screen_delay() {
|
|
fvideo_format
|
|
fdel
|
|
case $del in
|
|
"$del1")
|
|
for i in 3 2 1; do
|
|
notify-send -t 1000 "Starting in $i.."
|
|
sleep 1
|
|
done
|
|
;;
|
|
"$del2")
|
|
for i in 5 4 3 2 1; do
|
|
notify-send -t 1000 "Starting in $i.."
|
|
sleep 1
|
|
done
|
|
;;
|
|
"$del3")
|
|
for i in 10 9 8 7 6 5 4 3 2 1; do
|
|
notify-send -t 1000 "Starting in $i.."
|
|
sleep 1
|
|
done
|
|
;;
|
|
esac
|
|
|
|
sleep 1
|
|
if pgrep -x "ffmpeg" > /dev/null; then
|
|
notify-send "A screen recording is already in progress."
|
|
else
|
|
filename="$CASTDIR/$(date +%s).$video_format"
|
|
resolution="$(xdpyinfo | grep dimensions | awk '{print $2}')"
|
|
ffmpeg -f x11grab -s "$resolution" -i :0.0 -c:v libx264 -preset ultrafast -qp 0 "$filename" &
|
|
notify-send "Screen recording started"
|
|
fi
|
|
}
|
|
|
|
# Start recording a user-defined area of the screen
|
|
rec_area() {
|
|
fvideo_format
|
|
if pgrep -x "ffmpeg" > /dev/null; then
|
|
notify-send "A screen recording is already in progress."
|
|
else
|
|
filename="$CASTDIR/$(date +%s).$video_format"
|
|
slop_result=$(slop -f "%x %y %w %h")
|
|
if [ -n "$slop_result" ]; then
|
|
IFS=' ' read -r x y w h <<< "$slop_result"
|
|
ffmpeg -f x11grab -s "${w}x${h}" -i :0.0+"$x","$y" -c:v libx264 -preset ultrafast -qp 0 "$filename" &
|
|
notify-send "Screen recording started"
|
|
else
|
|
notify-send "No area selected. Aborting recording."
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Start recording the currently active window
|
|
rec_window() {
|
|
fvideo_format
|
|
if pgrep -x "ffmpeg" > /dev/null; then
|
|
notify-send "A screen recording is already in progress."
|
|
else
|
|
filename="$CASTDIR/$(date +%s).$video_format"
|
|
active_window_id=$(xdotool getactivewindow)
|
|
|
|
if [ -n "$active_window_id" ]; then
|
|
ffmpeg -f x11grab -s "$(xdotool getwindowgeometry --shell $active_window_id | grep WIDTH | cut -d'=' -f2)x$(xdotool getwindowgeometry --shell $active_window_id | grep HEIGHT | cut -d'=' -f2)" -i :0.0+"$(xdotool getwindowgeometry --shell $active_window_id | grep X | cut -d'=' -f2)","$(xdotool getwindowgeometry --shell $active_window_id | grep Y | cut -d'=' -f2)" -c:v libx264 -preset ultrafast -qp 0 "$filename" &
|
|
notify-send "Recording active window started"
|
|
else
|
|
notify-send "No active window found. Aborting recording."
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Stop the ongoing screen recording
|
|
stop_recording() {
|
|
if pgrep -x "ffmpeg" > /dev/null; then
|
|
pkill -f "ffmpeg -f x11grab"
|
|
notify-send "Screen recording stopped. Video saved to $CASTDIR"
|
|
else
|
|
notify-send "No recording in progress."
|
|
fi
|
|
}
|
|
|
|
# Main script execution
|
|
check_dependencies
|
|
|
|
# Display the main menu and handle user choice
|
|
mchoice=$(echo -e "$mchos" | dmenu -i -l 4 -p " Screen Capture Menu")
|
|
case $mchoice in
|
|
"$mcho1")
|
|
# Display the screenshot submenu and handle user choice
|
|
mschoice=$(echo -e "$mschos" | dmenu -i -l 9 -p " Screenshot Menu")
|
|
case $mschoice in
|
|
"$mscho1") shot_screen ;;
|
|
"$mscho2") shot_screen_delay ;;
|
|
"$mscho3") shot_area ;;
|
|
"$mscho4") shot_window ;;
|
|
"$mscho5") exit 0 ;;
|
|
esac
|
|
;;
|
|
"$mcho2")
|
|
# Display the screencast submenu and handle user choice
|
|
mschoice=$(echo -e "$mschos" | dmenu -i -l 9 -p " Screencast Menu")
|
|
case $mschoice in
|
|
"$mscho1") rec_screen ;;
|
|
"$mscho2") rec_screen_delay ;;
|
|
"$mscho3") rec_area ;;
|
|
"$mscho4") rec_window ;;
|
|
"$mscho5") exit 0 ;;
|
|
esac
|
|
;;
|
|
"$mcho3") stop_recording ;;
|
|
"$mcho4") exit 0 ;;
|
|
esac
|