forked from HPR/hpr-tools
		
	
		
			
	
	
		
			214 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			214 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | #!/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 |