ambevar-dotfiles/.scripts/tc-audio-batch

126 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
_printhelp ()
{
cat<<EOF
Usage: ${1##*/} [-p PROC] ROOT [OPTIONS]
This will batch-process all audio files found in ROOT folder and subfolders with
the tc-audio-transcode script.
All OPTIONS are passed to tc-audio-transcode. For more details see
tc-audio-transcode -h
This script has the ability to run multiple processes. The number of processes
defaults to the number of online cores if 'lscpu' is found, or to 1
otherwise. The number of parallel processes is bounded by the number of input
files. Outputting from several processes at the same time to the standard output
is not convenient, therefore when more than 1 process are started, the output is
disabled (except for errors).
If you still want the output, you need to restrict the number of processes to
1. For instance to preview changes in current folder you would write:
${1##*/} -p1 . -p
Options:
-p PROC: run PROC processes in parallel.
EOF
}
if command -v lscpu >/dev/null; then
## lscpu is a Linux util also available on *BSD.
CPUNO=$(lscpu | awk '/^CPU\(s\)/ {print $2;exit}')
else
CPUNO=1
fi
while getopts ":p:h" opt; do
case $opt in
h)
_printhelp "$0"
exit 1 ;;
p)
CPUNO=$OPTARG ;;
?)
_printhelp "$0"
exit 1 ;;
:)
_printhelp "$0"
exit 1 ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
_printhelp "$0"
exit 1
fi
ROOT="$1"
shift
if ! command -v ffmpeg >/dev/null; then
echo "ffmpeg required."
exit
fi
if [ ! -f "${0%/*}/titlecase.awk" ]; then
echo "AWK titlecase script required."
exit
fi
if [ ! -f "${0%/*}/tc-audio-transcode" ]; then
echo "tc-audio-transcode script required."
exit
fi
INPUT="$(find "." \( \
-iname '*.aac' -o \
-iname '*.ape' -o \
-iname '*.flac' -o \
-iname '*.ogg' -o \
-iname '*.mp3' -o \
-iname '*.mp4' -o \
-iname '*.mpc' -o \
-iname '*.wav' -o \
-iname '*.wv' \) | sort -n)"
_worker()
{
CORE=$1
shift
## WARNING: ffmpeg continues to read stdin once it has started, so it should
## not be called from within a while<<EOF loop without redirecting stdin.
while IFS= read -r file; do
if [ -n "$file" ]; then
echo "$(tput setf 2)$(tput bold)==>$(tput sgr0) $file"
[ $CPUNO -eq 1 ] && "${0%/*}"/tc-audio-transcode "$@" "$file" || \
tc-audio-transcode -q "$@" "$file" >/dev/null
fi
done<<EOF
$(echo "$INPUT" | sed -n "$CORE~${CPUNO}p")
EOF
echo "$(tput setf 5)$(tput bold)::$(tput sgr0) Thread $CORE/$CPUNO terminated."
}
FILENO=$(echo "$INPUT" | wc -l)
if [ $CPUNO -gt $FILENO ]; then
CPUNO=$FILENO
fi
for i in $(seq 2 $CPUNO); do
_worker $i "$@" &
done
## We run one worker in the current process so that this script will hopefully
## terminate when the last job finishes.
_worker 1 "$@"