#!/bin/bash - #=============================================================================== # # FILE: transcode # # USAGE: ./transcode path_to_file # # DESCRIPTION: Given an audio file generated for archive.org transcode it to # other audio formats: wav, opus, flac, mp3, ogg, spx. Having # done so propagate the tags from the first file to the others. # # OPTIONS: --- # REQUIREMENTS: --- # BUGS: --- # NOTES: --- # AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com # VERSION: 0.0.2 # CREATED: 2018-01-05 12:52:49 # REVISION: 2021-04-23 20:27:35 # #=============================================================================== set -o nounset # Treat unset variables as an error SCRIPT=${0##*/} # DIR=${0%/*} VERSION="0.0.2" STDOUT="/dev/fd/2" #=== FUNCTION ================================================================ # NAME: _usage # DESCRIPTION: Reports usage; always exits the script after doing so # PARAMETERS: 1 - the integer to pass to the 'exit' command # RETURNS: Nothing #=============================================================================== _usage () { local -i result=${1:-0} cat >$STDOUT <<-endusage ${SCRIPT} - version: ${VERSION} Usage: ./${SCRIPT} [-h] [-v] path_to_file Performs a "transcode" action on the given file. This means a variety of audio types are generated from the 'wav' format. The formats required are 'wav' 'opus' 'flac' 'mp3' 'ogg' 'spx'. If the file presented is not 'wav' format then this format is generated from the file using ffmpeg. Options: -h Print this help -v Run in verbose mode where more information is reported Arguments: path_to_file The primary file to be processed. The replica files generated from it are written to the same path. The file is expected to be an HPR audio file with a name such as 'hpr1234.mp3'. endusage exit "$result" } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Options # while getopts :hv opt do case "${opt}" in h) _usage 1;; v) VERBOSE=1;; *) _usage 1;; esac done shift $((OPTIND - 1)) VERBOSE=${VERBOSE:-0} # # Check for the presence of the required tools # for f in ffmpeg ffprobe opusenc sox speexenc transfer_tags; do TOOL=$(command -v $f) if [[ -z $TOOL ]]; then echo "$SCRIPT: Unable to find required audio tool '$f'; aborted" exit 1 fi done # # We need an audio file argument # if [[ $# -ne 1 ]]; then _usage 1 fi PRIMARY=$1 WORKDIR=${PRIMARY%/*} FILE=${PRIMARY##*/} # echo "PRIMARY=$PRIMARY" # echo "WORKDIR=$WORKDIR" # echo "FILE=$FILE" declare -a audiotypes mapfile -t audiotypes < <(printf '%s\n' wav opus flac mp3 ogg spx) # # We expect an HPR-format filename and one of a list of audio formats. # TODO: review the use of spx! # RE="${audiotypes[*]/%/|}" RE="${RE// /}" RE="${RE:0: -1}" RE="^hpr([0-9]{1,4})\.($RE)$" if [[ $FILE =~ $RE ]]; then ep_num=${BASH_REMATCH[1]} ext=${BASH_REMATCH[2]} else echo "$SCRIPT: Expecting an HPR audio file, got $FILE" exit 1 fi # # Check the primary file exists # [ -e "$PRIMARY" ] || { echo "$SCRIPT: Unable to find the file: $PRIMARY"; exit 1; } # # Is the primary file a wav file? If not, convert it # TODO: Can this be one with spx? # CHANNELS=1 WAV="$WORKDIR/hpr${ep_num}.wav" if [[ ! -e $WAV ]]; then if [[ ! "$ext" == 'wav' ]]; then [[ $VERBOSE -eq 1 ]] && echo "Making a wav file from $ext" ffmpeg -i "${PRIMARY}" -ar 44100 -ac $CHANNELS "$WAV" > /dev/null 2>&1 fi fi TEMP_DIR='/tmp' # # Make variables containing the audio variants # [[ $VERBOSE -eq 1 ]] && echo "Generating replica files..." for fmt in "${audiotypes[@]}"; do target="$WORKDIR/hpr${ep_num}.${fmt}" case $fmt in wav) [[ $VERBOSE -eq 1 ]] && echo "** Nothing to do for $fmt" continue ;; opus) if [[ ! -e "$target" ]]; then if [[ $VERBOSE -eq 1 ]]; then echo "Make format $fmt" opusenc "$WAV" "$target" else opusenc "$WAV" "$target" > /dev/null 2>&1 fi else [[ $VERBOSE -eq 1 ]] && echo "** $target already exists" fi continue ;; flac|mp3|ogg) if [[ ! -e "$target" ]]; then if [[ $VERBOSE -eq 1 ]]; then echo "Make format $fmt" sox --temp "${TEMP_DIR}" -S "$WAV" "$target" else sox --temp "${TEMP_DIR}" -S "$WAV" "$target" > /dev/null 2>&1 fi else [[ $VERBOSE -eq 1 ]] && echo "** $target already exists" fi continue ;; spx) if [[ ! -e "$target" ]]; then if [[ $VERBOSE -eq 1 ]]; then echo "Make format $fmt" sox --temp "${TEMP_DIR}" -S "$WAV" -c 1 -r 16000 -t wav - |\ speexenc - "$target" else sox --temp "${TEMP_DIR}" -S "$WAV" -c 1 -r 16000 -t wav - |\ speexenc - "$target" > /dev/null 2>&1 fi else [[ $VERBOSE -eq 1 ]] && echo "** $target already exists" fi continue ;; esac done [[ $VERBOSE -eq 1 ]] && echo "transfer_tags $PRIMARY" if [[ $VERBOSE -eq 1 ]]; then transfer_tags -verbose "$PRIMARY" else transfer_tags -noverbose "$PRIMARY" fi exit # vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21