#!/bin/bash
# run to capture audio, encode it to memory as high-quality ogg opus,
# then at any time save a replay of the last minutes of audio.
# REQUIRES logbufpipe, ffmpeg, date, pgrep, ps, tee, head, bash, and pwd in /tmp.
# bitrate: 512k -> 512*60/8 = 3.75 MiB/min, 225 MiB/hour.
# currently configured to record up to 60 minutes of audio using up to 250 MiB of memory.
DIR='/tmp/opusreplay1'
MONITOR='mark_combine_out_2.monitor'
# [ SETUP ]
mkdir -p "$DIR"
cd "$DIR" || exit 1
# [ CAPTURING via ffmpeg ]
ffmpeg -y -f pulse -i "$MONITOR" \
-flush_packets 1 -f ogg -c:a libopus -application lowdelay \
-b:a 512k - \
| logbufpipe 230M audio.lbp \
| head -c 1K > head.opus &
SRV="$(pgrep -P "$$" -n ffmpeg)"
# [ WEBUI via pyhttpcgi ]
echo 'not running' > index.html
tee save stop ls replay get rename delete > index <<< '#!/bin/bash'
chmod +x save stop ls replay get rename delete index
mkdir -p replays
mkdir -p deleted
echo "pgrep --quiet --pid '$SRV' || exit 1" >> index
echo "echo 'ffmpeg PID $SRV TIME'" >> index
echo "ps -p '$SRV' -o etime" >> index
echo "echo '(dont save more than this)'" >> index
echo 'echo '"'"'
$ARG_f"' >> replay
echo 'ls -lh "replays/$ARG_f"' >> replay
echo 'echo ""' >> replay
echo 'cat "replays/$ARG_f"' >> get
echo 'if [ -z "$ARG_from" ] || [ -z "$ARG_to" ]; then exit 1; fi' >> rename
echo 'mv -b "replays/$ARG_from" "replays/$ARG_to.opus" && echo renamed || echo rename failed' >> rename
echo 'if [ -z "$ARG_from" ]; then exit 1; fi' >> delete
echo 'mv "replays/$ARG_from" "deleted"' >> delete
python3 -c "$(base64 -d <<< ZnJvbSBodHRwLnNlcnZlciBpbXBvcnQgQmFzZUhUVFBSZXF1ZXN0SGFuZGxlciwgSFRUUFNlcnZlcgpmcm9tIHVybGxpYi5wYXJzZSBpbXBvcnQgdXJsc3BsaXQsIHBhcnNlX3FzCmZyb20gc3VicHJvY2VzcyBpbXBvcnQgcnVuCmZyb20gc3lzIGltcG9ydCBhcmd2LCBleGl0CmZyb20gb3MgaW1wb3J0IGVudmlyb24KCmlmIGxlbihhcmd2KSA8PSAxOgoJcHJpbnQoIkFyZzogYWRkcjpwb3J0LCBvciBwb3J0IChsb2NhbGhvc3QpLCBvciA6cG9ydCAoYWxsIGludGVyZmFjZXMpIikKCWV4aXQoMCkKaWYgJzonIGluIGFyZ3ZbMV06CglBRERSID0gYXJndlsxXS5yc3BsaXQoJzonLCAxKQoJUE9SVCA9IGludChBRERSWzFdKQoJQUREUiA9IEFERFJbMF0KZWxzZToKCUFERFIgPSAnbG9jYWxob3N0JwoJUE9SVCA9IGludChhcmd2WzFdKQpwcmludChmJ0xpc3RlbmluZyBvbiB7QUREUiBvciAnKid9OntQT1JUfScpCgp0cnk6Cgl3aXRoIG9wZW4oJ2luZGV4Lmh0bWwnLCAncmInKSBhcyBmOgoJCUlYID0gZi5yZWFkKCkKZXhjZXB0OgoJSVggPSBOb25lCgpkZWYgYWxudW0odik6CglyZXR1cm4gYWxsKChjIGluICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OV8tLicgZm9yIGMgaW4gdikpIGFuZCBub3Qgdi5zdGFydHN3aXRoKCIuIikKCmNsYXNzIEhhbmRsZXIoQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CglkZWYgZG9fR0VUKHNlbGYpOgoJCXUgPSB1cmxzcGxpdChzZWxmLnBhdGgpCgkJcCA9IHUucGF0aAoJCWEgPSBwYXJzZV9xcyh1LnF1ZXJ5KQoJCWlmIHAuc3RhcnRzd2l0aCgnLycpOgoJCQlwID0gcFsxOl0KCQlpZiBub3QgYWxudW0ocCk6CgkJCXNlbGYuc2VuZF9yZXNwb25zZSg0MDApCgkJCXNlbGYuZW5kX2hlYWRlcnMoKQoJCQlyZXR1cm4KCQljdCA9IE5vbmUKCQlpZiBsZW4ocCkgPT0gMDoKCQkJcCA9ICdpbmRleCcKCQkJY3QgPSBJWAoJCXRyeToKCQkJZW52ID0gTm9uZQoJCQlpZiBsZW4oYSkgPiAwOgoJCQkJZW52ID0gZGljdChlbnZpcm9uKQoJCQkJZm9yIGsgaW4gYToKCQkJCQlpZiBhbG51bShrKSBhbmQgbGVuKGFba10pID09IDEgYW5kIGFsbnVtKGFba11bMF0pOgoJCQkJCQllbnZbZidBUkdfe2t9J10gPSBhW2tdWzBdCgkJCWMgPSBydW4oYXJncz1bZicuL3twfSddLCBlbnY9ZW52LCBjaGVjaz1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlKQoJCQljdCA9IGMuc3Rkb3V0CgkJZXhjZXB0OgoJCQlwYXNzCgkJaWYgY3QgaXMgTm9uZSBhbmQgKElYIGlzIE5vbmUgb3IgcCAhPSAnaW5kZXgnKToKCQkJc2VsZi5zZW5kX3Jlc3BvbnNlKDQwMCkKCQkJc2VsZi5lbmRfaGVhZGVycygpCgkJCXJldHVybgoJCXNlbGYuc2VuZF9yZXNwb25zZSgyMDApCgkJc2VsZi5zZW5kX2hlYWRlcignQ29udGVudC10eXBlJywgJ3RleHQvaHRtbCcpCgkJc2VsZi5lbmRfaGVhZGVycygpCgkJc2VsZi53ZmlsZS53cml0ZShjdCkKCkhUVFBTZXJ2ZXIoKEFERFIsIFBPUlQpLCBIYW5kbGVyKS5zZXJ2ZV9mb3JldmVyKCkK)" \
:2602
echo "goodbye"
# [ SAVING via optional ffmpeg without webui ]
# MIN=1 SEC=0 \
# ; (KIB="$(($MIN*3840+$SEC*64))" ; cat head.opus ; logbufpipe raw "$KIB"K audio.lbp | head -c "$((KIB+128))"K) \
# | ffmpeg -f ogg -i - -f ogg -c:a copy -ss 2 replay_"$(date -I)"_"$(date +%H-%M-%S)".opus