Skip to content

Instantly share code, notes, and snippets.

@tmck-code
Last active March 7, 2019 13:53
Show Gist options
  • Select an option

  • Save tmck-code/ae30c6835991895b901f8bee14a7dff4 to your computer and use it in GitHub Desktop.

Select an option

Save tmck-code/ae30c6835991895b901f8bee14a7dff4 to your computer and use it in GitHub Desktop.
Encode all files in a directory tree to a different location, while mirroring the structure

encode-dirs-mirrored

This is a simple command line tool in Bash tailored for encoding all files in a directory tree, mirroring the folder structure in a different location.

Prerequisites:

  • Bash
  • ffmpeg

Behaviour

Input:

./encode-dirs-mirrored.sh <input_dir> <output_dir> <opts>

<opts> include: --copy-on-error: if an error occurs, copy the file to the new location, e.g. when you want to preserve metadata/subtitle files etc

e.g.

./endode-dirs-mirrored.sh ./original/ ./encoded/ ./endode-dirs-mirrored.sh /home/user/videos/original/ /mnt/external/encoded/

Notes

This script uses GNU utils, not BSD utils. If you are running on a mac, you must ensure that the following utils are aliased or overridden correctly to their GNU variants

  • readlink
#!/bin/bash
# github.com/tmck-code/encode-dirs-mirrored
set -euo pipefail
# Nice wee help message just in case
if [ -z ${1:-} ] || [ -z ${2:-} ]; then
echo "Error: Must specify input & output dirs
e.g. ./encode-dirs-mirrored <input_dir> <output_dir>"
exit 1
fi
input_dir=$(greadlink -f "${1}")
output_dir=$(greadlink -f "${2}")
echo -e "Encoding all videos, mirroring structure\n"
echo "in: ${input_dir}\nout: ${output_dir}\n"
# this script will attempt to encode _all_ files in the input dir, regardless
# of type or file extension.
files=$(find "${input_dir}" -type f)
n_files=$(echo "${files[@]}" | wc -l | tr -d '[:space:]')
n_errors=0
echo -e "Encoding ${n_files} files\n"
# This solution is NON-RECURSIVE (improves code readability).
for f in $(echo "${files[@]}"); do
output_subdir="${output_dir}$(dirname ${f})"
output_fpath="${output_subdir}/$(basename ${f})"
echo -e "-- ${f}\n-> ${output_fpath}\n"
mkdir -p "${output_subdir}"
if ! $(ffmpeg -i "${f}" -loglevel 16 -acodec copy -vcodec copy "${output_fpath}"); then
echo -e "!! Error when encoding ${f}\n"
[ "${3:-}" == "--copy-on-error" ] && cp -v "${f}" "${output_fpath}"
n_errors=$((n_errors+=1))
fi
done
[ "${n_errors}" != 0 ] && echo "- Errors occurred for ${n_errors}/${n_files} files"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment