Created
June 3, 2020 00:42
-
-
Save visualblind/ae298b54688336002538be7f6e769718 to your computer and use it in GitHub Desktop.
Transcode with FFmpeg all (mkv, mp4) media files in specified directory, overwriting the original source files.
This file contains hidden or 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
#!/usr/bin/env bash | |
# | |
## DESCRIPTION: Transcode with FFmpeg all (mkv, mp4) media files in specified directory, | |
## overwriting the original source files. | |
## | |
## AUTHOR: Travis Runyard | |
## Revised: 04/18/2020 | |
## URL: https://sysinfo.io/ffmpeg-batch-transcode-audio/ | |
# Exit on first non-zero exit code | |
set -e | |
# Set shell options | |
shopt -s globstar | |
shopt -u nullglob | |
# Declare variables (optionally) are indexed arrays | |
# Only associative arrays require declaration, but standardizing is a good thing | |
declare -a FILENAME | |
declare -a LOG | |
# Modify TEMPDIR and WORKDIR to suit your needs | |
TEMPDIR="/mnt/pool0/p0ds0smb/temp/ffmpeg" | |
WORKDIR="$TEMPDIR/.working" | |
SCRIPT_NAME=$(basename "$0") | |
usage() | |
{ | |
cat 1>&2 <<EOF | |
Usage: "$SCRIPT_NAME" [options] | |
-h| --help Help shows this message. | |
-d| --directory Specify the directory to process. | |
-w| --workdir Writable working directory for FFmpeg. | |
If you don't specify this option, the | |
subdirectory named "working" will be used | |
within the --directory path or \$TEMPDIR. | |
EOF | |
} | |
while [ "$1" != "" ]; do | |
case $1 in | |
-d | --directory ) shift | |
TEMPDIR="${1:-$TEMPDIR}" | |
WORKDIR="$WORKDIR" | |
;; | |
-w | --workdir ) shift | |
WORKDIR="${1:-$WORKDIR}" | |
;; | |
-h | --help ) usage | |
exit 0 | |
;; | |
* ) usage | |
exit 1 | |
esac | |
shift | |
done | |
cd $TEMPDIR | |
echo -e "*** DEBUG ***\n\$TEMPDIR = $TEMPDIR\n\$WORKDIR = $WORKDIR" | |
[ -d "$WORKDIR" ] || mkdir "$WORKDIR" | |
# Set field separator to newline | |
OIFS="$IFS" | |
IFS=$'\n' | |
FILENAME=($(find . ! -path "*$(basename "$WORKDIR")/*" -regextype posix-extended -regex '.*\.(mkv|mp4)$' -type f -print)) | |
if [ -n "$FILENAME" ]; then | |
for f in "${FILENAME[@]}"; do | |
LOG+=("$f") | |
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f")) | |
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then | |
# Build ffmpeg array within the loop to populate variables | |
args=( | |
-nostdin | |
-y | |
-i "$f" | |
-map 0:v:0 | |
-map 0:a | |
-map 0:s? | |
-ac "${AUDIOFORMAT[1]}" | |
-ar 48000 | |
-metadata:s:a:0 | |
language=eng | |
-c:v copy | |
-c:a aac | |
-c:s copy | |
"$WORKDIR/$(basename "$f")" | |
) | |
echo -e "*** DEBUG: ffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream with '${AUDIOFORMAT[1]}' channels\nPreparing to convert audio codec to AAC..." ; sleep 1 | |
echo -e "*** DEBUG: ffmpeg ${args[@]}" | |
ffmpeg "${args[@]}" || break | |
echo -e "*** DEBUG: Moving '$WORKDIR/$(basename "$f")' back to source directory name '$(dirname "$f")'"; sleep 1 | |
mv -ufv "$WORKDIR/$(basename "$f")" "$(dirname "$f")" || break | |
fi | |
done | |
printf '*** DEBUG ***\nPROCESSED:%s\n' | |
for i in "${LOG[@]}"; do echo "$i"; done | |
else | |
echo -e "*** DEBUG: No files to process" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment