#!/usr/bin/env bash
set -u

HERE=$(cd "$(dirname "$0")" && pwd)
DISPLAY_INDEX=${1:-0}
FFMPEG=$(command -v ffmpeg || echo "$HERE/ffmpeg")
if [ ! -x "$FFMPEG" ]; then
  echo "ffmpeg not found. macOS: brew install ffmpeg. Linux: sudo apt install ffmpeg."
  exit 1
fi

AUTH=""
[ -f "$HERE/auth.txt" ] && AUTH=$(head -n 1 "$HERE/auth.txt" | tr -d '[:space:]')
AUTH_FORMAT='^(([A-Za-z0-9_-]+):)?([A-Za-z0-9_-]+)@([A-Za-z0-9.:,-]+)$'
until [[ "$AUTH" =~ $AUTH_FORMAT ]]; do
  read -r -p "Paste your auth string: " AUTH
done
USERNAME=${BASH_REMATCH[2]}
SECRET=${BASH_REMATCH[3]}
IFS=, read -r -a SERVERS <<< "${BASH_REMATCH[4]}"

if [ -z "$USERNAME" ]; then
  HOST=${SERVERS[0]%%:*}
  if [ "$(uname)" = Darwin ]; then
    USERNAME=$(ipconfig getifaddr "$(route -n get "$HOST" | awk '/interface:/ {print $2}')")
  else
    USERNAME=$(ip route get "$(getent hosts "$HOST" | awk '{print $1; exit}')" | awk '{for (i = 1; i < NF; i++) if ($i == "src") print $(i + 1)}')
  fi
fi
I=$(( $(printf '%s' "$USERNAME" | cksum | cut -d' ' -f1) % ${#SERVERS[@]} ))

SCALE="scale=1920:1080:force_original_aspect_ratio=decrease:force_divisible_by=2,format=nv12"

if [ "$(uname)" = Darwin ]; then
  DEVICE=$("$FFMPEG" -f avfoundation -list_devices true -i "" 2>&1 | sed -n "s/.*\[\([0-9]*\)\] Capture screen $DISPLAY_INDEX\$/\1/p")
  if [ -z "$DEVICE" ]; then
    echo "Screen not found. Allow your terminal under System Settings > Privacy & Security > Screen Recording, then run this again."
    exit 1
  fi
  INPUT=(-f avfoundation -capture_cursor 1 -framerate 15 -pixel_format nv12 -i "$DEVICE:none")
  ENCODERS="h264_videotoolbox libx264"
else
  if [ "${XDG_SESSION_TYPE:-}" = wayland ]; then
    echo "Wayland sessions cannot be captured. Log in with an X11 session, or use OBS."
    exit 1
  fi
  if [ "$DISPLAY_INDEX" = 0 ]; then
    MONITOR=$(xrandr --listactivemonitors | grep '\*' || xrandr --listactivemonitors | sed -n 2p)
  else
    MONITOR=$(xrandr --listactivemonitors | grep -v '\*' | sed -n "$((DISPLAY_INDEX + 1))p")
  fi
  GEOMETRY=$(echo "$MONITOR" | awk '{print $3}')
  WIDTH=${GEOMETRY%%/*}
  HEIGHT=${GEOMETRY#*x}
  HEIGHT=${HEIGHT%%/*}
  OFFSET=${GEOMETRY#*+}
  INPUT=(-f x11grab -framerate 15 -video_size "${WIDTH}x${HEIGHT}" -i "$DISPLAY+${OFFSET/+/,}")
  ENCODERS="libx264"
fi

ENCODER=""
for E in $ENCODERS; do
  if "$FFMPEG" -nostdin -loglevel quiet "${INPUT[@]}" -t 1 -vf "$SCALE" -c:v "$E" -f null -; then
    ENCODER=$E
    break
  fi
done
if [ -z "$ENCODER" ]; then
  echo "Could not capture the screen. Use OBS instead (see README)."
  exit 1
fi

OPTIONS=(-c:v "$ENCODER" -b:v 2500k -maxrate 4000k -bufsize 8000k -g 30 -bf 0)
[ "$ENCODER" = libx264 ] && OPTIONS+=(-preset veryfast -tune zerolatency)

while true; do
  SERVER=${SERVERS[$I]}
  [[ "$SERVER" == *:* ]] || SERVER="$SERVER:8890"
  echo "Streaming display $DISPLAY_INDEX to $SERVER as $USERNAME. Press Ctrl+C to stop."
  START=$(date +%s)
  "$FFMPEG" -nostdin -loglevel quiet "${INPUT[@]}" -vf "$SCALE" "${OPTIONS[@]}" -f mpegts \
    "srt://$SERVER?streamid=publish:$USERNAME&passphrase=$SECRET&pbkeylen=32&latency=2000000"
  [ $(( $(date +%s) - START )) -lt 30 ] && I=$(( (I + 1) % ${#SERVERS[@]} ))
  echo "$(date +%H:%M:%S) Not connected. Retrying in 5 seconds."
  sleep 5
done
