distro specific fixes
[distro-setup] / ffs
1 #!/bin/bash
2 # I, Ian Kelling, follow the GNU license recommendations at
3 # https://www.gnu.org/licenses/license-recommendations.en.html. They
4 # recommend that small programs, < 300 lines, be licensed under the
5 # Apache License 2.0. This file contains or is part of one or more small
6 # programs. If a small program grows beyond 300 lines, I plan to change
7 # to a recommended GPL license.
8
9 # Copyright 2024 Ian Kelling
10
11 # Licensed under the Apache License, Version 2.0 (the "License");
12 # you may not use this file except in compliance with the License.
13 # You may obtain a copy of the License at
14
15 # http://www.apache.org/licenses/LICENSE-2.0
16
17 # Unless required by applicable law or agreed to in writing, software
18 # distributed under the License is distributed on an "AS IS" BASIS,
19 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 # See the License for the specific language governing permissions and
21 # limitations under the License.
22
23 # ffs = ffmpeg stream
24
25 # todo: figure out how to record mumble
26 # todo: get icecast on li.b8.nz
27 # todo: https://superuser.com/questions/1106674/how-to-add-blank-lines-above-the-bottom-in-terminal
28
29 if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
30 shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
31 set -eE -o pipefail
32 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
33
34
35 # 3 mountpoints: fsf-sysops (public), fsf (default, all staff), fsf-tech (tech team)
36 case $1 in
37 sysops|tech)
38 mount_suffix=-$1
39 ;;
40 esac
41
42 host=live.iankelling.org:8000
43 if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
44 && ip n show 10.2.0.1 | grep . &>/dev/null; then
45 host=127.0.0.1:8000
46 fi
47
48 pass=$(sed -n 's/ *<source-password>\([^<]*\).*/\1/p' /p/c/icecast.xml)
49
50
51 tmpf=$(mktemp)
52 xrandr >$tmpf
53
54 # example xrandr output: 1280x800+0+0
55 primary_res=$(awk '$2 == "connected" && $3 == "primary" { print $4 }' $tmpf | sed 's/+.*//')
56 secondary_res=$(awk '$2 == "connected" && $3 != "primary" { print $3 }' $tmpf | sed 's/+.*//')
57
58 if [[ $secondary_res ]]; then
59 # assumes secondary is on the right
60 x_offset=${primary_res%%x*}
61 secondary_x=${secondary_res%%x*}
62 secondary_y=${secondary_res##*x}
63 stream_res=$(( secondary_x / 2 ))x$(( secondary_y / 2))
64 else
65 x_offset=0
66 stream_res=$primary_res
67 fi
68
69
70 opts=(
71 # nice to have: be a little less verbose
72 -hide_banner
73 -video_size $stream_res
74 -f x11grab
75 -framerate 4
76 # input options come before -i
77 -i :0.0+$x_offset.0
78 -vf drawbox=color=black
79 -vcodec libvpx
80 -g 8
81 -quality realtime
82 -threads 2
83 -error-resilient 1
84 -content_type video/webm
85 -f webm
86 icecast://source:$pass@$host/fsf$mount_suffix.webm
87
88 )
89
90
91 rm -f /tmp/iank-ffmpeg
92 mkfifo -m 0600 /tmp/iank-ffmpeg
93 echo executing: ffmpeg -stdin ${opts[@]}
94 # ffmpeg sits and waits until we do this. dunno why. whatever.
95 echo >/tmp/iank-ffmpeg &
96 ffmpeg ${opts[@]} </tmp/iank-ffmpeg