/subdir_files/.config/i3/config
/subdir_files/.config/sway/config
/.mblaze/cur
+# bash script for testing things
+/ms
# source /usr/share/doc/fzf/examples/key-bindings.bash
# fi
+# this looks more interesting for more easily selecting multiple files:
+# https://github.com/peco/peco?tab=readme-ov-file#keymaps
+# This also looks like it could be customized more than fzf:
+# https://github.com/lotabout/skim
+
# * functions
# shellcheck disable=SC2120 # we expect to pass arguments in use outside this file
etail() {
ngset
- tail -F /var/log/exim4/mainlog /var/log/exim4/*main /var/log/exim4/paniclog /var/log/exim4/*panic -n 200 "$@"
+ ta /var/log/exim4/mainlog /var/log/exim4/*main /var/log/exim4/paniclog /var/log/exim4/*panic -n 200 "$@"
ngreset
}
etailm() {
- tail -F /var/log/exim4/mainlog -n 200 "$@"
+ ta /var/log/exim4/mainlog -n 200 "$@"
}
etail2() {
- tail -F /var/log/exim4/nondmain -n 200 "$@"
+ ta /var/log/exim4/nondmain -n 200 "$@"
}
-# shortcut for tail -F
+
+# shortcut for tail -F + highlighting if we have it.
+tailf() {
+ if type -t batcat >/dev/null; then
+ # note: another useful useful style is "header"
+ tail -F "$@" | batcat --color always --style plain --theme Coldark-Cold -P
+ else
+ tail -F "$@"
+ fi
+ }
+
ta() {
- tail -F "$@"
+ bn ta "$@"
}
ccomp tail etail etail2 ta
# journalctl with times in the format the --since= and --until= options accept
jrt() { journalctl -e -n100000 -o short-full "$@"; }
jr() { journalctl -e -n100000 "$@" ; }
-jrf() { journalctl -n1000 -f "$@" ; }
+jrf() { SYSTEMD_COLORS=true bn journalctl -n1000 -f "$@" ; }
jru() {
# the invocation id is "assigned each time the unit changes from an inactive
# state into an activating or active state" man systemd.exec
q() { # start / launch a program in the backround and redir output to null
"$@" &> /dev/null &
}
+# quietly run command and then redisplay prompt on the same line.
+qr() {
+ local ret=0
+ "$@" &>/dev/null || ret=$?
+ # https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
+ # [2K = erase whole line
+ # [1A = go up one line. aka tput cuu 1
+ echo -ne "\e[1A\e[2K"
+ return $ret
+}
+# Execute then redo the prompt back at the original spot.
+# we = random easy to type command.
+#
+# Also echoes a block after the end of the output. If we didn't do that,
+# it would intermingle with previous output of this command.
+#
+# I wondered about doing this automatically for every command,
+# and I found https://unix.stackexchange.com/questions/562018/run-every-bash-command-through-a-function-or-wrapper
+# which gives me the idea that I could rebind enter to first
+# prefix the current command with a wrapper.
+# We could also use the debug trap to define a function of the about to be executed command,
+# but I don't know how to modify an existing function.
+#
+# todo: consider better handling of when linec > LINES
+#
+# todo: create a command which deletes the lines beneath the cursor (one probably already exists).
+we() {
+ local ret=0 out linec i tmp cur_line empty_lines clear_lines tmpf
+
+ # for wemode
+ while [[ $1 == we ]]; do
+ shift
+ done
+ # Give up if our command is part of a pipeline.
+ if ! test -t 1 || ! test -t 2; then
+ "$@" || ret=$?
+ return $ret
+ fi
+
+ tmpf=$(mktemp)
+ # note: Another way to do this without redirection would be with tput
+ # sc and tput rc, but if our command output past the bottom line of
+ # the terminal, we'd be restoring into the middle of its output.
+ "$@" &>$tmpf || ret=$?
+
+ # we can't do this because inside the {, some terminal escape sequences don't work right.
+ #"$@" |& { read -r -d '' out
+ out=$(cat $tmpf)
+ rm -- $tmpf
+ linec=0
+ if [[ $out ]]; then
+ # wc gives us 1 when out is an empty string because $() is not newline terminated.
+ linec=$(wc -l <<<"$out")
+ fi
+ # always clear the very next line after our prompt.
+ echo -ne "\e[2K"
+ clear_lines=$(( linec - 1 ))
+ if (( clear_lines > 0 )); then
+ # https://stackoverflow.com/questions/2575037/how-to-get-the-cursor-position-in-bash
+ # note, echoing $tmp at this point wont show anything because it is
+ # still an escape sequence.
+ IFS='[;' read -p $'\e[6n' -d R -rs tmp
+ tmp="${tmp%%;*}"
+ cur_line="${tmp##*[^0-9]}"
+ empty_lines=$(( LINES - cur_line ))
+ if (( empty_lines < linec )); then
+ clear_lines="$empty_lines"
+ fi
+ for (( i=0; i < linec - 1; i++ )); do
+ # 1B = go down one line
+ echo -ne "\e[1B\e[2K"
+ done
+ echo -ne "\e[${clear_lines}A\e[2K"
+ fi
+
+ if (( linec > 0 )); then
+ printf "%s\nā\n" "$out"
+ else
+ printf "ā\n"
+ fi
+ # see qr for escape code explanation
+ echo -ne "\e[$(( linec + 2 ))A\e[2K"
+ return $ret
+}
+
+# mode where every command is automatically wrapped in we()
+wemode() {
+ # c-space to set mark, eOH is begining of line (dunno how to press that
+ # on a keyboard). c-q is jump back to mark. c-j = alternate enter
+ #
+ # Another interesting variant of this which would handle pipelines
+ # would be to take "original | cmd" and make it be: "t() { original |
+ # cmd; }; we t"
+ #
+ # This has an annoying flaw that if we run a command from history that
+ # already starts with we, it adds another we. Might be able to fix it
+ # with some readline functionality, or the stackoverflow page has a
+ # bit about editing the last history entry, which I want to avoid
+ # saving the history file. It isn't a big deal, I'm just going to
+ # leave it. One idea is: history is editable, we could press up,
+ # remove the we, then press down.
+ bind '"\C-m": "\e \eOHwe \C-q\C-j"'
+}
+weoff() {
+ bind '"\C-m": accept-line'
+}
+
+# Run the command in the background and make its output go above our
+# prompt so it doesn't interfere with it. Especially useful for tailing
+# logs.
+#
+# The name bn is not special.
+#
+# Note: colorization will need to be turned on since it captures
+# output to a pipe, eg: SYSTEMD_COLORS=true bn journalctl -f
+bn() {
+ local line lwlc i
+ {
+ "$@" |& while read -r line; do
+ # lwlc = line wrapped line count.
+ lwlc=$(( ${#line} / COLUMNS + 1 ))
+ # from man terminfo
+ # tput sc = \e7 = save cursor
+ # tput rc = \e8 = restore cursor
+ # tput hpa 0 = \e[1G = move cursor to column 0
+ # tput il X = \e[XL = insert X lines
+ # tput ind = \eD = (according to
+ # https://superuser.com/questions/1106674/how-to-add-blank-lines-above-the-bottom-in-terminal
+ # But I can't verify because cannot be captured into a var from tput.)
+ #\e[XA = up X lines
+ for (( i=0; i < lwlc; i++ )); do
+ echo -ne "\eD"
+ done
+ echo -ne "\e7\e[${lwlc}A\e[1G\e[${lwlc}L$line\e8"
+ done
+ } &
+}
# shellcheck disable=SC2120
r() {
PROMPT_COMMAND='trap DEBUG; unset PROMPT_COMMAND; PS1=" \w \$ "'
}
-pskde() {
- # shellcheck disable=SC2178 # intentional
- PROMPT_COMMAND='trap DEBUG; unset PROMPT_COMMAND'
- PS1='\[\e]133;L\a\]\[\e]133;D;$?\]\[\e]133;A\a\]\w \$ \[\e]133;B\a\]' ;
- PS2='\[\e]133;A\a\]'$PS2'\[\e]133;B\a\]' ;
- PS0='\[\e]133;C\a\]'
-
-}
-
pson() {
PROMPT_COMMAND=(prompt-command)
if [[ $TERM == *(screen*|xterm*|rxvt*) ]]; then
# old enough to no longer condition on $BASH_VERSION anymore
shopt -s autocd
shopt -s dirspell
- PS1='\w'
if [[ $- == *i* ]] && [[ ! $LC_INSIDE_EMACS ]]; then
PROMPT_DIRTRIM=2
bind -m vi-command B:shell-backward-word
if [[ $SSH_CLIENT || $SUDO_USER ]]; then
unset PROMPT_DIRTRIM
- PS1="\h:$PS1"
fi
# emacs terminal has problems if this runs slowly,
prompt-command() {
local return=$? # this MUST COME FIRST
+ PS1='\w'
+ if [[ $SSH_CLIENT || $SUDO_USER ]]; then
+ PS1="\h:$PS1"
+ fi
# all usable colors:
# black
# red bold pwd different owner & group & writable (pri 2)
# yellow
- local ps_char ps_color
+ local ps_char ps_color col tmp
+
+ IFS='[;' read -p $'\e[6n' -d R -rs tmp
+ col="${tmp##*[^0-9]}"
+
unset IFS
if [[ $HISTFILE ]]; then
fi
jobs_char=
if [[ $(jobs -p) ]]; then
- jobs_char="$(jobs -p)"'j\j '
+ jobs_char='j\j '
fi
fi
PS1="${PS1%"${PS1#*[wW]}"} $jobs_char$psudo\[$ps_color\]$ps_char\[$term_nocolor\] "
+ # If the last command was not newline terminated, add a space (so we
+ # can more easily copy the output if needed), and an indicator to
+ # help us not be confused.
+ if [[ $col != 1 ]]; then
+ PS1=" \[$term_yellow\]ā\[$term_nocolor\]$PS1"
+ fi
# copy of what is automatically added by guix.
fi
fi
+ # version 211203 does not have this feature, 230805 does
+ if [[ $KONSOLE_VERSION && $KONSOLE_VERSION == [3456789]* || $KONSOLE_VERSION == 2[3456789]* ]]; then
+ # This is from konsole, copied after pressing ctrl-alt-] .
+ # I figured out what it does from reading git clone https://gitlab.freedesktop.org/Per_Bothner/specifications
+ #
+ #proposals/semantic-prompts.md
+ #
+ # I tried figuring out what they really do from the konsole source code,
+ # but I gave up.
+ #
+ # \[\e]133;L\a\] This makes it so the last command is always
+ # newline terminated. That is kind nice, but I also want to know
+ # when they aren't, and this screws up my we() function, so
+ # removed. The doc notes that Fish and ZSH both show a specific
+ # char to indicate that happened, that sounds nice so I figured
+ # out how to do that on my own.
+ #
+ # \[\e]133;D;$?\]
+ # This is something to try to show the last exit code. I already do that
+ # and colorize it so removed.
+ #
- # set titlebar. instead, using more advanced
- # titelbar below
- #echo -ne "$_title_escape $HOSTNAME ${PWD/#$HOME/~} \007"
-
- # version 211203 does not have this feature.
- if [[ $KONSOLE_VERSION && $KONSOLE_VERSION == [3456789]* || $KONSOLE_VERSION == 2[2456789]* ]]; then
- # from konsole, output via ctrl-alt-]
if [[ ! $PS1 =~ 133 ]] ; then
- PS1='\[\e]133;L\a\]\[\e]133;D;$?\]\[\e]133;A\a\]'$PS1'\[\e]133;B\a\]' ;
- PS2='\[\e]133;A\a\]'$PS2'\[\e]133;B\a\]' ;
- PS0='\[\e]133;C\a\]' ; fi
+ PS1='\[\e]133;A\a\]'"$PS1"'\[\e]133;B\a\]'
+ PS2='\[\e]133;A\a\]'"$PS2"'\[\e]133;B\a\]'
+ # shellcheck disable=SC2034 # false positive
+ PS0='\[\e]133;C\a\]'
+ fi
fi
}
if [[ $1 == prompt-command ]]; then
return 0
fi
+ # note: this could be useful to do something interesting.
+ #_iank_last_cmd="$*"
echo -ne "$_title_escape ${PWD/#$HOME/~} "
printf "%s" "$*"
echo -ne "\007"
/a/opt/timetrap/bin/t d -ftotal -s $day -e $day all -m '^w|lunch$'
done
}
-to() { t out -a "$@"; }
-ti() { t in -a "$@"; }
-tl() {
+to() { we t out -a "$@"; }
+ti() { we t in -a "$@"; }
+
+_tl() {
local in_secs
to "$*"
t s lunch
m t out -a "$(date +%F.%T -d @$(( in_secs + 60*45 )) )"
t s w
}
-
+tl() {
+ we _tl "$@"
+}
# help me focus. opens 2 windows.
focus() {
[[ $1 ]] || { echo need arg; return 1; }
journalctl --since=now --unit=$vpn_service@$1 -f -n0 &
+ # might be able to go lower than 1
+ sleep 1
sudo systemctl start $vpn_service@$1
# sometimes the ask-password agent does not work and needs a delay.
sleep .5
ffmpeg -i "$in" -c:v libsvtav1 -crf 60 -preset 6 -g 60 -svtav1-params tune=0:enable-overlays=1:scd=1:scm=1 -pix_fmt yuv420p10le -c:a copy "$out"
}
+localai() {
+ schroot -c bookworm
+ }
+
export BASEFILE_DIR=/a/bin/fai-basefiles
#export ANDROID_HOME=/a/opt/android-home
+#!/bin/bash
+
+set -e
-### begin docker install ####
-if isdeb; then
# https://docs.docker.com/engine/install/ubuntu/
-sudo mkdir -p /etc/apt/keyrings
+# Add Docker's official GPG key:
+sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
+sudo chmod a+r /etc/apt/keyrings/docker.asc
+
+# Add the repository to Apt sources:
+echo \
+ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
+ $(debian-codename-compat) stable" | \
+ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+sudo apt-get update
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
-# lsb_release -cs -> debian-codename-compat
-echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(debian-codename-compat) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
p update
- pi software-properties-common apt-transport-https
- curl -fsSL https://download.docker.com/linux/$(distro-name-compat)/gpg | sudo apt-key add -
- url=https://download.docker.com/linux/$(distro-name-compat)
- l="deb [arch=amd64] $url $codename_compat stable"
-
- if ! grep -xFq "$l" /etc/apt/sources.list{,.d/*.list}; then
- sudo add-apt-repository "$l"
- p update
- fi
- # docker eats up a fair amount of cpu when doing nothing, so don't enable it unless
- # we really need it.
- pi-nostart docker-ce
- # and docker is even more crap, it ignores that it shouldnt start
- ser stop docker
- ser disable docker
- case $HOSTNAME in
- li|lj) sgo docker ;;
- esac
-fi
+# docker eats up a fair amount of cpu when doing nothing, so don't enable it unless
+# we really need it.
+pi-nostart docker-ce
+# case $HOSTNAME in
+# li|lj) sgo docker ;;
+# *)
+# # and docker is even more crap, it ignores that it shouldnt start
+# ser stop docker
+# ser disable docker
+# ;;
+# esac
### end docker install ####
fi
if [[ ! -e /usr/share/debootstrap/scripts/noble ]]; then
- t=$(mktemp -d)
- cd $t
- m aptitude download debootstrap/noble
- m ex ./*
- sudo cp ./usr/share/debootstrap/scripts/* /usr/share/debootstrap/scripts
+ # noble debootstrap as of 2024-07-05. not going to bother
+ # adding a whole repo for one package which doesn't seem to generally change within a single distro version.
+ sudo dpkg -i /a/opt/debootstrap_1.0.134ubuntu1_all.deb
fi
;;&
usage() {
cat <<EOF
+Somewhat hacky script to watch whatever screencast I'm creating with ffs.
+
Usage: ${0##*/} [-d] [sysops|tech|staff]
3 mountpoints: fsf-sysops (default, public), fsf (all staff), fsf-tech (tech team)
-d debug. start unmuted.
-note: args duplicated in ffp
+todo: add -n dry run which will for print out suggested commands for viewers
+
+Note: full screen will cause distortion in fonts. I dunno why, seems like ffplay is a bit buggy
+
+note: some args duplicated in ffp
ret=0; getopt -T || ret=$?
[[ $ret == 4 ]] || { echo "Install util-linux for enhanced getopt" >&2; exit 1; }
+debug=false
volume=0
temp=$(getopt -l help hdw "$@") || usage 1
eval set -- "$temp"
while true; do
case $1 in
- -d) volume=100 ;;
+ -d)
+ volume=100
+ debug=true
+ ;;
-h|--help) usage ;;
--) shift; break ;;
*) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
##### end command line parsing ########
-
host=https://live.iankelling.org:443
live_host=$(dig +timeout=1 +short @iankelling.org live.iankelling.org)
vps_host=$(dig +timeout=1 +short iankelling.org)
host=http://127.0.0.1:8000
fi
+url=$host/fsf$mount_suffix.webm
+
+files=(~/2*.webm)
+file=${files[@]}
+if [[ -e $file ]]; then
+ url=$file
+fi
+
opts=(
-v error
+ #-v debug
-hide_banner
-nostats
-volume $volume
- -f webm
-fast
-fflags nobuffer
-flags low_delay
- -i $host/fsf$mount_suffix.webm
+ # makes it a floating window in i3 and avoids scaling
+ -noborder
+ -f webm
+ -i $url
-autoexit
- )
+)
+if $debug; then
+ echo running: ffplay "${opts[@]}"
+fi
ffplay "${opts[@]}"
+
+# # working mpv, but still a second or so slower than ffplay.
+# mpv_opts=(
+# # these seem to have no effect on latency
+# #--no-cache
+# #--untimed
+# --no-demuxer-thread
+# --vd-lavc-threads=1
+# --volume=$volume
+# --video-unscaled
+# $host/fsf$mount_suffix.webm
+# )
+
+# todo: make more mountpoints for other ppl to stream
+# todo: make raw recordings accessible to public, for public streams.
+#
# See the License for the specific language governing permissions and
# limitations under the License.
-# ffs = ffmpeg stream
-
-# potential improvement: it might be nice that we could have a tall terminal but only use
+# potential feature: it might be nice that we could have a tall terminal but only use
# the top half for a 1080p stream, this is how:
# https://superuser.com/questions/1106674/how-to-add-blank-lines-above-the-bottom-in-terminal
+# Another way to do this is with tput csr 0 $(( LINES - something ))
+# as in https://stackoverflow.com/questions/51175911/line-created-with-tput-gets-removed-on-scroll
+# however, that makes it so if you run man, it won't start at the top, then you
+# move around to see the top and exit, your cursor is in a nonscrolling region
+# which we do not want.
if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
usage() {
cat <<EOF
+ffs = ffmpeg stream
+
Usage: ${0##*/} [OPTIONS] [sysops|tech|staff|test]
arg is icecast mountpoint suffix, except staff removes suffix.
--d debug.
+-d DEBUG_FLAGS Debug (implies -w). Flags are as follows:
+ x no flags, just basic debug.
+ a Avoid hw accel even if it is available.
+ l loud/listen. Start unmuted. Usually for testing.
+ v extra verbose debug output.
+-m Minimal resources for video, for low powered computers.
+-r Make local recording instead of sending to icecast.
-s SPLIT_TYPE
- full: full screen even high resolution.
- tall (default): half screen.
+ f|full: full screen even high resolution.
+ t|tall (default): half screen.
quarter: self evident
--l loud/listen. Start unmuted. Usually for testing.
-u Undelayed. Removes 5 second video delay, and about 4 second audio delay.
-w do not launch watch of stream
+-8 Use vp9 instead of default vp9.
note: args duplicated in ffp
EOF
exit $1
}
+set-bitrate() {
+ bitrate=$(( ( stream_x * stream_y ) / ( (1920*1080) / $1 ) ))
+
+}
##### begin command line parsing ########
[[ $ret == 4 ]] || { echo "Install util-linux for enhanced getopt" >&2; exit 1; }
ffp_args=()
+
debug=false
delay=true
+local=false
loglevel=fatal
-watch=true
+mvv=false
+try_accel=true
volume=0
+vp9=true
+watch=true
+
fullscreen=false
tall=true
-mvv=false
-temp=$(getopt -l help hdlms:uw "$@") || usage 1
+
+temp=$(getopt -l help hd:mrs:uw8 "$@") || usage 1
eval set -- "$temp"
while true; do
case $1 in
-d)
debug=true
- loglevel=debug
loglevel=info
ffp_args+=(-d)
- ;;
- -l)
- volume=1
+ case $2 in
+ *a*)
+ try_accel=false
+ ;;&
+ *l*)
+ volume=1
+ ;;&
+ *v*)
+ loglevel=debug
+ ;;&
+ esac
+ shift
;;
-m)
mvv=true
;;
+ -r)
+ local=true
+ ;;
-s)
case $2 in
- tall)
+ tall|t)
fullscreen=false
tall=true
;;
- quarter)
+ quarter|q)
fullscreen=false
tall=false
;;
- full)
+ full|f)
fullscreen=true
tall=false
;;
+ *)
+ echo "unknown split type: $2" >&2
+ exit 1
+ ;;
esac
shift
;;
-u)
delay=false
;;
+ -8)
+ vp9=false
+ ;;
-h|--help) usage ;;
--) shift; break ;;
*) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
##### end command line parsing ########
-host=live.iankelling.org:8443
-live_host=$(dig +timeout=1 +short @iankelling.org live.iankelling.org)
-vps_host=$(dig +timeout=1 +short iankelling.org)
-if [[ $live_host != "$vps_host" ]] && ip n show 10.2.0.1 | grep . &>/dev/null && \
- [[ $(dig +timeout=1 +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]]; then
- host=127.0.0.1:8000
- if ! pgrep '^icecast2$' >/dev/null; then
- sudo systemctl start icecast2
+if ! $local; then
+ host=live.iankelling.org:8443
+ live_host=$(dig +timeout=1 +short @iankelling.org live.iankelling.org)
+ vps_host=$(dig +timeout=1 +short iankelling.org)
+ if [[ $live_host != "$vps_host" ]] && ip n show 10.2.0.1 | grep . &>/dev/null && \
+ [[ $(dig +timeout=1 +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]]; then
+ host=127.0.0.1:8000
+ if ! pgrep '^icecast2$' >/dev/null; then
+ sudo systemctl start icecast2
+ fi
+ else
+ find_prefix="ssh live.iankelling.org"
fi
-else
- find_prefix="ssh live.iankelling.org"
-fi
-if $find_prefix find /var/icecast -type f | grep .; then
- echo "warning: suggest clearing /var/icecast with icrmr or moving files. sleeping for 4 seconds"
- sleep 4
-fi
-
-
-pass=$(sed -n 's/ *<source-password>\([^<]*\).*/\1/p' /p/c/icecast.xml)
+ if $find_prefix find /var/icecast -type f | grep .; then
+ echo "warning: suggest clearing /var/icecast with icrmr or moving files. sleeping for 4 seconds"
+ sleep 4
+ fi
+ pass=$(sed -n 's/ *<source-password>\([^<]*\).*/\1/p' /p/c/icecast.xml)
+fi
-tmpf=$(mktemp)
-xrandr >$tmpf
+xrandr=$(xrandr)
# example xrandr output: 1280x800+0+0
-primary_res=$(awk '$2 == "connected" && $3 == "primary" { print $4 }' $tmpf | sed 's/+.*//')
-tmp=$(awk '$2 == "connected" && $3 != "primary" { print $3 }' $tmpf | sed 's/+/ /g')
+primary_res=$(awk '$2 == "connected" && $3 == "primary" { print $4 }' <<<"$xrandr" | sed 's/+.*//')
+tmp=$(awk '$2 == "connected" && $3 != "primary" { print $3 }' <<<"$xrandr" | sed 's/+/ /g')
read -r secondary_res x_offset _ <<<"$tmp"
-
if [[ $secondary_res ]]; then
- secondary_x=${secondary_res%%x*}
- secondary_y=${secondary_res##*x}
- if $fullscreen; then
- stream_res=$secondary_res
- elif $tall; then
- stream_res=$(( secondary_x / 2 ))x$secondary_y
- else
- stream_res=$(( secondary_x / 2 ))x$(( secondary_y / 2))
- fi
+ target_res=$secondary_res
else
x_offset=0
- stream_res=$primary_res
+ target_res=$primary_res
+fi
+target_x=${target_res%%x*}
+target_y=${target_res##*x}
+if $fullscreen; then
+ stream_res=$target_res
+elif $tall; then
+ stream_res=$(( target_x / 2 ))x$target_y
+else
+ stream_res=$(( target_x / 2 ))x$(( target_y / 2))
fi
stream_x=${stream_res%x*}
stream_res=$(( stream_x - 4 ))x$(( stream_y - 4))
-# if hardware acceleration exists, use it to save power & cpu.
-if vainfo |& grep -i VAProfileVP9Profile &>/dev/null; then
- # 1500 seems almost flawless
- bitrate_1080=1500
-
- encode_settings=(
- -c:v vp9_vaapi
- # these options increase compression based on random internet reference.
- -bsf:v vp9_raw_reorder,vp9_superframe
- )
- # https://trac.ffmpeg.org/wiki/Hardware/VAAPI
- global_extra_args=(
- -vaapi_device /dev/dri/renderD128
- )
- extra_filter_arg=",format=nv12|vaapi,hwupload"
+# 1000 is a bit blury, 1500 is pretty clear, 2000 makes scrolling
+# adjust much faster, 2500 has marginal improvement on that.
+#
+# note https://livekit.io/webrtc/bitrate-guide
+if $mvv; then
+ set-bitrate 1000
else
- # 1000 is a bit blury, 1500 is pretty clear, 2000 makes scrolling
- # adjust much faster, 2500 has marginal improvement on that.
- #
- # note https://livekit.io/webrtc/bitrate-guide
- if $mvv; then
- bitrate_1080=1000
- else
- bitrate_1080=2000
- fi
-
- encode_settings=(
- -vcodec libvpx
- -quality realtime
- -error-resilient 1
- )
+ set-bitrate 2000
fi
-bitrate=$(( ( stream_x * stream_y ) / ( (1920*1080) / bitrate_1080 ) ))
+encode_settings=(
+ -vcodec libvpx
+ -quality realtime
+ -error-resilient 1
+ -b:v ${bitrate}k
+)
+if $vp9; then
+ # if hardware acceleration exists, use it to save power & cpu.
+ if $try_accel && vainfo |& grep -i VAProfileVP9Profile &>/dev/null; then
+ # 1500 seems almost flawless. 1200 still very good. 700k actual of 1080p tall.
+ set-bitrate 1200
+
+ encode_settings=(
+ -vcodec vp9_vaapi
+ # these options increase compression based on random internet reference.
+ -bsf:v vp9_raw_reorder,vp9_superframe
+ -b:v ${bitrate}k
+ )
+ # https://trac.ffmpeg.org/wiki/Hardware/VAAPI
+ global_extra_args=(
+ # not documented in man page, only here:
+ # https://trac.ffmpeg.org/wiki/Hardware/VAAPI
+ -vaapi_device /dev/dri/renderD128
+ )
+ extra_filter_arg=",format=nv12|vaapi,hwupload"
+ else
+ # https://trac.ffmpeg.org/wiki/Encode/VP9. note, these docs are a bit
+ # shit because they don't fully explain modes and conflicting options.
+ encode_settings=(
+ # https://developers.google.com/media/vp9/live-encoding
+ -tile-columns 2
+ -row-mt 1
+ -frame-parallel 1
+ -error-resilient 1
+ -vcodec vp9
+ # default can have wrong color for hardware decoders.
+ # this is what vp8 uses, It doesn't seem like there any
+ # functional difference I should care about
+ -pix_fmt yuv420p
+ )
+ if $mvv; then
+ encode_settings+=(
+ -b:v ${bitrate}k
+ -deadline realtime
+ -cpu-used 8
+ )
+ else
+ encode_settings+=(
+
+ # https://developers.google.com/media/vp9/bitrate-modes use Q mode.
+ -b:v 0
+ -crf 45
+ # use the least cpu possible in this mode since it uses a lot
+ # relatively, bitrate jumps a bit, quality suffers a bit.
+ -cpu-used 5
+ )
+ fi
+ fi
+fi
+
if $mvv; then
framerate=5
else
framerate=10
fi
+# todo: decide 2 vs 3. maybe vary between vp8 & vp9
keyframe_interval=$((framerate * 2))
# Monitor of default sink.
# this is for ffmpeg warnings. doesnt seem to affect latency.
# 160 was too small. at 300, it occasionally complains,
# probably only when we are using delayed output
-thread_queue_size_arg="-thread_queue_size 500"
+thread_queue_size_arg="-thread_queue_size 800"
# hardcoded switch for debugging
doaudio=true
if $doaudio; then
audio_out_args=(
- -c:a libvorbis
+ -acodec libopus
-b:a 92k
# afaik, this ensures that the amerge doesn't make 4 channel output if
# our output format supported it.
-ac 2
)
audio_in_args=(
-
-f pulse
-name ffs
# note: duplicated
-i "$pa_sink"
)
filter_args=(
- # Video + audio filter. Note: this has only the things we actually need in it.
- #
- # volume=precision=fixed fixes this error:
- # The following filters could not choose their formats: Parsed_amerge_4.
- #
- # Default volume precision is float. Our input is fixed. maybe ffmpeg
- # thinks the input could change and so can't commit to an output.
- # The error suggests using aformat, which seems like it would probably
- # also fix the error.
- #
- # man page say zmq url default includes "localhost", but specifying a
- # localhost url caused an error for me.
- -filter_complex "[0]azmq,volume=precision=fixed: volume=$volume [vol0];
+ # Video + audio filter. Note: this has only the things we actually need in it.
+ #
+ # volume=precision=fixed fixes this error:
+ # The following filters could not choose their formats: Parsed_amerge_4.
+ #
+ # Default volume precision is float. Our input is fixed. maybe ffmpeg
+ # thinks the input could change and so can't commit to an output.
+ # The error suggests using aformat, which seems like it would probably
+ # also fix the error.
+ #
+ # man page say zmq url default includes "localhost", but specifying a
+ # localhost url caused an error for me.
+ -filter_complex "[0]azmq,volume=precision=fixed: volume=$volume [vol0];
[1]azmq='b=tcp\://127.0.0.1\:5556',volume=precision=fixed: volume=0 [vol1];
[vol0][vol1] amerge=inputs=2;
-[2]zmq='b=tcp\://127.0.0.1\:5557',drawbox=color=0x262626,drawtext=fontsize=90: fontcolor=beige: x=40: y=40: text=''${delay_arg}${extra_filter_arg}[out]"
-
- # An online source says to match a 5 second vid delay, we can do an
- # audio delay filter: "adelay=5000|5000". However, we already get
- # a stream delay of about 2 seconds, and having the audio be about
- # 2 seconds ahead is fine, they do that intentionally in soccer
- # matches.
-
- # Based on error message and poking around, it seems ffmpeg is not
- # smart enough to see that [vol0] and [vol1] are inputs to the amerge
- # filter, and thus we would not want them as final outputs. So, we
- # have to identify the amerge output and pass it to -out. This
- # identifier is called an "output pad" in man ffmpeg-filters, and a
- # "link label" in man ffmpeg.
- -map '[out]'
+[2]zmq='b=tcp\://127.0.0.1\:5557',drawbox=color=0x262626,drawtext=fontsize=90: fontcolor=beige: x=40: y=40: text=''${delay_arg}${extra_filter_arg}[vout]"
+
+ # Based on error message and poking around, it seems ffmpeg is not
+ # smart enough to see that [vol0] and [vol1] are inputs to the amerge
+ # filter, and thus we would not want them as final outputs. So, we
+ # have to identify the amerge output and pass it to -out. This
+ # identifier is called an "output pad" in man ffmpeg-filters, and a
+ # "link label" in man ffmpeg.
+ -map '[vout]'
+
+ # An online source says to match a 5 second vid delay, we can do an
+ # audio delay filter: "adelay=5000|5000". However, we already get
+ # a stream delay of about 2 seconds, and having the audio be about
+ # 2 seconds ahead is fine, they do that intentionally in soccer
+ # matches.
+ )
+fi
+
+if $local; then
+ out_file_opts=(
+ "$HOME/$(date +%F_%H_%M_%S%:::z).webm"
+ )
+else
+
+ out_file_opts=(
+ -content_type video/webm
+ -f webm
+ icecast://source:$pass@$host/fsf$mount_suffix.webm
)
fi
# video output options
- -g $keyframe_interval
${encode_settings[@]}
- -b:v ${bitrate}k
+ -g $keyframe_interval
+ ${out_file_opts[@]}
- -content_type video/webm
- -f webm
- icecast://source:$pass@$host/fsf$mount_suffix.webm
)
rm -f /tmp/iank-ffmpeg-interlude-toggle
fi
}
-move-ws() {
- local target_out output tmps
- target_out=$1
- shift
-
- if [[ ! ${ws_out[*]} ]]; then
- declare -a ws_out
- tmps=$(i3 -t get_workspaces)
- if [[ ! $tmps ]]; then
- return 0
- fi
- tmps=$(jq -r '.[] | .num, .output' <<<"$tmps")
- while read -r ws; do
- read -r output || break
- ws_out["$ws"]=$output
- done <<<"$tmps"
- fi
-
- for ws; do
- if [[ ${ws_out[$ws]} && ${ws_out[$ws]} != "$target_out" ]]; then
- # if the workspace is already there, this will fail.
- # if the workspace doesn't exist yet, it fails with:
- # ERROR: No output matched
- m i3 '[workspace="'$ws'"]' move workspace to output $target_out
- fi
- done
-}
-
date "+%A, %B %d, %r, %S seconds"
## begin i3 config ##
+move_outputs=()
+ws_outputs=()
if [[ $secondary_out ]]; then
ws1_output=$primary_out
move_outputs=($primary_out)
-else
- move_outputs=()
+elif $tall || $quarter; then
ws1_output=MON-RIGHT
fi
$ws1_output
)
+
if $tall; then
ws_outputs+=(
MON-LEFT
MON-RIGHT
)
move_outputs+=(MON-BOTTOM-LEFT MON-RIGHT)
+elif [[ $secondary_out ]]; then
+ move_outputs+=($secondary_out)
+ ws_outputs+=($secondary_out)
+
fi
echo d1 ${ws_outputs[@]}
-if (( ${#move_outputs[@]} == 0 )); then
- move_outputs=(right)
-fi
-
rm -f ~/i3-myx.conf
total_ws_count=10
for (( i=0; i<total_ws_count; i++ )); do
ws=$(( i+1 ))
tmp=${ws_outputs[$i]}
- echo tmp: $tmp
# use the last output in the array for all remaining workspaces
if [[ $tmp ]]; then
ws_out=$tmp
fi
echo "workspace $ws output $ws_out" >>~/i3-myx.conf
done
+if [[ $secondary_out ]]; then
+ cat /a/bin/ds/i3-sway/bar.conf >> ~/i3-myx.conf
+fi
echo "bindsym \$mod+Shift+t move workspace to output ${move_outputs[*]}" >>~/i3-myx.conf
m /a/bin/ds/i3-sway/gen
-
-# this bit is so that we only move workspaces that need to be moved
-# and we don't have to ignore errors. A waste of time, but
-# it was fun.
-declare -A ws_to_out
-tmps=$(i3 -t get_workspaces)
-tmps=$(jq -r '.[] | .num, .output' <<<"$tmps")
-while read -r ws; do
- read -r output || break
- ws_to_out["$ws"]=$output
-done <<<"$tmps"
-
-for (( i=0; i<total_ws_count; i++ )); do
- ws=$(( i+1 ))
- tmp=${ws_outputs[$i]}
- echo tmp: $tmp
- # use the last output in the array for all remaining workspaces
- if [[ $tmp ]]; then
- ws_out=$tmp
- fi
- if [[ ${ws_to_out[$ws]} && ${ws_to_out[$ws]} != "$ws_out" ]]; then
- m i3 '[workspace="'$ws'"]' move workspace to output $ws_out
- fi
-done
+# give it some time to reload
+sleep 1
+
+if (( ${#ws_outputs[@]} )); then
+ # this bit is so that we only move workspaces that need to be moved
+ # and we don't have to ignore errors. A waste of time, but
+ # it was fun.
+ declare -A ws_to_out
+ tmps=$(i3 -t get_workspaces)
+ tmps=$(jq -r '.[] | .num, .output' <<<"$tmps")
+ while read -r ws; do
+ read -r output || break
+ ws_to_out["$ws"]=$output
+ done <<<"$tmps"
+
+ for (( i=0; i<total_ws_count; i++ )); do
+ ws=$(( i+1 ))
+ tmp=${ws_outputs[$i]}
+ echo "tmp: $tmp"
+ # use the last output in the array for all remaining workspaces
+ if [[ $tmp ]]; then
+ ws_out=$tmp
+ fi
+ if [[ ${ws_to_out[$ws]} && ${ws_to_out[$ws]} != "$ws_out" ]]; then
+ m i3 '[workspace="'$ws'"]' move workspace to output $ws_out
+ fi
+ done
+fi
## end i3 config ##
+++ /dev/null
-[Launchpad]
-host = .launchpad.net
-scheme = ssh
-user = iank
bold_is_bright=false
paste_button=2
menu_button=3
+show_tab_bar=multiple
+copy_on_select=false
+window_columns=80
+window_rows=24
SemanticUpDown=false
[Interaction Options]
+AlternateScrolling=true
+MouseWheelZoomEnabled=true
OpenLinksByDirectClickEnabled=false
TextEditorCmd=6
TextEditorCmdCustom=/a/exe/g +LINE:COLUMN PATH
WordCharacters=@-./_~?&=%+#
[Keyboard]
-KeyBindings=ian
+KeyBindings=default
[Scrolling]
HistorySize=100000
[Terminal Features]
+BellMode=3
UrlHintsModifiers=0
<LSGT> = 94;
# down
<FK11> = 116;
- # todo: right, 114 is unused
+ # todo: right/rght, 114 is unused
<FK12> = 66;
<AB11> = 97;
<KATA> = 98;