Skip to content

Instantly share code, notes, and snippets.

@nixjdm
Created January 14, 2026 20:02
Show Gist options
  • Select an option

  • Save nixjdm/9695b06c156119041e49bd8b2b1c5d20 to your computer and use it in GitHub Desktop.

Select an option

Save nixjdm/9695b06c156119041e49bd8b2b1c5d20 to your computer and use it in GitHub Desktop.
A simple graphical region selector feeding into ffmpeg video recording
!/usr/bin/env bash
set -euo pipefail
FPS=30
CQ=23
PRESET="p5"
AUDIO=0
USE_LAST=0
CLEAR_LAST=0
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/record-region"
STATE_FILE="$STATE_DIR/last_region.env"
usage() {
cat <<EOF
Usage:
record-region [options]
Options:
--last Use the last saved region (skip selection UI)
--clear Clear the saved region
--audio Record microphone audio (PulseAudio default input)
--fps N Set framerate (default: ${FPS})
--cq N NVENC constant quality (default: ${CQ})
-h, --help Show this help
Notes:
- Stop recording with Ctrl+C.
- Output files go to ~/Videos/
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--last) USE_LAST=1; shift ;;
--clear) CLEAR_LAST=1; shift ;;
--audio) AUDIO=1; shift ;;
--fps) FPS="${2:?missing value}"; shift 2 ;;
--cq) CQ="${2:?missing value}"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown option: $1"; usage; exit 1 ;;
esac
done
mkdir -p "$STATE_DIR"
if [[ "$CLEAR_LAST" -eq 1 ]]; then
rm -f "$STATE_FILE"
echo "Cleared saved region."
exit 0
fi
select_region() {
# This prints shell assignments like: X=.. Y=.. W=.. H=..
eval "$(slop -f "X=%x Y=%y W=%w H=%h")"
}
load_last_region() {
if [[ ! -f "$STATE_FILE" ]]; then
echo "No saved region found. Run without --last to select one first."
exit 1
fi
# shellcheck disable=SC1090
source "$STATE_FILE"
}
save_region() {
cat > "$STATE_FILE" <<EOF
X=${X}
Y=${Y}
W=${W}
H=${H}
EOF
}
# Get region
if [[ "$USE_LAST" -eq 1 ]]; then
load_last_region
else
echo "Drag to select recording region..."
select_region
save_region
fi
# Basic validation
if [[ -z "${W:-}" || -z "${H:-}" || "$W" -le 0 || "$H" -le 0 ]]; then
echo "Invalid region selected."
exit 1
fi
OUT="$HOME/Videos/Screencasts/region_$(date +%F_%H-%M-%S).mp4"
echo "Recording region: ${W}x${H} at +${X},${Y}"
echo "Saving to: $OUT"
echo "Press Ctrl+C to stop."
# Build ffmpeg command
# crop filter ensures even dimensions for h264 encoding
VIDEO_INPUT=(-f x11grab -framerate "$FPS" -video_size "${W}x${H}" -i "${DISPLAY}+${X},${Y}")
VIDEO_ENC=(-vf "crop=floor(iw/2)*2:floor(ih/2)*2" -c:v h264_nvenc -preset "$PRESET" -cq "$CQ")
if [[ "$AUDIO" -eq 1 ]]; then
ffmpeg \
"${VIDEO_INPUT[@]}" \
-f pulse -i default \
"${VIDEO_ENC[@]}" \
-c:a aac -b:a 160k \
"$OUT"
else
ffmpeg \
"${VIDEO_INPUT[@]}" \
"${VIDEO_ENC[@]}" \
"$OUT"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment