tc-audio-transcode: command-line parameters do not get titelcased anymore.

tc-audio-transcode: overwrite option.
tc-audio-transcode: capital-case option.
tc-audio-transcode: clearer variable name, colored warnings.
tc-audio-batch: color support + OGG support.
titlecase.awk: 'capital' option support for first letter only (most non-english
               titles are like this).
master
Pierre Neidhardt 2013-05-02 12:34:17 +02:00
parent b955b5c9d6
commit c4deb10885
3 changed files with 75 additions and 42 deletions

View File

@ -31,15 +31,16 @@ fi
IFS="
"
for i in $(find "." \( \
-iname '*.mp3' -o \
-iname '*.flac' -o \
-iname '*.wv' -o \
-iname '*.aac' -o \
-iname '*.wav' -o \
-iname '*.ape' -o \
-iname '*.mpc' \) ) ;do
-iname '*.flac' -o \
-iname '*.ogg' -o \
-iname '*.mp3' -o \
-iname '*.mpc' -o \
-iname '*.wav' -o \
-iname '*.wv' \) ) ;do
echo "$i"
echo "$(tput setf 2)$(tput bold)==>$(tput sgr0) $i"
"${0%/*}/tc-audio-transcode" "$@" "$i"
done
unset IFS

View File

@ -16,8 +16,8 @@ fi
################################################################################
## For the sake of simplicity we convert everything to OGG.
## You can easily set output folder to current folder with TC_AUDIO_DEST=".".
TC_AUDIO_DEST="/media/data1/Musics/"
## You can easily set output folder to current folder with OUTPUT_ROOT=".".
OUTPUT_ROOT="/media/data1/Musics/"
## OGG quality ranges from -1 to 10.
## -q-1 45 kbit/s
@ -33,8 +33,9 @@ TC_AUDIO_DEST="/media/data1/Musics/"
## -q9 320 kbit/s
## -q10 500 kbit/s
## Artists: we use same value for artist and album_artist.
## Genres: since this is not universal by nature, we do not put a genre in tags.
## Artists: we use same value for artist and album_artist.
## Genres: since this is not universal by nature, we do not put a genre in tags,
## except for special cases like Soundtrack.
## Composer: not universal neither, we prefer ARTIST over COMPOSER, so COMPOSER
## will be empty.
@ -57,6 +58,8 @@ _printhelp ()
Usage: ${1##*/} [OPTIONS] FILE
Options:
-c : capital case (only first letter in upper case)
-f : overwrite if file exists
-p : preview (do not change file)
-s : skip encoding
@ -82,7 +85,7 @@ You can use the following variables to refer to existing values:
\$TYER
Default output folder:
OUTPUT="\$TC_AUDIO_DEST/\$OUTPUT_ARTIST/\${OUTPUT_ALBUM:+\${OUTPUT_DATE:+\$OUTPUT_DATE - }\$OUTPUT_ALBUM/}"
OUTPUT_FOLDER="\$OUTPUT_ROOT/\$OUTPUT_ARTIST/\${OUTPUT_ALBUM:+\${OUTPUT_DATE:+\$OUTPUT_DATE - }\$OUTPUT_ALBUM/}"
Default output file:
OUTPUT_FILE="\$OUTPUT\$OUTPUT_ARTIST - \${OUTPUT_TRACK:+\$OUTPUT_TRACK - }\$OUTPUT_TITLE.\$OUTPUT_FORMAT"
@ -101,9 +104,10 @@ EOF
}
## OPTIONS
SKIP=0
CAPITAL=0
OVERWRITE=0
PREVIEW=0
SKIP=0
## TAGS
OUTPUT_ALBUM='$ALBUM'
@ -121,10 +125,10 @@ OUTPUT_FORMAT="ogg"
OGG_PARAM="-c:a libvorbis -b:a ${OUTPUT_BITRATE}k"
## These ones are not CLI-options either, but this could be easily changed.
OUTPUT='$TC_AUDIO_DEST/$OUTPUT_ARTIST/${OUTPUT_ALBUM:+${OUTPUT_DATE:+$OUTPUT_DATE - }$OUTPUT_ALBUM/}'
OUTPUT_FILE='$OUTPUT$OUTPUT_ARTIST - ${OUTPUT_PADDEDTRACK:+$OUTPUT_PADDEDTRACK - }$OUTPUT_TITLE'
OUTPUT_FOLDER='$OUTPUT_ROOT/$OUTPUT_ARTIST/${OUTPUT_ALBUM:+${OUTPUT_DATE:+$OUTPUT_DATE - }$OUTPUT_ALBUM/}'
OUTPUT_FILE='$OUTPUT_FOLDER$OUTPUT_ARTIST - ${OUTPUT_PADDEDTRACK:+$OUTPUT_PADDEDTRACK - }$OUTPUT_TITLE'
while getopts ":a:b:d:g:l:n:r:t:hps" opt; do
while getopts ":a:b:cd:fg:l:n:r:t:hps" opt; do
case $opt in
a) OUTPUT_ARTIST=$OPTARG ;;
@ -133,13 +137,20 @@ while getopts ":a:b:d:g:l:n:r:t:hps" opt; do
g) OUTPUT_GENRE=$OPTARG ;;
l) OUTPUT_ALBUM=$OPTARG ;;
n) OUTPUT_TRACK=$OPTARG ;;
r) TC_AUDIO_DEST=$OPTARG ;;
r) OUTPUT_ROOT=$OPTARG ;;
t) OUTPUT_TITLE=$OPTARG ;;
h)
_printhelp "$0"
exit 1
;;
c)
CAPITAL=1
;;
f)
OVERWRITE=1
;;
p)
PREVIEW=1
;;
@ -169,14 +180,14 @@ fi
##================================================================================
## Get metadata.
STREAM=$(ffmpeg -i "$1" 2>&1)
METADATA=$(echo "$STREAM" | sed -n '/Metadata/ ! d; /Metada/{b cont}; :cont ; {n;p;b cont}')
STREAM=$(echo "$STREAM" | grep "Stream")
if [ -z "$STREAM" ]; then
if [ -z "$(echo $STREAM | grep "Stream")" ]; then
echo "[$1] Non-audio file."
exit
fi
METADATA=$(echo "$STREAM" | sed -n '/Metadata/ ! d; /Metada/{b cont}; :cont ; {n;p;b cont}')
## Filename without extension nor path.
FILENAME="${1%.*}"
FILENAME="${FILENAME##*/}"
@ -186,8 +197,8 @@ SOURCEFOLDER="${SOURCEFOLDER%/*}"
## We get format from extension, because codec is not reliable either.
FORMAT="${1##*.}"
## CODEC is unused for now.
CODEC=$(echo "$STREAM" | sed -n '/Audio:/ {s/.*Audio: \([^,]*\),.*/\1/;p}')
BITRATE=$(echo "$METADATA" | sed -n '/Duration/ {s|.* \([[:digit:]]\+\) kb/s|\1|;p;q}')
CODEC=$(echo "$STREAM" | sed -n '/Stream.*Audio:/ {s/.*Audio: \([^,]*\),.*/\1/;p}')
BITRATE=$(echo "$STREAM" | sed -n '/Duration/ {s|.* \([[:digit:]]\+\) kb/s|\1|;p;q}')
if [ -z "$FORMAT" ]; then
echo "ERROR: non-audio file."
@ -223,20 +234,26 @@ TYER=$(_metadata_filter "TYER")
# / => -
_string_cleanser()
{
echo "$@" | awk -f "$TITLECASE_SCRIPT" \
echo "$@" | awk -v capital=$CAPITAL -f "$TITLECASE_SCRIPT" \
| sed -n -e "s//'/g ; s/ *: */ - /g ; s| */ *| - |g; p; q"
}
OUTPUT_TITLE=$(eval _string_cleanser $OUTPUT_TITLE)
if [ "$OUTPUT_TITLE" = '$TITLE' ]; then
OUTPUT_TITLE=$(eval _string_cleanser $OUTPUT_TITLE)
fi
OUTPUT_TITLE="${OUTPUT_TITLE:-Unknown Title}"
## We use album artist if artist is empty.
OUTPUT_ARTIST=$(eval _string_cleanser $OUTPUT_ARTIST)
[ -z "$OUTPUT_ARTIST" ] && [ -n "$ALBUM_ARTIST" ] && OUTPUT_ARTIST="$ALBUM_ARTIST"
if [ "$OUTPUT_ARTIST" = '$ARTIST' ]; then
## We use album artist if artist is empty.
OUTPUT_ARTIST=$(eval _string_cleanser $OUTPUT_ARTIST)
[ -z "$OUTPUT_ARTIST" ] && [ -n "$ALBUM_ARTIST" ] && OUTPUT_ARTIST="$ALBUM_ARTIST"
fi
OUTPUT_ARTIST="${OUTPUT_ARTIST:-Unknown Artist}"
OUTPUT_ALBUM=$(eval _string_cleanser $OUTPUT_ALBUM)
[ -z "$OUTPUT_ALBUM" ] && echo "${#OUTPUT_ALBUM}${OUTPUT_ALBUM}"
if [ "$OUTPUT_ALBUM" = '$ALBUM' ]; then
OUTPUT_ALBUM=$(eval _string_cleanser $OUTPUT_ALBUM)
fi
OUTPUT_ARTIST="${OUTPUT_ALBUM:-Unknown Album}"
## If OUTPUT_GENRE is set from command-line parameters, we clease the
## string. Otherwise we put GENRE in lower case and underscore to ease matching.
@ -289,16 +306,23 @@ if [ -n "$OUTPUT_PADDEDTRACK" ]; then
[ ${OUTPUT_PADDEDTRACK} -lt 10 ] && OUTPUT_PADDEDTRACK="0$OUTPUT_PADDEDTRACK"
fi
OUTPUT=$(eval echo $OUTPUT)
OUTPUT_FOLDER=$(eval echo $OUTPUT_FOLDER)
OUTPUT_FILE=$(eval echo $OUTPUT_FILE)
## IF file exist, we append a unique timestamp to the name.
[ -e "${OUTPUT_FILE}.$OUTPUT_FORMAT" ] && OUTPUT_FILE="$OUTPUT_FILE-$(date '+%F-%H%M%S')"
if [ -e "${OUTPUT_FILE}.$OUTPUT_FORMAT" ]; then
if [ $OVERWRITE -eq 0 ]; then
## If file exist, we append a unique timestamp to the name.
OUTPUT_FILE="$OUTPUT_FILE-$(date '+%F-%H%M%S')"
OUTPUT_MSG="$(tput setf 1)$(tput bold)(Warning: destination exists, appending timestamp.)$(tput sgr0)"
else
OUTPUT_MSG="$(tput setf 4)$(tput bold)(Warning: overwriting destination!)$(tput sgr0)"
fi
fi
##==============================================================================
## PREVIEW
echo "==> BEFORE"
echo ":: BEFORE"
echo "ALBUM [$ALBUM]"
echo "ALBUM_ARTIST [$ALBUM_ARTIST]"
echo "ARTIST [$ARTIST]"
@ -312,7 +336,7 @@ echo "TITLE [$TITLE]"
echo "TRACK [$TRACK]"
echo "TYER [$TYER]"
echo
echo "==> AFTER"
echo ":: AFTER"
echo "ALBUM [$OUTPUT_ALBUM]"
echo "ARTIST [$OUTPUT_ARTIST]"
echo "BITRATE [$OUTPUT_BITRATE]"
@ -322,18 +346,18 @@ echo "GENRE [$OUTPUT_GENRE]"
echo "TITLE [$OUTPUT_TITLE]"
echo "TRACK [$OUTPUT_TRACK]"
echo
echo "==> OUTPUT"
echo ":: OUTPUT $OUTPUT_MSG"
echo "[$OUTPUT_FILE.$OUTPUT_FORMAT]"
# echo "[$OGG_PARAM]"
echo
[ $PREVIEW -ne 0 ] && exit
[ $PREVIEW -eq 1 ] && exit
##==============================================================================
## RUN PROCESS
## Make sure directory exists.
mkdir -p "$OUTPUT"
mkdir -p "$OUTPUT_FOLDER"
if [ $? -ne 0 ]; then
echo "ERROR: could not create output folder [$OUTPUT]."
exit
@ -359,7 +383,7 @@ while read -r i; do
COVER_COUNTER=$(($COVER_COUNTER+1))
done
echo "==> COVER from $SOURCEFOLDER"
echo ":: COVER from $SOURCEFOLDER"
cp -nv "$i" "$OUTPUT_COVERFILE"
echo
done <<EOF
@ -384,6 +408,13 @@ ffmpeg -i "$1" -vn -sn $OGG_PARAM \
-metadata genre="$OUTPUT_GENRE" \
"$OUTPUT_FILE.$OUTPUT_FORMAT"
echo
if [ $OVERWRITE -eq 1 ]; then
mv -vf "$OUTPUT_FILE.$OUTPUT_FORMAT" "$1"
echo
fi
## Restore Zsh previous options. This will not turn off shwordsplit if it
## was on before calling the function.
[ "$STATUS" = "off" ] && set +o shwordsplit

