126 lines
2.9 KiB
Bash
Executable File
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
|
|
# Instead of sed, we could also use: awk "NR % $CPUNO == $CORE"
|
|
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 "$@"
|