aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/capture-screen.sh
blob: 40bb8606dd9854f1ac21790d6345c157037cfd35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/env bash
# Captures the screen and writes a JPEG to standard output.
#
#   scripts/capture-screen.sh [width] [output]
#
#   width   Width to scale the capture down to. Defaults to 1280, the
#           measured minimum for the model to read UI text without making
#           it up (see docs/RENDIMIENTO.md).
#   output  A specific monitor. Empty = everything there is.
#
# It lives outside the binary so supporting a new graphical environment means
# editing this script, not recompiling. Detection goes from most specific to
# most general.
set -euo pipefail

WIDTH="${1:-1280}"
OUTPUT="${2:-}"

missing() { echo "nothing to capture the screen with: $1" >&2; exit 1; }

# Scaling happens here and not in the binary: shrinking before sending the
# image to the model is what brings the cost from 23 s down to 7 s, and ffmpeg
# is already needed for the camera.
shrink() {
  if command -v ffmpeg >/dev/null 2>&1; then
    ffmpeg -hide_banner -loglevel error -i - \
           -vf "scale=${WIDTH}:-2:flags=lanczos" -q:v 3 -f image2 -c:v mjpeg -
  else
    cat   # without ffmpeg it goes full size: slow, but it works
  fi
}

if [ -n "${WAYLAND_DISPLAY:-}" ] && command -v grim >/dev/null 2>&1; then
  # wlroots: Hyprland, Sway, river… grim writes to stdout with «-».
  if [ -n "$OUTPUT" ]; then
    grim -t png -o "$OUTPUT" - | shrink
  else
    grim -t png - | shrink
  fi
elif [ -n "${WAYLAND_DISPLAY:-}" ] && command -v spectacle >/dev/null 2>&1; then
  TMP=$(mktemp --suffix=.png); trap 'rm -f "$TMP"' EXIT
  spectacle -b -n -f -o "$TMP" >/dev/null 2>&1
  shrink < "$TMP"
elif [ -n "${DISPLAY:-}" ] && command -v maim >/dev/null 2>&1; then
  maim --format=png /dev/stdout | shrink
elif [ -n "${DISPLAY:-}" ] && command -v import >/dev/null 2>&1; then
  # ImageMagick, present on almost any X11.
  import -silent -window root png:- | shrink
elif [ -n "${DISPLAY:-}" ] && command -v scrot >/dev/null 2>&1; then
  scrot -o /dev/stdout | shrink
else
  missing "install grim (Wayland) or maim/imagemagick (X11)"
fi