Created
July 11, 2017 22:50
-
-
Save SludgeVohaul/654ad130ab730c85e90122368f992aa7 to your computer and use it in GitHub Desktop.
Find all MKV files below a source directory and create a 2s long snippet of each found file below a target directory while preserving the directory structure.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
set -u | |
# Cannot use /bin/sh due to process substitution in run(). | |
VERSION="20170711" | |
FIND=/usr/bin/find | |
MKDIR=/bin/mkdir | |
SORT=/usr/bin/sort | |
PWD=/bin/pwd | |
FILE=/usr/bin/file | |
# Install through homebrew with | |
# brew install ffmpeg --HEAD --without-libvo-aacenc --without-qtkit | |
FFMPEG=/usr/local/bin/ffmpeg | |
FFMPEG_LOGGING_ARGS=( "-loglevel" "warning" ) | |
#FFMPEG_LOGGING_ARGS=( "-loglevel" "info" ) | |
FFMPEG_BASE_ARGS=( "-hide_banner" ) | |
# ######### TODO these values are not really user configurable right now ##### | |
ABS_CURRENT_DIR=$("${PWD}") | |
# ############################################################################ | |
# No user configurable options below this line. | |
# -------------------------------------------------------------------------------- | |
function usage() | |
{ | |
printf %s ' | |
Version: | |
'"${VERSION}"' | |
Usage: | |
'"${PROGRAM}"' [-v] [-j] [-x] srcdir targetdir | |
-v increases the verbosity level. A higher level means more output to stdout. | |
Level 0: Warnings and errors only. | |
Level 1: Processed files. | |
Level 2: Executed commands. | |
-j writes a job summary to stdout and exits. | |
srcdir is the directory with the MKV files. | |
targetdir is the directory where the shortened MKV files are created. | |
Always use double quotes around names with spaces, or things won'"'"'t work. | |
' | |
} | |
# ---------------------------------------------------------------------------- | |
function log() | |
{ | |
local message="$1" | |
local verbosityLevel=$2 | |
if (( VERBOSITY >= verbosityLevel )); then | |
echo "${message}" | |
fi | |
} | |
# -------------------------------------------------------------------------------- | |
function logRun() | |
{ | |
local commands=("$@") | |
# Read the last element (i.e. the verbosity level) | |
local verbosityLevel="${commands[$(( ${#commands[@]} - 1 ))]}" | |
# Remove last element (the verbosity level) from the commands array. | |
unset commands[$(( ${#commands[@]} - 1 ))] | |
if (( VERBOSITY >= verbosityLevel )); then | |
(set -x; "${commands[@]}") | |
else | |
"${commands[@]}" | |
fi | |
} | |
# -------------------------------------------------------------------------------- | |
function shortenMkv() | |
{ | |
local absSrcFile="$1" | |
local absTargetFile="$2" | |
local ffmpegInputArgs=( "-i" "${absSrcFile}" ) | |
# Encode 2s only. | |
local ffmpegTestArgs=( "-ss" "00:00:00" "-t" "2" ) | |
local ffmpegAudioArgs=( "-flags" "+global_header" "-map" "0:a" "-map" "-0:s" "-map" "0:v" "-map_metadata" "0" "-c:a" "copy" "-c:v" "copy") | |
local ffmpegAllArgs=( | |
"${FFMPEG_LOGGING_ARGS[@]}" | |
"${FFMPEG_BASE_ARGS[@]}" | |
"${ffmpegTestArgs[@]}") | |
ffmpegAllArgs+=( | |
"${ffmpegInputArgs[@]}" | |
"${ffmpegAudioArgs[@]}" | |
"${absTargetFile}") | |
log "-----------------------------------------------------------------------" 2 | |
log "Shortening '${absSrcFile}'..." 1 | |
logRun "${FFMPEG}" "${ffmpegAllArgs[@]}" 3 | |
log "Done." 3 | |
} | |
# ---------------------------------------------------------------------------- | |
function showJobSummary() | |
{ | |
local absSrcRootDir="$1" | |
local absTargetRootDir="$2" | |
local params=( | |
"${absSrcRootDir}" | |
"${absTargetRootDir}") | |
printf " | |
----------------------------------------------------------------------- | |
I would shorten all *.mkv files in source directory to target directory. | |
Source directory : '%s' | |
Target directory : '%s' | |
----------------------------------------------------------------------- | |
" "${params[@]}" | |
} | |
# -------------------------------------------------------------------------------- | |
function run() | |
{ | |
local absSrcRootDir="$1" | |
local absTargetRootDir="$2" | |
if (( JOB_SUMMARY )); then | |
showJobSummary "${absSrcRootDir}" "${absTargetRootDir}" | |
exit | |
fi | |
while read -d '' -r -u3 absSrcFile; do | |
local absTargetFile="${absSrcFile/${absSrcRootDir}/${absTargetRootDir}}" | |
if [ ! -d "${absTargetFile%/*}" ]; then | |
log "-----------------------------------------------------------------------" 2 | |
log "Creating directory..." 2 | |
logRun "${MKDIR}" -p "${absTargetFile%/*}" 3 | |
log "Done." 3 | |
fi | |
shortenMkv "${absSrcFile}" "${absTargetFile}" | |
done 3< <("${FIND}" "${absSrcRootDir}" -type f -name \*.mkv -print0 | "${SORT}" -z) | |
} | |
# ---------------------------------------------------------------------------- | |
# ---------------------------------------------------------------------------- | |
# ---------------------------------------------------------------------------- | |
PROGRAM="${0##*/}" | |
VERBOSITY=0 | |
JOB_SUMMARY=0 | |
while getopts ":vj" optname; do | |
case "$optname" in | |
"v") | |
(( VERBOSITY++ )) | |
;; | |
"j") | |
JOB_SUMMARY=1 | |
;; | |
"?") | |
log "Invalid option: -$OPTARG" 0 >&2 | |
exit 1 | |
;; | |
":") | |
log "Option -$OPTARG requires an argument." 0 >&2 | |
exit 1 | |
;; | |
esac | |
done | |
shift $(( OPTIND - 1 )) | |
if [ $# -ne 2 ]; then | |
usage | |
exit 1 | |
fi | |
# http://www.network-theory.co.uk/docs/bashref/ShellParameterExpansion.html | |
if [ -d "${ABS_CURRENT_DIR}/${1}" ]; then | |
absSrcRootDir="${ABS_CURRENT_DIR}/${1%/}" | |
elif [ -d "${1}" ]; then | |
absSrcRootDir="${1%/}" | |
else | |
log "Invalid srcdir: '${1}'" 0 >&2 | |
exit 1 | |
fi | |
if [ -d "${ABS_CURRENT_DIR}/${2}" ]; then | |
absTargetRootDir="${ABS_CURRENT_DIR}/${2%/}" | |
elif [ -d "${2}" ]; then | |
absTargetRootDir="${2%/}" | |
else | |
log "Invalid targetdir: '${2}'" 0 >&2 | |
exit 1 | |
fi | |
run "${absSrcRootDir}" "${absTargetRootDir}" | |
log "-----------------------------------------------------------------------" 2 | |
log "All done." 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment