diff options
-rwxr-xr-x | .config/init/funcs/audio-convert | 74 | ||||
-rw-r--r-- | .config/init/helpers | 115 |
2 files changed, 139 insertions, 50 deletions
diff --git a/.config/init/funcs/audio-convert b/.config/init/funcs/audio-convert index 4923baa..24c5d62 100755 --- a/.config/init/funcs/audio-convert +++ b/.config/init/funcs/audio-convert @@ -20,8 +20,6 @@ usage() { exit 0 } -local fifoname -local fifomade=0 local pid trap_abort() { @@ -32,7 +30,6 @@ trap_abort() { [[ -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 } @@ -150,6 +147,14 @@ fi [[ $#@ -eq 0 ]] && abort "no input files specified" +local roots=(${@:t:r}) +local uniqroots=(${(u)roots}) + +[[ $#roots == $#uniqroots ]] \ + || abort "input contains files which share a root name (i.e. when extension is stripped)" + +local filecount=$#@ + local f for f in $@; do [[ -f $f ]] || abort "could not read file \`$f\`" @@ -157,17 +162,6 @@ 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" @@ -186,48 +180,50 @@ local jobstr=$jobcount [[ $#@ -lt $jobcount ]] && jobstr=$#@ [[ $jobstr -gt 1 ]] && jobstr="${jobstr} jobs" || jobstr="${jobstr} job" -( -{ +coproc { local joblist=() - while read -d $'\0' f; do + while read -d $'\0' c; do + [[ $c == "done" ]] && break + local f=${c:s/file:/} local dest="$dirstr/${f:t:r}.$extstr" ( - ffmpeg -loglevel -8 -i $f \ + 1>/dev/null 2>&1 </dev/null 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" + echo "next" ) & 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 -)& + echo "done" +} pid=$! -wait-anim $pid "using $jobstr to convert $totalstr to $codecprintstr" +repeat $jobcount; do + if [[ $#@ -gt 0 ]]; then + 1>&p printf "%s\0" $@[1] + shift + fi +done + +while read -p line; do + [[ $line == "done" ]] && coproc exit && break + echo "$line" + if [[ $#@ -gt 0 ]]; then + 1>&p printf "%s\0" "file:${@[1]}" + shift + else + 1>&p printf "%s\0" "done" + fi +done | progress-bar $filecount "using $jobstr to convert $totalstr to $codecprintstr" -2>/dev/null rm $fifoname +2>/dev/null wait $pid diff --git a/.config/init/helpers b/.config/init/helpers index 69963cb..1f2ed89 100644 --- a/.config/init/helpers +++ b/.config/init/helpers @@ -1,12 +1,111 @@ +# $1 - message print-error() { 1>&2 echo "\e[1;31merror:\e[0m $1" } +# $1 - message abort() { print-error $1 exit 1 } +# $1 - count +# $2 - message (opt) +# $3 - colourpat (opt) +progress-bar() { + + zmodload zsh/datetime zsh/mathfunc || return 1 + + [[ $#@ -ne 0 ]] && [[ $#@ -lt 4 ]] || return 1 + + local countpat='^[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)$' + + local count + [[ $1 =~ $countpat ]] && count=$1 || 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 i=0 + local starttime=$EPOCHREALTIME + local lasttime=$starttime + local thistime=$starttime + local elapsed=0 + while true; do + + [[ $i -eq $count ]] && break + + local width=$COLUMNS + local statwidth=$(( ($#count * 2) + 20)) + local progwidth=$(($width - $statwidth - 3)) + [[ $progwidth -gt 30 || $progwidth -le 1 ]] && progwidth=30 + + if [[ $i -eq 0 || $elapsed -eq 0 ]]; then + eta='??:??:??' + else + local left=$(( ($count - $i) * ($elapsed / $i) - ($EPOCHREALTIME - $lasttime) )) + if [[ $left -ge 86400 ]]; then + eta=' days...' + elif [[ $left -le 0 ]]; then + eta='00:00:00' + else + eta=$(strftime '%H:%M:%S' ${$(( ceil($left + 802800) )):s/\./}) + fi + fi + + local fpart="" + local epart="" + local progress=$(($i * $progwidth / $count)) + repeat $progress fpart="$fpart#" + repeat $(($progwidth-$progress)) epart="$epart-" + + printf \ + "\e[G\e[K$colour%s...\e[0m\n[%${#count}s/$count] [eta: $eta] [$fpart$epart]\e[J" \ + $message \ + $i \ + + read -t 0.2 \ + && thistime=$EPOCHREALTIME \ + && elapsed=$(($elapsed + $thistime - $lasttime)) \ + && lasttime=$EPOCHREALTIME \ + && i=$(($i + 1)) + + printf "\e[F" + done + + [[ $i -eq $count ]] && echo "\e[G\e[32m$message... done!\e[0m\e[J" \ + || echo "\e[G\e[31m$message... failed!\e[0m\e[J" +} + +# $1 - pid +# $2 - message (opt) +# $3 - colourpat (opt) wait-anim() { [[ $#@ -ne 0 ]] && [[ $#@ -lt 4 ]] || return 1 @@ -21,7 +120,7 @@ wait-anim() { local message local colour - [[ -z $2 ]] && message='waiting...' || message=$2 + [[ -z $2 ]] && message='waiting' || message=$2 [[ -z $3 ]] && colour='yellow' || colour=$3 case $colour in @@ -57,21 +156,15 @@ wait-anim() { 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" + [[ -z $curframe ]] && curframe=0 + printf "\e[G\e[K|\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" + [[ $r ]] && printf "\e[G\e[K\e[31m$message... failed!\e[0m\n" \ + || printf "\e[G\e[K\e[32m$message... done!\e[0m\n" return $r } |