aboutsummaryrefslogtreecommitdiffstats
path: root/.config
diff options
context:
space:
mode:
Diffstat (limited to '.config')
-rw-r--r--.config/init/funcreqs/audio-concat2
-rw-r--r--.config/init/funcreqs/audio-convert2
-rwxr-xr-x.config/init/funcs/audio-concat127
-rwxr-xr-x.config/init/funcs/audio-convert233
-rwxr-xr-x.config/init/funcs/mpd-cover-convert8
-rwxr-xr-x.config/init/funcs/scap4
-rw-r--r--.config/init/helpers77
-rw-r--r--.config/ranger/rifle.conf5
8 files changed, 453 insertions, 5 deletions
diff --git a/.config/init/funcreqs/audio-concat b/.config/init/funcreqs/audio-concat
new file mode 100644
index 0000000..b3cc909
--- /dev/null
+++ b/.config/init/funcreqs/audio-concat
@@ -0,0 +1,2 @@
+func_init_prereqs=(ffmpeg)
+func_init_checks=()
diff --git a/.config/init/funcreqs/audio-convert b/.config/init/funcreqs/audio-convert
new file mode 100644
index 0000000..b3cc909
--- /dev/null
+++ b/.config/init/funcreqs/audio-convert
@@ -0,0 +1,2 @@
+func_init_prereqs=(ffmpeg)
+func_init_checks=()
diff --git a/.config/init/funcs/audio-concat b/.config/init/funcs/audio-concat
new file mode 100755
index 0000000..73b3ae7
--- /dev/null
+++ b/.config/init/funcs/audio-concat
@@ -0,0 +1,127 @@
+#!/usr/bin/env zsh
+# concatenate multiple audio files into one
+
+source "$HOME/.config/init/helpers" || exit 1
+
+local callstr=$0
+
+usage() {
+ echo "Usage: $callstr [OPTIONS...] <infile>..."
+ echo "Concatenate multiple audio files into one"
+ echo ""
+ echo " \e[1mdescription opt longform arg default\e[0m"
+ echo " specify destination file -o --outfile <file> out.ogg"
+ echo " specify output bitrate -b --bitrate <int>k (opus:35k, vorbis:50k, mp3:65k, flac:N/A)"
+ echo " workaround for many inputs -m --many"
+ echo " print this help -h --help"
+ exit 0
+}
+
+trap_abort() {
+ echo ""
+ abort "process interrupted"
+}
+
+trap 'trap_abort' SIGABRT SIGHUP SIGINT SIGQUIT SIGTERM
+
+local dest='out.opus'
+
+local destpat='^.*\.(opus|mp3|ogg|flac)$'
+local bitratepat='^[1-9][0-9]*k$'
+
+local filterstr
+local codecstr
+local bitratestr
+local many
+
+local parseerr=$(2>&1 zparseopts -D -E -M -A args \
+ o: -outfile:=o \
+ b: -bitrate:=b \
+ m -many=m \
+ h -help=h | cut -d ' ' -f 2-)
+
+[[ -z $parseerr ]] || abort $parseerr
+
+zparseopts -D -E -M -A args \
+ o: -outfile:=o \
+ b: -bitrate:=b \
+ m -many=m \
+ h -help=h
+
+local optarg
+for opt in ${(@k)args}; do
+ unset optarg
+ [[ -z $args[$opt] ]] || optarg=$args[$opt]
+ case $opt in
+ -o) [[ $optarg =~ $destpat ]] || \
+ abort "destination file must be of type opus, mp3, or ogg"
+ dest=$optarg
+ [[ ${optarg:e} == 'opus' ]] && codecstr='libopus' \
+ && [[ -z $bitratestr ]] && bitratestr='35k'
+ [[ ${optarg:e} == 'mp3' ]] && codecstr='libmp3lame' \
+ && [[ -z $bitratestr ]] && bitratestr='65k'
+ [[ ${optarg:e} == 'ogg' ]] && codecstr='libvorbis' \
+ && [[ -z $bitratestr ]] && bitratestr='50k'
+ [[ ${optarg:e} == 'flac' ]] && codecstr='flac' \
+ && [[ -z $bitratestr ]] && bitratestr=''
+ ;;
+ -b) [[ $optarg =~ $bitratepat ]] || \
+ abort "bitrate must positive integer + k, for kbps"
+ bitratestr=$optarg
+ ;;
+ -m) many=true ;;
+ -h) usage ;;
+ esac
+done
+
+[[ -z $codecstr ]] && codecstr='libopus'
+[[ -z $bitratestr ]] && bitratestr='35k'
+
+[[ $codecstr == "flac" ]] && bitratestr=''
+
+[[ ${#@} -eq 0 ]] && abort "no input files specified"
+
+if [[ -e $dest ]]; then
+ local delprompt
+ printf "destination file \`$dest\` exists\ndelete it? [y/N]: "
+ read -q delprompt
+ echo ""
+ [[ $delprompt = "y" ]] || return 0
+ 2>/dev/null rm $dest || abort "could not delete file \`$dest\`"
+fi
+
+local pid
+
+if [[ -z $many ]]; then
+ local inputlist=()
+ local i=0
+ for f in $@; do
+ inputlist+=(-i $f)
+ filterstr="${filterstr}[${i}:a:0] "
+ i=$((i+1))
+ done
+
+ filterstr="${filterstr}concat=n=${i}:v=0:a=1 [outa]"
+
+ (
+ ffmpeg -loglevel -8 $inputlist \
+ -filter_complex $filterstr -map '[outa]' \
+ -c:a $codecstr ${bitratestr/*k/-b:a} $bitratestr \
+ -map_metadata -1 $dest
+ ) &
+ pid=$!
+else
+ (
+ for f in $@; do
+ ffmpeg -loglevel -8 -i $f -f s16le -ar 44.1k -ac 2 pipe:
+ done | ffmpeg -loglevel -8 -f s16le -ar 44.1k -ac 2 -i pipe: \
+ -c:a $codecstr ${bitratestr/*k/-b:a} $bitratestr \
+ -map_metadata -1 $dest
+ ) &
+ pid=$!
+fi
+
+local plural
+[[ $#@ -ne 1 ]] && plural='s'
+
+wait-anim $pid "concatenating $#@ file$plural to \`$dest\`"
diff --git a/.config/init/funcs/audio-convert b/.config/init/funcs/audio-convert
new file mode 100755
index 0000000..4923baa
--- /dev/null
+++ b/.config/init/funcs/audio-convert
@@ -0,0 +1,233 @@
+#!/usr/bin/env zsh
+# concatenate multiple audio files into one
+
+source "$HOME/.config/init/helpers" || exit 1
+
+local callstr=$0
+
+usage() {
+ echo "Usage: $callstr [OPTIONS...] <infile>..."
+ echo "Convert multiple audio files to a new format"
+ echo ""
+ echo " \e[1mdescription opt longform arg default\e[0m"
+ echo " output codec -c --codec <codec> opus"
+ echo " output bitrate -b --bitrate <int>k (opus:35k, vorbis:50k, mp3:65k, flac:N/A)"
+ echo " output quality -q --quality <int> N/A"
+ echo " output directory -d --dest <dir> ."
+ echo " copy metadata -m --metadata <bool> false"
+ echo " background job count -j --jobs <int> 4"
+ echo " print this help -h --help"
+ exit 0
+}
+
+local fifoname
+local fifomade=0
+local pid
+
+trap_abort() {
+ echo ""
+ print-error "process interrupted"
+ # race condition-y, but eh
+ repeat 5; do
+ [[ -z $pid ]] && sleep 0.1 || break
+ done
+ [[ -z $pid ]] || kill -s SIGKILL $pid
+ [[ -p $fifoname ]] && [[ $fifomade -eq 1 ]] && 2>/dev/null rm $fifoname
+ exit 1
+}
+
+trap 'trap_abort' SIGABRT SIGHUP SIGINT SIGQUIT SIGTERM
+
+local codecpat='^(opus|mp3|vorbis|flac)$'
+local bitratepat='^[1-9][0-9]*k$'
+local metadatapat='^(true|false)$'
+local jobcountpat='^[1-9][0-9]*$'
+
+local qpatvorbis='^([0-9]|10)$'
+local qpatmp3='^[0-9]$'
+
+local codecstr
+local codecprintstr
+local extstr
+local bitratestr
+local bitrateset
+local metastr
+local dirstr
+local qstr
+
+local jobcount
+
+local parseerr=$(2>&1 zparseopts -D -E -M -A args \
+ c: -codec:=c \
+ b: -bitrate:=b \
+ q: -quality:=q \
+ d: -dest:=d -destination:=d \
+ j: -jobs:=j \
+ m:: -metadata::=m \
+ h -help=h | cut -d ' ' -f 2-)
+
+[[ -z $parseerr ]] || abort $parseerr
+
+zparseopts -D -E -M -A args \
+ c: -codec:=c \
+ b: -bitrate:=b \
+ q: -quality:=q \
+ d: -dest:=d -destination:=d \
+ j: -jobs:=j \
+ m:: -metadata::=m \
+ h -help=h
+
+local optarg
+local opt
+for opt in ${(@k)args}; do
+ unset optarg
+ [[ -z $args[$opt] ]] || optarg=$args[$opt]
+ case $opt in
+ -c) [[ $optarg =~ $codecpat ]] || \
+ abort "codec must be one of \`opus\`, \`mp3\`, \`flac\`, or \`vorbis\`"
+ [[ ${optarg} == 'opus' ]] \
+ && codecprintstr=${optarg} \
+ && codecstr='libopus' && extstr='opus' \
+ && [[ -z $bitratestr ]] && bitratestr='35k'
+ [[ ${optarg} == 'mp3' ]] \
+ && codecprintstr=${optarg} \
+ && codecstr='libmp3lame' && extstr='mp3' \
+ && [[ -z $bitratestr ]] && bitratestr='65k'
+ [[ ${optarg} == 'vorbis' ]] \
+ && codecprintstr=${optarg} \
+ && codecstr='libvorbis' && extstr='ogg' \
+ && [[ -z $bitratestr ]] && bitratestr='50k'
+ [[ ${optarg} == 'flac' ]] \
+ && codecprintstr=${optarg} \
+ && codecstr='flac' && extstr='flac' \
+ && [[ -z $bitratestr ]] && bitratestr=''
+ ;;
+ -b) [[ $optarg =~ $bitratepat ]] || \
+ abort "bitrate must positive integer + k, for kbps"
+ bitratestr=$optarg
+ bitrateset=1
+ ;;
+ -q) qstr=$optarg ;;
+ -d) dirstr=$optarg ;;
+ -j) [[ $optarg =~ $jobcountpat ]] || \
+ abort "job count must be a non-negative integer"
+ jobcount=$optarg
+ ;;
+ -m) if [[ $optarg ]]; then
+ [[ $optarg =~ $metadatapat ]] || \
+ abort "metadata must be either \`true\` or \`false\`"
+
+ [[ $optarg == "false" ]] && metastr="" \
+ || metastr=("-map_metadata" "-1")
+ else
+ metastr=("-map_metadata" "-1")
+ fi
+ ;;
+ -h) usage ;;
+ esac
+done
+
+[[ -z $codecstr ]] && codecstr='libopus'
+[[ -z $bitratestr ]] && bitratestr='35k'
+[[ -z $codecprintstr ]] && codecprintstr='opus'
+[[ -z $extstr ]] && extstr='opus'
+[[ -z $jobcount ]] && jobcount=4
+[[ -z $dirstr ]] && dirstr='.'
+[[ -z $metastr ]] && metastr=("-map_metadata" "-1")
+
+if [[ ! -z $qstr ]]; then
+ [[ -z $bitratset ]] || abort "-b and -q are not compatible"
+ [[ $codecstr == "libopus" ]] && abort "-q cannot be used with opus"
+ [[ $codecstr == "libflac" ]] && abort "-q cannot be used with flac"
+ [[ $codecstr == "libvorbis" ]] && [[ ! $qstr =~ $qpatvorbis ]] \
+ && abort "for vorbis, -q must be in the range [0-10]"
+ [[ $codecstr == "libmp3lame" ]] && [[ ! $qstr =~ $qpatmp3 ]] \
+ && abort "for mp3, -q must be in the range [0-9]"
+else
+fi
+
+[[ $codecstr == "flac" ]] && bitratestr=''
+
+[[ $#@ -eq 0 ]] && abort "no input files specified"
+
+local f
+for f in $@; do
+ [[ -f $f ]] || abort "could not read file \`$f\`"
+done
+
+2>/dev/null mkdir -p $dirstr || abort "could not write to directory \`$dirstr\`"
+
+repeat 5; do
+ fifoname="$dirstr/audio-convert-tmp-$RANDOM"
+ [[ -e $fifoname ]] && continue
+ 2>/dev/null mkfifo $fifoname || return 1
+ fifomade=1
+ break
+done
+
+[[ $fifomade -eq 1 ]] || abort "could not make temporary fifo"
+
+local delprompt
+for f in $@; do
+ local dest="$dirstr/${f:t:r}.$extstr"
+
+ if [[ -e $dest ]]; then
+ printf "destination file \`$dest\` exists\ndelete it? [y/N]: "
+ read -q delprompt
+ print ""
+ [[ $delprompt = "y" ]] || return 0
+ 2>/dev/null rm $dest || abort "could not delete file \`$dest\`"
+ fi
+done
+
+local totalstr="${#@} file"
+[[ $#@ -ne 1 ]] && totalstr="${totalstr}s"
+local jobstr=$jobcount
+[[ $#@ -lt $jobcount ]] && jobstr=$#@
+[[ $jobstr -gt 1 ]] && jobstr="${jobstr} jobs" || jobstr="${jobstr} job"
+
+(
+{
+ local joblist=()
+ while read -d $'\0' f; do
+ local dest="$dirstr/${f:t:r}.$extstr"
+ (
+ ffmpeg -loglevel -8 -i $f \
+ -vn -sn -c:a $codecstr \
+ ${bitratestr/*k/-b:a} $bitratestr \
+ ${qstr/[0-9]*/-q:a} $qstr \
+ $metastr \
+ $dest
+ echo "done"
+ ) &
+ joblist+=$!
+ done
+
+ local j
+ for j in $joblist; do
+ 2>/dev/null wait $j
+ done
+} < $fifoname | {
+ repeat $jobcount; do
+ if [[ $#@ -gt 0 ]]; then
+ printf "%s\0" $@[1]
+ shift
+ fi
+ done
+
+ while read line; do
+ if [[ $#@ -gt 0 ]]; then
+ printf "%s\0" $@[1]
+ shift
+ else
+ break
+ fi
+ done
+} > $fifoname
+)&
+
+pid=$!
+
+wait-anim $pid "using $jobstr to convert $totalstr to $codecprintstr"
+
+2>/dev/null rm $fifoname
diff --git a/.config/init/funcs/mpd-cover-convert b/.config/init/funcs/mpd-cover-convert
index e8359b7..d9d7a2c 100755
--- a/.config/init/funcs/mpd-cover-convert
+++ b/.config/init/funcs/mpd-cover-convert
@@ -3,10 +3,14 @@
# leaks memory for some reason, so don't run on a clean library
# or it'll crash everything
-local d
+source "$HOME/.config/init/helpers" || exit 1
+
+(local file
find ~/music -type f -regextype posix-extended -regex ".*cover\.(png|jpg)"\
| while read file; do
if [[ ! -f "${file:h}/cover-small.png" ]]; then
convert "$file" -resize 250x "${file:h}/cover-small.png"
fi
-done
+done) &
+
+wait-anim $! "converting"
diff --git a/.config/init/funcs/scap b/.config/init/funcs/scap
index 85a083f..f87eb93 100755
--- a/.config/init/funcs/scap
+++ b/.config/init/funcs/scap
@@ -7,8 +7,8 @@ xset q
archey3
sleep .2
-if [[ -f '/tmp/cap.mp4' ]]; then
- rm '/tmp/cap.mp4'
+if [[ -e '/tmp/cap.mp4' ]]; then
+ rm '/tmp/cap.mp4' || return 1
fi
echo 'recording...'
diff --git a/.config/init/helpers b/.config/init/helpers
new file mode 100644
index 0000000..69963cb
--- /dev/null
+++ b/.config/init/helpers
@@ -0,0 +1,77 @@
+print-error() {
+ 1>&2 echo "\e[1;31merror:\e[0m $1"
+}
+
+abort() {
+ print-error $1
+ exit 1
+}
+
+wait-anim() {
+ [[ $#@ -ne 0 ]] && [[ $#@ -lt 4 ]] || return 1
+
+ local pidpat='^[1-9][0-9]*$'
+ local colourpat='^(black|light_black|red|light_red|green|light_green|yellow|light_yellow|blue|light_blue|magenta|light_magenta|cyan|light_cyan|white|light_white)$'
+
+ [[ $1 =~ $pidpat ]] || return 1
+ if [[ ! -z $3 ]]; then
+ [[ $3 =~ $colourpat ]] || return 1
+ fi
+
+ local message
+ local colour
+
+ [[ -z $2 ]] && message='waiting...' || message=$2
+ [[ -z $3 ]] && colour='yellow' || colour=$3
+
+ case $colour in
+ 'black') colour='\e[30m' ;;
+ 'light_black') colour='\e[1;30m' ;;
+ 'red') colour='\e[31m' ;;
+ 'light_red') colour='\e[1;31m' ;;
+ 'green') colour='\e[32m' ;;
+ 'light_green') colour='\e[1;32m' ;;
+ 'yellow') colour='\e[33m' ;;
+ 'light_yellow') colour='\e[1;33m' ;;
+ 'blue') colour='\e[34m' ;;
+ 'light_blue') colour='\e[1;34m' ;;
+ 'magenta') colour='\e[35m' ;;
+ 'light_magenta') colour='\e[1;35m' ;;
+ 'cyan') colour='\e[36m' ;;
+ 'light_cyan') colour='\e[1;36m' ;;
+ 'white') colour='\e[37m' ;;
+ 'light_white') colour='\e[1;37m' ;;
+ esac
+
+ local curframe
+ local frames
+
+ case $(($RANDOM % 7)) in
+ 0) frames=('▁' '▂' '▃' '▄' '▅' '▆' '▇' '█' '▇' '▆' '▅' '▄' '▃' '▂') ;;
+ 1) frames=(' ' '▖' '▚' '▝' ' ' '▘' '▞' '▗') ;;
+ 2) frames=('╀' '╂' '╁' '┼' '┽' '┿' '┾' '┼' '╁' '╂' '╀' '┼' '┾' '┿' '┽' '┼') ;;
+ 3) frames=('─' '└' '│' '┌' '─' '┐' '│' '┘') ;;
+ 4) frames=('.' '。' '×' ':' '*' '.' '°' '♪' '×' '♫' '°' '♡') ;;
+ 5) frames=(' ' ' ' '░' '░' '▒' '▒' '▓' '▓' '█' '█' '▓' '▓' '▒' '▒' '░' '░') ;;
+ 6) frames=('O' 'o' '.' 'o') ;;
+ esac
+
+ (while 2>/dev/null kill -0 $1; do
+ if [[ -z $curframe ]]; then
+ curframe=0
+ printf "\e[s"
+ else
+ printf "\e[u\e[K"
+ fi
+ printf "|\e[1;32m${frames[$(($curframe + 1))]}\e[0m| $colour$message\e[0m"
+ curframe=$(( ($curframe + 1) % $#frames ))
+ sleep .2
+ done) &
+
+ # trap "echo -n '\e[G\e[J\e[s'" SIGWINCH
+
+ wait $1
+ local r=$?
+ printf "\e[u\e[K"
+ return $r
+}
diff --git a/.config/ranger/rifle.conf b/.config/ranger/rifle.conf
index 9f1f981..7000ba6 100644
--- a/.config/ranger/rifle.conf
+++ b/.config/ranger/rifle.conf
@@ -47,7 +47,6 @@
# only running the current file even if you have marked multiple files.
# music conversion and import
-directory, has flac2all = flac2all vorbis "$1" -v quality=10 -o "$1/converted"
directory, has beet = beet imp -t "$1"
# view man pages
@@ -80,6 +79,10 @@ ext php = php -- "$1"
mime ^audio, terminal, has mpv = mpv --no-video -- "$@"
mime ^audio, !terminal, has mpv, X, flag f = mpv --force-window=yes -- "$@"
+mime ^audio, terminal, has audio-convert = audio-convert -d converted -c vorbis -q 10 "$@"
+mime ^audio, terminal, has audio-convert = audio-convert -d converted -c opus "$@"
+mime ^audio, terminal, has audio-concat = audio-concat "$@"
+
mime ^video, has mpv, X, flag f = mpv -- "$@"
mime ^video, has mpv, terminal, !X = mpv --vo=tct -- "$@"