Skip to content

Instantly share code, notes, and snippets.

@Vftdan
Last active July 23, 2023 07:05
Show Gist options
  • Save Vftdan/e2b4d91ec9e4dc30b2c21dfe60bd6194 to your computer and use it in GitHub Desktop.
Save Vftdan/e2b4d91ec9e4dc30b2c21dfe60bd6194 to your computer and use it in GitHub Desktop.
Script for copying file trees while converting files with some extension. Extensions to convert and conversion commands can be easily added or changed.
#! /bin/sh
# Should work both in bash and dash + GNU coreutils. Probably works in other POSIX shells & coreutils.
if [ $# -ne 2 ]; then \
echo "Usage: $0 <old_dir> <new_dir>" >&2
exit 1
fi
# Output dir must not be descendor of input dir!
in_dir="$(realpath "$1")"
out_dir="$(realpath "$2")"
stdin="$(realpath /dev/stdin)"
convert_path() {
# Usage: convert_path <in_path> [<old_ext>] [<new_ext>]
local ext_changed="${1%$2}$3"
printf '%s\n' "$out_dir${ext_changed#$in_dir}"
}
# BEGIN conversion commands
# <cmd> <in_file> <out_file>
cmd_copy() {
cp -i "$1" "$2"
}
cmd_transcode_m4a() {
# You may want to use 192K instead of 128K (or another bitrate)
ffmpeg -hide_banner -i "$1" -vn -c:a aac -b:a 128K "$2"
}
cmd_playlist_m4a() {
sed -e 's/.\(flac\)$/.m4a/' "$1" > "$2"
}
# Example for opus:
cmd_transcode_opus() {
# For voice 43k should be enough AFAIK
ffmpeg -hide_banner -i "$1" -vn -c:a libopus -b:a 87k -vbr on -frame_duration 60 -application audio "$2"
}
cmd_playlist_opus() {
# Other source formats can be added
sed -e 's/.\(flac\|m4a\|mp3\)$/.opus/' "$1" > "$2"
}
# END conversion commands
copy_or_convert() {
# Usage: copy_or_convert <in_file>
local copy_cmd='cmd_copy'
local old_ext=''
local new_ext=''
case "$1" in
*.flac)
old_ext=flac
new_ext=m4a
copy_cmd=cmd_transcode_m4a
;;
# *.mp3)
# old_ext=mp3
# new_ext=m4a
# copy_cmd=cmd_transcode_m4a
# *.m4a)
# old_ext=m4a
# new_ext=opus
# copy_cmd=cmd_transcode_opus
# ;;
*.m3u|*.m3u8)
copy_cmd=cmd_playlist_m4a
;;
esac
"$copy_cmd" "$1" "$(convert_path "$1" "$old_ext" "$new_ext")" < "$stdin"
}
# Create dirs
find "$in_dir" -type d | while read -r file; do \
mkdir -p "$(convert_path "$file")"
done
# Process regular files
find "$in_dir" -type f | while read -r file; do \
copy_or_convert "$file"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment