mirror of
https://github.com/natelandau/shell-scripting-templates.git
synced 2025-11-09 13:43:46 -05:00
bump version. support recursive directory conversions
This commit is contained in:
229
bin/convertMedia
229
bin/convertMedia
@@ -3,9 +3,9 @@
|
|||||||
# ##################################################
|
# ##################################################
|
||||||
# My Generic BASH script template
|
# My Generic BASH script template
|
||||||
#
|
#
|
||||||
version="1.1.1" # Sets version variable for this script
|
version="1.2.0" # Sets version variable for this script
|
||||||
#
|
#
|
||||||
scriptTemplateVersion="1.3.0" # Version of scriptTemplate.sh that this script is based on
|
scriptTemplateVersion="1.5.0" # Version of scriptTemplate.sh that this script is based on
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# HISTORY:
|
# HISTORY:
|
||||||
@@ -13,6 +13,7 @@ scriptTemplateVersion="1.3.0" # Version of scriptTemplate.sh that this script is
|
|||||||
# * 2015-03-31 - v1.0.0 - First creation
|
# * 2015-03-31 - v1.0.0 - First creation
|
||||||
# * 2015-04-07 - v1.1.0 - Added support for music files
|
# * 2015-04-07 - v1.1.0 - Added support for music files
|
||||||
# * 2015-05-26 - v1.1.1 - Fixed log level on downsize720
|
# * 2015-05-26 - v1.1.1 - Fixed log level on downsize720
|
||||||
|
# * 2015-08-30 - v1.2.0 - Support for recursive directory conversions
|
||||||
#
|
#
|
||||||
# ##################################################
|
# ##################################################
|
||||||
|
|
||||||
@@ -53,15 +54,16 @@ function trapCleanup() {
|
|||||||
# Flags which can be overridden by user input.
|
# Flags which can be overridden by user input.
|
||||||
# Default values are below
|
# Default values are below
|
||||||
# -----------------------------------
|
# -----------------------------------
|
||||||
quiet=0
|
quiet=false
|
||||||
printLog=0
|
printLog=false
|
||||||
verbose=false
|
verbose=false
|
||||||
force=0
|
recursive=false
|
||||||
strict=0
|
force=false
|
||||||
debug=0
|
strict=false
|
||||||
|
debug=false
|
||||||
safeRun=0
|
safeRun=0
|
||||||
downsize720=0
|
downsize720=0
|
||||||
deleteOriginal=0
|
deleteOriginal=false
|
||||||
XLD=0
|
XLD=0
|
||||||
args=()
|
args=()
|
||||||
|
|
||||||
@@ -90,9 +92,12 @@ logFile="$HOME/Library/Logs/${scriptBasename}.log"
|
|||||||
# Arrays containing package dependencies needed to execute this script.
|
# Arrays containing package dependencies needed to execute this script.
|
||||||
# The script will fail if dependencies are not installed. For Mac users,
|
# The script will fail if dependencies are not installed. For Mac users,
|
||||||
# most dependencies can be installed automatically using the package
|
# most dependencies can be installed automatically using the package
|
||||||
# manager 'Homebrew'.
|
# manager 'Homebrew'. Mac applications will be installed using
|
||||||
|
# Homebrew Casks. Ruby and gems via RVM.
|
||||||
# -----------------------------------
|
# -----------------------------------
|
||||||
homebrewDependencies=(ffmpeg jq rename)
|
homebrewDependencies=(ffmpeg jq rename)
|
||||||
|
caskDependencies=()
|
||||||
|
gemDependencies=()
|
||||||
|
|
||||||
function mainScript() {
|
function mainScript() {
|
||||||
############## Begin Script Here ###################
|
############## Begin Script Here ###################
|
||||||
@@ -157,80 +162,28 @@ function identifyUserFile() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recursiveSearch() {
|
||||||
|
|
||||||
|
# Add matching items to array
|
||||||
|
while read item; do
|
||||||
|
recursiveFiles+=("${item}")
|
||||||
|
done < <(find . -name "*.${MEDIATYPE}" -type f -maxdepth 4)
|
||||||
|
|
||||||
|
for i in "${recursiveFiles[@]}"; do
|
||||||
|
userFile="${i}"
|
||||||
|
verbose "found item: ${userFile}"
|
||||||
|
recursiveDirectory=$(dirname "${userFile}")
|
||||||
|
recursiveDirectory="${recursiveDirectory#*/}"
|
||||||
|
saveDir="${recursiveDirectory}/"
|
||||||
|
runScript
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
function userFormat() {
|
function userFormat() {
|
||||||
# Reads user input for format (-o, --output)
|
# Reads user input for format (-o, --output)
|
||||||
# Override defaults with CLI
|
# Override defaults with CLI
|
||||||
if [ -n "$userOutput" ]; then
|
if [ -n "$userOutput" ]; then
|
||||||
outputFormat="${userOutput,,}" && verbose "outputFormat=${outputFormat}"
|
outputFormat="${userOutput,,}" #&& verbose "outputFormat=${outputFormat}"
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function doConvert() {
|
|
||||||
|
|
||||||
# Set the output name, format, and directory
|
|
||||||
# ###############################################
|
|
||||||
|
|
||||||
if $verbose; then v="-v" ; fi
|
|
||||||
|
|
||||||
# Set output filename
|
|
||||||
output="$(basename "${f%.*}").$outputFormat" && verbose "output="${output}""
|
|
||||||
|
|
||||||
# Add users output save directory if used
|
|
||||||
if [[ -n "${outputDir}" ]]; then
|
|
||||||
output="${outputDir}${output}" && verbose "output=${outputDir}${output}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Confirm we're not overwriting an existing file
|
|
||||||
if [[ "${safeRun}" -ne "1" ]]; then
|
|
||||||
if [ -e "${output}" ]; then
|
|
||||||
# rename the new file to '.new'
|
|
||||||
output="$(basename "${f%.*}").new."${outputFormat}"" && verbose "Adding '.new' to the new file name"
|
|
||||||
if [[ -n "${outputDir}" ]]; then
|
|
||||||
output="${outputDir}${output}" && verbose "output=${outputDir}${output}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Respect the 'Quiet' flag
|
|
||||||
if [[ "${quiet}" == "1" ]]; then
|
|
||||||
ffquiet="-loglevel quiet"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# # Respect the 'logfile' flag
|
|
||||||
# if [[ "${printLog}" == "1" ]]; then
|
|
||||||
# ffmpegLog=">> ${logFile}"
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# Invoke the conversion
|
|
||||||
# ##################################
|
|
||||||
|
|
||||||
# Use XLD for audio file conversion if available
|
|
||||||
if [[ "$XLD" == "1" ]]; then
|
|
||||||
verbose "Running XLD commands for audio. No FFMPEG"
|
|
||||||
# Respect --safe flag.
|
|
||||||
if [[ "${safeRun}" == "1" ]]; then
|
|
||||||
notice "xld -o "${output}" ${audioConvertCommand} "${f}""
|
|
||||||
else
|
|
||||||
verbose "xld -o "${output}" ${audioConvertCommand} "${f}""
|
|
||||||
xld -o "${output}" ${audioConvertCommand} "${f}"
|
|
||||||
fi
|
|
||||||
else # Use ffmpeg when XLD is set to 0
|
|
||||||
# Respect --safe flag.
|
|
||||||
if [[ "${safeRun}" == "1" ]]; then
|
|
||||||
notice "ffmpeg -i "${f}" ${videoResize} ${videoCommand} ${videoAudioCommand} ${audioConvertCommand} "${output}" ${ffquiet}"
|
|
||||||
else
|
|
||||||
verbose "ffmpeg -i "${f}" ${videoResize} ${videoCommand} ${videoAudioCommand} ${audioConvertCommand} "${output}" ${ffquiet}"
|
|
||||||
ffmpeg -i "${f}" ${videoResize} ${videoCommand} ${videoAudioCommand} ${audioConvertCommand} "${output}" ${ffquiet}
|
|
||||||
|
|
||||||
# delete original if requested and remove '.new' from new file
|
|
||||||
if [[ "${deleteOriginal}" == "1" ]]; then
|
|
||||||
rm -f $v "${f}"
|
|
||||||
#remove '.new' from filename
|
|
||||||
for file in *.new.*; do
|
|
||||||
rename $v 's/.new//g' "${file}"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +202,6 @@ convertVideo() {
|
|||||||
######################################################################
|
######################################################################
|
||||||
verbose "Reading JSON and writing to TMP"
|
verbose "Reading JSON and writing to TMP"
|
||||||
|
|
||||||
|
|
||||||
# Output a JSON file for each video asset being parsed.
|
# Output a JSON file for each video asset being parsed.
|
||||||
ffprobe -v quiet -print_format json -show_format -show_streams "${f}" >> "${informationFile}"
|
ffprobe -v quiet -print_format json -show_format -show_streams "${f}" >> "${informationFile}"
|
||||||
# uncomment the line below for debugging. It will write a json file for each file in the source directory
|
# uncomment the line below for debugging. It will write a json file for each file in the source directory
|
||||||
@@ -476,7 +428,6 @@ convertVideo() {
|
|||||||
done
|
done
|
||||||
breakLoop
|
breakLoop
|
||||||
done
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
convertMusic() {
|
convertMusic() {
|
||||||
@@ -610,15 +561,100 @@ convertMusic() {
|
|||||||
done
|
done
|
||||||
breakLoop
|
breakLoop
|
||||||
done
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run the functions
|
function doConvert() {
|
||||||
|
|
||||||
|
# Set the output name, format, and directory
|
||||||
|
# ###############################################
|
||||||
|
|
||||||
|
if $verbose; then v="-v" ; fi
|
||||||
|
|
||||||
|
# Set output filename
|
||||||
|
output="$(basename "${f%.*}").$outputFormat" && verbose "output="${output}""
|
||||||
|
|
||||||
|
# Add user's output save directory if used
|
||||||
|
if [[ -n "${outputDir}" ]]; then
|
||||||
|
verbose "outputDir=${outputDir}"
|
||||||
|
output="${outputDir}${output}" && verbose "output=${outputDir}${output}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Confirm we're not overwriting an existing file
|
||||||
|
if [[ "${safeRun}" -ne "1" ]]; then
|
||||||
|
if [ -e "${output}" ]; then
|
||||||
|
# rename the new file to '.new'
|
||||||
|
output="$(basename "${f%.*}").new."${outputFormat}"" && verbose "Adding '.new' to the new file name"
|
||||||
|
if [[ -n "${outputDir}" ]]; then
|
||||||
|
output="${outputDir}${output}" && verbose "output=${outputDir}${output}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Respect the 'Quiet' flag
|
||||||
|
if "${quiet}"; then
|
||||||
|
verbose "running in quiet mode"
|
||||||
|
ffquiet="-loglevel quiet"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Respect the 'logfile' flag
|
||||||
|
if ${printLog}; then
|
||||||
|
ffmpegLog=">> ${logFile}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Invoke the conversion
|
||||||
|
# ##################################
|
||||||
|
|
||||||
|
# Use XLD for audio file conversion if available
|
||||||
|
if [[ "$XLD" == "1" ]]; then
|
||||||
|
verbose "Running XLD commands for audio. No FFMPEG"
|
||||||
|
# Respect --safe flag.
|
||||||
|
if [[ "${safeRun}" == "1" ]]; then
|
||||||
|
notice "xld -o "${output}" ${audioConvertCommand} "${f}""
|
||||||
|
else
|
||||||
|
verbose "xld -o "${output}" ${audioConvertCommand} "${f}""
|
||||||
|
xld -o "${output}" ${audioConvertCommand} "${f}"
|
||||||
|
fi
|
||||||
|
else # Use ffmpeg when XLD is set to 0
|
||||||
|
# Respect --safe flag.
|
||||||
|
if [[ "${safeRun}" == "1" ]]; then
|
||||||
|
notice "ffmpeg -i "${f}" ${videoResize} ${videoCommand} ${videoAudioCommand} ${audioConvertCommand} "${output}" ${ffquiet}"
|
||||||
|
else
|
||||||
|
verbose "ffmpeg -i "${f}" ${videoResize} ${videoCommand} ${videoAudioCommand} ${audioConvertCommand} "${output}" ${ffquiet}"
|
||||||
|
ffmpeg -i "${f}" ${videoResize} ${videoCommand} ${videoAudioCommand} ${audioConvertCommand} "${output}" ${ffquiet}
|
||||||
|
|
||||||
|
# delete original if requested and remove '.new' from new file
|
||||||
|
if ${deleteOriginal}; then
|
||||||
|
rm -f $v "${f}"
|
||||||
|
#remove '.new' from filename
|
||||||
|
if [[ -n "${outputDir}" ]]; then
|
||||||
|
for file in "${outputDir}*.new.*"; do
|
||||||
|
rename $v 's/.new//g' "${file}"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
for file in *.new.*; do
|
||||||
|
rename $v 's/.new//g' "${file}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
runScript() {
|
||||||
|
# All functions within the script are here
|
||||||
identifyUserFile
|
identifyUserFile
|
||||||
userFormat
|
userFormat
|
||||||
outputDir
|
outputDir
|
||||||
convertVideo
|
convertVideo
|
||||||
convertMusic
|
convertMusic
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the functions
|
||||||
|
if ${recursive}; then
|
||||||
|
recursiveSearch # Run the recursive search function
|
||||||
|
else
|
||||||
|
runScript
|
||||||
|
fi
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
############### End Script Here ####################
|
############### End Script Here ####################
|
||||||
@@ -655,6 +691,7 @@ ${bold}General Options:${reset}
|
|||||||
${bold} --safe${reset} Runs the script without actually invoking FFMPEG. Will simply print
|
${bold} --safe${reset} Runs the script without actually invoking FFMPEG. Will simply print
|
||||||
the FFMPEG commands to the terminal
|
the FFMPEG commands to the terminal
|
||||||
${bold}--version${reset} Output version information and exit
|
${bold}--version${reset} Output version information and exit
|
||||||
|
${bold}--recursive${reset} Will search recursively through directories
|
||||||
|
|
||||||
${bold}File Options:${reset}
|
${bold}File Options:${reset}
|
||||||
${bold}-f, --file${reset} Specify a specific file to take actions on.
|
${bold}-f, --file${reset} Specify a specific file to take actions on.
|
||||||
@@ -697,6 +734,10 @@ Convert a Windows Media file (file.wmv) to h264 (mp4).
|
|||||||
|
|
||||||
$ convertMedia -o mp4 file.wmv
|
$ convertMedia -o mp4 file.wmv
|
||||||
|
|
||||||
|
Do a recursive search for all directories beneath the current one. In each
|
||||||
|
directory, search for .avi iles and convert them to .mp4
|
||||||
|
$ convertMedia --recursive -o mp4 -i avi
|
||||||
|
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,16 +792,17 @@ while [[ $1 = -?* ]]; do
|
|||||||
--height) shift; height="$1" ;;
|
--height) shift; height="$1" ;;
|
||||||
--width) shift; width="$1" ;;
|
--width) shift; width="$1" ;;
|
||||||
--downsize720) downsize720=1 ;;
|
--downsize720) downsize720=1 ;;
|
||||||
--delete) deleteOriginal=1 ;;
|
--recursive) recursive=true ;;
|
||||||
|
--delete) deleteOriginal=true ;;
|
||||||
--saveDir) shift; saveDir="$1" ;;
|
--saveDir) shift; saveDir="$1" ;;
|
||||||
--bitrate) shift; bitrate="$1" ;;
|
--bitrate) shift; bitrate="$1" ;;
|
||||||
-h|--help) usage >&2; safeExit ;;
|
-h|--help) usage >&2; safeExit ;;
|
||||||
--force) force=1 ;;
|
--force) force=true ;;
|
||||||
--version) echo "$(basename $0) $version"; safeExit ;;
|
--version) echo "$(basename $0) $version"; safeExit ;;
|
||||||
-v|--verbose) verbose=true ;;
|
-v|--verbose) verbose=true ;;
|
||||||
-l|--log) printLog=1 ;;
|
-l|--log) printLog=true ;;
|
||||||
-q|--quiet) quiet=1 ;;
|
-q|--quiet) quiet=true ;;
|
||||||
-d|--debug) debug=1;;
|
-d|--debug) debug=true;;
|
||||||
--endopts) shift; break ;;
|
--endopts) shift; break ;;
|
||||||
*) die "invalid option: '$1'." ;;
|
*) die "invalid option: '$1'." ;;
|
||||||
esac
|
esac
|
||||||
@@ -786,18 +828,17 @@ args+=("$@")
|
|||||||
# Trap bad exits with your cleanup function
|
# Trap bad exits with your cleanup function
|
||||||
trap trapCleanup EXIT INT TERM
|
trap trapCleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# Set IFS to preferred implementation
|
||||||
|
#IFS=$'\n\t'
|
||||||
|
|
||||||
# Exit on error. Append '||true' when you run the script if you expect an error.
|
# Exit on error. Append '||true' when you run the script if you expect an error.
|
||||||
set -o errexit
|
set -o errexit
|
||||||
|
|
||||||
# Run in debug mode, if set
|
# Run in debug mode, if set
|
||||||
if [ "${debug}" == "1" ]; then
|
if ${debug}; then set -x ; fi
|
||||||
set -x
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Exit on empty variable
|
# Exit on empty variable
|
||||||
if [ "${strict}" == "1" ]; then
|
if ${strict}; then set -o nounset ; fi
|
||||||
set -o nounset
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Bash will remember & return the highest exitcode in a chain of pipes.
|
# Bash will remember & return the highest exitcode in a chain of pipes.
|
||||||
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`, for example.
|
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`, for example.
|
||||||
|
|||||||
Reference in New Issue
Block a user