#!/usr/bin/env bash # Captura la pantalla y escribe un JPEG por la salida estándar. # # scripts/capturar-pantalla.sh [ancho] [salida] # # ancho Ancho al que reducir la captura. Por defecto 1280, que es el # mínimo medido para que el modelo lea texto de interfaz sin # inventárselo (ver docs/RENDIMIENTO.md). # salida Monitor concreto. Vacío = todo lo que haya. # # Está fuera del binario para que añadir un entorno gráfico nuevo sea editar # este guion y no recompilar. La detección va de más específico a más general. set -euo pipefail ANCHO="${1:-1280}" SALIDA="${2:-}" falta() { echo "no hay con qué capturar la pantalla: $1" >&2; exit 1; } # El escalado se hace aquí y no en el binario: reducir antes de mandar la # imagen al modelo es lo que baja el coste de 23 s a 7 s, y ffmpeg ya hace # falta para la cámara. reducir() { if command -v ffmpeg >/dev/null 2>&1; then ffmpeg -hide_banner -loglevel error -i - \ -vf "scale=${ANCHO}:-2:flags=lanczos" -q:v 3 -f image2 -c:v mjpeg - else cat # sin ffmpeg se manda a tamaño completo: lento, pero funciona fi } if [ -n "${WAYLAND_DISPLAY:-}" ] && command -v grim >/dev/null 2>&1; then # wlroots: Hyprland, Sway, river… grim escribe a stdout con «-». if [ -n "$SALIDA" ]; then grim -t png -o "$SALIDA" - | reducir else grim -t png - | reducir 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 reducir < "$TMP" elif [ -n "${DISPLAY:-}" ] && command -v maim >/dev/null 2>&1; then maim --format=png /dev/stdout | reducir elif [ -n "${DISPLAY:-}" ] && command -v import >/dev/null 2>&1; then # ImageMagick, presente en casi cualquier X11. import -silent -window root png:- | reducir elif [ -n "${DISPLAY:-}" ] && command -v scrot >/dev/null 2>&1; then scrot -o /dev/stdout | reducir else falta "instala grim (Wayland) o maim/imagemagick (X11)" fi