+#!/bin/bash
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to change
+# to a recommended GPL license.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ffs = ffmpeg stream
+
+# todo: figure out how to record mumble
+# todo: get icecast on li.b8.nz
+# todo: https://superuser.com/questions/1106674/how-to-add-blank-lines-above-the-bottom-in-terminal
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+
+
+# 3 mountpoints: fsf-sysops (public), fsf (default, all staff), fsf-tech (tech team)
+case $1 in
+ sysops|tech)
+ mount_suffix=-$1
+ ;;
+esac
+
+host=live.iankelling.org:8000
+if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
+ && ip n show 10.2.0.1 | grep . &>/dev/null; then
+ host=127.0.0.1:8000
+fi
+
+pass=$(sed -n 's/ *<source-password>\([^<]*\).*/\1/p' /p/c/icecast.xml)
+
+
+tmpf=$(mktemp)
+xrandr >$tmpf
+
+# example xrandr output: 1280x800+0+0
+primary_res=$(awk '$2 == "connected" && $3 == "primary" { print $4 }' $tmpf | sed 's/+.*//')
+secondary_res=$(awk '$2 == "connected" && $3 != "primary" { print $3 }' $tmpf | sed 's/+.*//')
+
+if [[ $secondary_res ]]; then
+ # assumes secondary is on the right
+ x_offset=${primary_res%%x*}
+ secondary_x=${secondary_res%%x*}
+ secondary_y=${secondary_res##*x}
+ stream_res=$(( secondary_x / 2 ))x$(( secondary_y / 2))
+else
+ x_offset=0
+ stream_res=$primary_res
+fi
+
+
+opts=(
+ # nice to have: be a little less verbose
+ -hide_banner
+ -video_size $stream_res
+ -f x11grab
+ -framerate 4
+ # input options come before -i
+ -i :0.0+$x_offset.0
+ -vf drawbox=color=black
+ -vcodec libvpx
+ -g 8
+ -quality realtime
+ -threads 2
+ -error-resilient 1
+ -content_type video/webm
+ -f webm
+ icecast://source:$pass@$host/fsf$mount_suffix.webm
+
+)
+
+
+rm -f /tmp/iank-ffmpeg
+mkfifo -m 0600 /tmp/iank-ffmpeg
+echo executing: ffmpeg -stdin ${opts[@]}
+# ffmpeg sits and waits until we do this. dunno why. whatever.
+echo >/tmp/iank-ffmpeg &
+ffmpeg ${opts[@]} </tmp/iank-ffmpeg