djcev.com

//

Git Repos / dotfiles / bin / audio_to_cbr320.sh

Last update to this file was on 2024-01-02 at 05:12.

Show audio_to_cbr320.sh

#!/bin/sh
#
# Copyright (c) 2015-2022, Cameron Vanderzanden. Available under the
# terms of the 2-clause BSD license. Please see the file "LICENSE" in
# the root dir of this repository for more information.
#
#- audio_to_cbr320.sh 2015/02/18 cev
#- audio_to_cbr320.sh 2021/07/23 cev
#- audio_to_cbr320.sh 2022/01/29 cev
## Usage: audio_to_cbr320.sh [-3fhV] <inputfile> <outputfile>
##
## Convert <inputfile> flac/mp3 into a 320kbps constant-bitrate mp3
## file at <outputfile>.
##
## -3 Operate on mp3 files
## -f Operate on flac files
## -h Show help
## -V Print version info
#
# TODO: This needs better error checking.

[ -x $HOME/.local/bin/cev_print.sh ] && . $HOME/.local/bin/cev_print.sh

self="${0##*'/'}"
mode=""
ext=""

if [ $self = "flac_to_cbr320.sh" -o $self = "flac_to_cbr320" ]; then
mode="flac"
ext="flac"
elif [ $self = "mp3_to_cbr320.sh" -o $self = "mp3_to_cbr320" ]; then
mode="mp3"
ext="mp3"
fi

die_inputoutputsame() {
print_self error
printf "%binput file %b%s %band output file %b%s %bare the same!%b\n" \
"$_norm" "$_error" "$1" "$_norm" "$_error" "$2" "$_norm" "$_clear" >&2
exit 1
}

die_invalidargumentcount() {
print_self error
printf "%b need an input file and output file! " "$_norm" >&2
printf "(Argument count != %b2%b).%b\n" "$_error" "$_norm" "$_clear" >&2
exit 1
}

die_noinput() {
print_self error
printf "%binput file %b%s %bdoes not exist!%b\n" \
"$_norm" "$_error" "$1" "$_norm" "$_clear" >&2
exit 1
}

die_nooutput() {
print_self error
printf "%boutput file not specified!%b\n" "$_norm" "$_clear" >&2
exit 1
}

die_unknownfiletype() {
print_unknownfiletype "$*"
exit 1
}

is_flac() { test_mimetype.sh -t "audio/x-flac" "$@" ; }

is_mp3() {
if test_mimetype.sh -t "audio/mpeg" "$@"; then
return 0
else
# test file extension
tmpname="$(basename "$@" ".mp3")"
tmpname2="${@##$tmpname}"
if [ "$tmpname2" = ".mp3" ]; then
return 0
fi
fi
return 1
}

mp3_copytags() {
# copy tags using py-mutagen
# TODO: replicate the flac_copytags system below to re-generate the mp3
# tags, instead of copying (possibly corrupt) tags with mid3cp.
mid3cp --write-v1 "$1" "$2"
}

mp3_transcode() {
inpfile="${1}"
outfile="${2}"
wavfile="${outfile}.wav"

# decode; had to update this 2022/01/29 because mpv options changed.
mpv --msg-level=all=warn \
--no-audio-display \
--no-video \
--audio-samplerate=44100 \
--ao=pcm \
--ao-pcm-file="${wavfile}" \
"$inpfile"
# encode
lame --preset insane -S "$wavfile" "$outfile"
rm -v "$wavfile"
}

# There's a better way to do this.
flac_gettag() {
metaflac --no-utf8-convert --list "$1" | grep "$2" | cut -d'=' -f 2-
}

flac_copytags() {
title="$(flac_gettag "$1" "TITLE=")"
artist="$(flac_gettag "$1" "ARTIST=")"
album="$(flac_gettag "$1" "ALBUM=")"
year="$(flac_gettag "$1" "DATE=")"
comment="$(flac_gettag "$1" "COMMENT=")"
trackno="$(flac_gettag "$1" "TRACKNUMBER=")"
tracktotal="$(flac_gettag "$1" "TRACKTOTAL=")"
genre="$(flac_gettag "$1" "GENRE=")"
albumartist="$(flac_gettag "$1" "ALBUMARTIST=")"
if [ -n "$tracktotal" ];
then tracks="$trackno/$tracktotal"
else
tracks="$trackno"
fi
[ -n "$title" ] && mid3v2 -t "$title" "$2"
[ -n "$artist" ] && mid3v2 -a "$artist" "$2"
[ -n "$album" ] && mid3v2 -A "$album" "$2"
[ -n "$year" ] && mid3v2 -y "$year" "$2"
[ -n "$comment" ] && mid3v2 -c "$comment" "$2"
[ -n "$tracks" ] && mid3v2 -T "$tracks" "$2"
[ -n "$genre" ] && mid3v2 -g "$genre" "$2"
[ -n "$albumartist" ] && mid3v2 --TPE2 "$albumartist" "$2"
if [ -f "00 cover.jpg" ]; then
eyeD3 --quiet --add-image="00 cover.jpg:FRONT_COVER:" "$2"
elif [ -f "cover.jpg" ]; then
eyeD3 --quiet --add-image="cover.jpg:FRONT_COVER:" "$2"
fi
}

flac_transcode() {
inpfile="${1}"
outfile="${2}"
wavfile="${outfile}.wav"

# decode
flac -s -o "$wavfile" -d "$inpfile"
# encode
lame --preset insane -S "$wavfile" "$outfile"
rm -v "$wavfile"
}

while getopts "3fhV?" option; do
case $option in
3) mode="mp3" && ext="mp3" ;;
f) mode="flac" && ext="flac" ;;
h) print_help && exit ;;
V) print_version && exit ;;
"?") print_help && exit ;;
esac
shift $((OPTIND - 1))
done

# need exactly two arguments at this point
[ $# -ne 2 ] && die_invalidargumentcount
# no input file specified
[ -z "$1" -o ! -e "$1" ] && die_noinput "$1"
# no output file specified
if [ -z "$2" ] && die_nooutput
# input file and output file are the same
if [ "$1" = "$2" ] && die_inputoutputsame "$1" "$2"

if [ "$mode" ]; then
eval transcode=\${mode}_transcode
eval copytags=\${mode}_copytags
$transcode "$1" "$2"
$copytags "$1" "$2"
exit 0
fi

if is_flac "$1"; then
mode="flac" && ext="flac"
flac_transcode "$1" "$2"
flac_copytags "$1" "$2"
exit 0
elif is_mp3 "$1"; then
mode="mp3" && ext="mp3"
mp3_transcode "$1" "$2"
mp3_copytags "$1" "$2"
exit 0
else
shortname="$(basename "$1")"
die_unknownfiletype "$shortname"
fi

Return to the top of this page or return to the overview of this repo.

Log audio_to_cbr320.sh

Date Commit Message Author + -
2024-01-02 Change from FreeBSD to Linux, other minor changes cev +1 -1
2022-01-29 Adding first batch of audio file handling scripts. cev +197  

Return to the top of this page or return to the overview of this repo.