View File

@ -50,7 +50,7 @@ BEGIN {
constants = constants "a an the and but for nor or so am is are against at between by from in into of on to upon "
## French
constants = constants "un une de du le la les et mais pour ni ou à a où contre entre chez dans sur "
constants = constants "un une de du le la les et mais pour ni ou à a où contre entre chez dans sur que qui "
## German
constants = constants "der die das den dem des ein eine einen eines einer von wo an am in für gegen bei aus mit nach seit zu durch ohne um "
@ -140,7 +140,7 @@ function titlecase(string) {
}
## RULE 3 -- Names like D'Arcy or O'Reilly
if ( hit == 0 && match(word, /^[DO]'[[:alpha:]]/) ) {
if ( hit == 0 && capital != 1 && match(word, /^[DO]'[[:alpha:]]/) ) {
word = substr(word,1,3) tolower(substr(word,4))
hit = 1
if (debug)
@ -160,8 +160,9 @@ function titlecase(string) {
## If one of the above rule is hit, we append the result to 'a',
## otherwise we capitalize it.
if (hit > 0) a = a word
else a = a toupper(head) tolower(tail)
if (hit > 0 ) a = a word
else if (capital == 1) a = a tolower(head) tolower(tail)
else a = a toupper(head) tolower(tail)
} while (pos > 0);