mirror of
https://github.com/auricom/home-cluster.git
synced 2025-09-17 18:24:14 +02:00
refactor: music-transcode
This commit is contained in:
@@ -3,14 +3,14 @@
|
|||||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
metadata:
|
metadata:
|
||||||
name: &app music-transcode
|
name: &app homelab-music-transcode
|
||||||
namespace: flux-system
|
namespace: flux-system
|
||||||
spec:
|
spec:
|
||||||
targetNamespace: default
|
targetNamespace: default
|
||||||
commonMetadata:
|
commonMetadata:
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: *app
|
app.kubernetes.io/name: *app
|
||||||
path: ./kubernetes/apps/default/music-transcode/app
|
path: ./kubernetes/apps/default/homelab/music-transcode
|
||||||
prune: true
|
prune: true
|
||||||
sourceRef:
|
sourceRef:
|
||||||
kind: GitRepository
|
kind: GitRepository
|
@@ -3,7 +3,7 @@
|
|||||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||||
kind: HelmRelease
|
kind: HelmRelease
|
||||||
metadata:
|
metadata:
|
||||||
name: &app music-transcode
|
name: &app homelab-music-transcode
|
||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
interval: 30m
|
interval: 30m
|
330
kubernetes/apps/default/homelab/music-transcode/scripts/transcode.sh
Executable file
330
kubernetes/apps/default/homelab/music-transcode/scripts/transcode.sh
Executable file
@@ -0,0 +1,330 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Exit on any error
|
||||||
|
set -e
|
||||||
|
# Exit on undefined variable
|
||||||
|
set -u
|
||||||
|
# Exit if any command in pipe fails
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# Create a logging function
|
||||||
|
log() {
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
checkForVariable() {
|
||||||
|
if [[ -z "${!1:-}" ]]; then
|
||||||
|
log "ERROR: $1 environment variable is not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
local exit_code=$?
|
||||||
|
log "Cleaning up..."
|
||||||
|
[[ -f "$TRANSCODE_INPUT_DIR/.fdignore" ]] && rm -f "$TRANSCODE_INPUT_DIR/.fdignore"
|
||||||
|
[[ -f "$TRANSCODE_OUTPUT_DIR/.fdignore" ]] && rm -f "$TRANSCODE_OUTPUT_DIR/.fdignore"
|
||||||
|
exit $exit_code
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'log "Script interrupted by user"; exit 1' INT TERM
|
||||||
|
|
||||||
|
# Initialize variables with defaults
|
||||||
|
export MODE_DELETE=false
|
||||||
|
export MODE_CHECKSUM=false
|
||||||
|
export MODE_DRY_RUN=false
|
||||||
|
export TIMESTAMP=$(date "+%Y%m%d_%H%M%S")
|
||||||
|
|
||||||
|
# Check required environment variables
|
||||||
|
checkForVariable TRANSCODE_INPUT_DIR
|
||||||
|
checkForVariable TRANSCODE_OUTPUT_DIR
|
||||||
|
|
||||||
|
# Set defaults if not defined
|
||||||
|
export TRANSCODE_DB="${TRANSCODE_DB:-${TRANSCODE_OUTPUT_DIR}.transcode}"
|
||||||
|
export TRANSCODE_FREAC_BIN="${TRANSCODE_FREAC_BIN:-/app/freaccmd}"
|
||||||
|
export TRANSCODE_COVER_EXTENSIONS="${TRANSCODE_COVER_EXTENSIONS:-png jpg}"
|
||||||
|
export TRANSCODE_MUSIC_EXTENSIONS="${TRANSCODE_MUSIC_EXTENSIONS:-flac opus mp3 ogg wma m4a wav}"
|
||||||
|
export TRANSCODE_FD_FILTERS="${TRANSCODE_FD_FILTERS:---changed-within 1week}"
|
||||||
|
|
||||||
|
# Validate directories and files
|
||||||
|
for dir in "$TRANSCODE_INPUT_DIR" "$TRANSCODE_OUTPUT_DIR"; do
|
||||||
|
if [[ ! -d "$dir" ]]; then
|
||||||
|
log "ERROR: Directory $dir does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! -f "$TRANSCODE_FREAC_BIN" ]]; then
|
||||||
|
log "ERROR: Binary $TRANSCODE_FREAC_BIN does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$(pwd)/transcode_exclude.cfg" ]]; then
|
||||||
|
log "ERROR: transcode_exclude.cfg file is missing"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine fd binary name based on OS
|
||||||
|
if grep -q ID_LIKE=debian /etc/os-release; then
|
||||||
|
export TRANSCODE_FD_BIN="fdfind"
|
||||||
|
else
|
||||||
|
export TRANSCODE_FD_BIN="fd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
command -v "$TRANSCODE_FD_BIN" >/dev/null 2>&1 || {
|
||||||
|
log "ERROR: $TRANSCODE_FD_BIN is required but not installed"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH="$(dirname "$TRANSCODE_FREAC_BIN")"
|
||||||
|
|
||||||
|
# Create transcode DB directory if it doesn't exist
|
||||||
|
mkdir -p "$TRANSCODE_DB"
|
||||||
|
|
||||||
|
# Parse command line options
|
||||||
|
while getopts ':frcd' OPTION; do
|
||||||
|
case "$OPTION" in
|
||||||
|
f)
|
||||||
|
log "INFO: FULL MODE"
|
||||||
|
export TRANSCODE_FD_FILTERS=""
|
||||||
|
;;
|
||||||
|
r)
|
||||||
|
log "INFO: DELETE MODE"
|
||||||
|
export MODE_DELETE=true
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
log "INFO: CHECKSUM MODE"
|
||||||
|
export MODE_CHECKSUM=true
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
log "INFO: DRY RUN MODE"
|
||||||
|
export MODE_DRY_RUN=true
|
||||||
|
;;
|
||||||
|
?)
|
||||||
|
log "script usage: $(basename "$0") [-f] [-r] [-c] [-d]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
transcode() {
|
||||||
|
local input_file="$1"
|
||||||
|
local output_file="$2"
|
||||||
|
local md5_file="$3"
|
||||||
|
|
||||||
|
log "##: Processing file $input_file..."
|
||||||
|
if [[ $MODE_DRY_RUN == false ]]; then
|
||||||
|
local output
|
||||||
|
if ! output=$("$TRANSCODE_FREAC_BIN" --encoder=opus --bitrate 96 "$input_file" -o "$output_file" 2>&1); then
|
||||||
|
log "ERROR: Transcoding failed for $input_file"
|
||||||
|
log "$output"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "$output" | grep -q "Could not process"; then
|
||||||
|
log "ERROR: Could not process $input_file"
|
||||||
|
log "$output"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$md5_file")"
|
||||||
|
md5sum "$input_file" | awk '{ print $1 }' > "$md5_file"
|
||||||
|
log "Successfully transcoded: $input_file -> $output_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
write_cue() {
|
||||||
|
local input_file="$1"
|
||||||
|
local output_file="$2"
|
||||||
|
local replacement_string="$3"
|
||||||
|
local md5_file="$4"
|
||||||
|
|
||||||
|
log "##: writing $input_file"
|
||||||
|
if [[ $MODE_DRY_RUN == false ]]; then
|
||||||
|
if ! sed -i "/FILE/c $replacement_string" "$output_file"; then
|
||||||
|
log "ERROR: writing cuefile $output_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$md5_file")"
|
||||||
|
md5sum "$input_file" | awk '{ print $1 }' > "$md5_file"
|
||||||
|
log "Successfully wrote cue: $output_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
write_jpg() {
|
||||||
|
local input_file="$1"
|
||||||
|
local output_file="$2"
|
||||||
|
local md5_file="$3"
|
||||||
|
|
||||||
|
log "##: converting cover $input_file"
|
||||||
|
if [[ $MODE_DRY_RUN == false ]]; then
|
||||||
|
if ! convert "$input_file" -resize 1000 -quality 75 "$output_file"; then
|
||||||
|
log "ERROR: converting cover $input_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$md5_file")"
|
||||||
|
md5sum "$input_file" | awk '{ print $1 }' > "$md5_file"
|
||||||
|
log "Successfully converted cover: $input_file -> $output_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
directory_structure() {
|
||||||
|
local dryrun_flag=""
|
||||||
|
[[ $MODE_DRY_RUN == true ]] && dryrun_flag="--dry-run"
|
||||||
|
|
||||||
|
log "INFO: Creating directory structure with rsync..."
|
||||||
|
if ! rsync -rvz $dryrun_flag --exclude-from="./transcode_exclude.cfg" \
|
||||||
|
--include="*/" --exclude="*" "$TRANSCODE_INPUT_DIR" "$TRANSCODE_OUTPUT_DIR"; then
|
||||||
|
log "ERROR: rsync failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_covers() {
|
||||||
|
log "INFO: Looking for covers to convert..."
|
||||||
|
cd "$TRANSCODE_INPUT_DIR" || exit 1
|
||||||
|
|
||||||
|
for ext in $TRANSCODE_COVER_EXTENSIONS; do
|
||||||
|
log "INFO: Searching for .$ext files..."
|
||||||
|
while IFS= read -r val; do
|
||||||
|
[[ -z "$val" ]] && continue
|
||||||
|
|
||||||
|
local filename="$TRANSCODE_OUTPUT_DIR/${val%.*}.jpg"
|
||||||
|
local md5_filename="$TRANSCODE_DB/${val}.md5"
|
||||||
|
local process_file=false
|
||||||
|
|
||||||
|
# Create output directory if it doesn't exist
|
||||||
|
mkdir -p "$(dirname "$filename")"
|
||||||
|
mkdir -p "$(dirname "$md5_filename")"
|
||||||
|
|
||||||
|
# Check if we need to process this file
|
||||||
|
if [[ ! -f "$md5_filename" ]]; then
|
||||||
|
process_file=true
|
||||||
|
log "Processing new file: $val"
|
||||||
|
elif [[ $MODE_CHECKSUM == true ]]; then
|
||||||
|
if [[ ! -f "$md5_filename" ]] || [[ "$(cat "$md5_filename" 2>/dev/null)" != "$(md5sum "$val" | awk '{ print $1 }')" ]]; then
|
||||||
|
process_file=true
|
||||||
|
log "File changed, reprocessing: $val"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $process_file == true ]]; then
|
||||||
|
write_jpg "$val" "$filename" "$md5_filename"
|
||||||
|
fi
|
||||||
|
done < <("$TRANSCODE_FD_BIN" --extension "$ext" $TRANSCODE_FD_FILTERS --type f)
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_music() {
|
||||||
|
log "INFO: Looking for music to transcode..."
|
||||||
|
cd "$TRANSCODE_INPUT_DIR" || exit 1
|
||||||
|
|
||||||
|
for ext in $TRANSCODE_MUSIC_EXTENSIONS; do
|
||||||
|
log "INFO: Searching for .$ext files..."
|
||||||
|
while IFS= read -r val; do
|
||||||
|
[[ -z "$val" ]] && continue
|
||||||
|
|
||||||
|
local filebasename="$TRANSCODE_OUTPUT_DIR/${val%.*}"
|
||||||
|
local filename="${filebasename}.opus"
|
||||||
|
local md5_filename="$TRANSCODE_DB/${val}.md5"
|
||||||
|
local process_file=false
|
||||||
|
|
||||||
|
# Create output directory if it doesn't exist
|
||||||
|
mkdir -p "$(dirname "$filename")"
|
||||||
|
mkdir -p "$(dirname "$md5_filename")"
|
||||||
|
|
||||||
|
# Check if we need to process this file
|
||||||
|
if [[ ! -f "$md5_filename" ]]; then
|
||||||
|
process_file=true
|
||||||
|
log "Processing new file: $val"
|
||||||
|
elif [[ $MODE_CHECKSUM == true ]]; then
|
||||||
|
if [[ ! -f "$md5_filename" ]] || [[ "$(cat "$md5_filename" 2>/dev/null)" != "$(md5sum "$val" | awk '{ print $1 }')" ]]; then
|
||||||
|
process_file=true
|
||||||
|
log "File changed, reprocessing: $val"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $process_file == true ]]; then
|
||||||
|
transcode "$val" "$filename" "$md5_filename"
|
||||||
|
fi
|
||||||
|
done < <("$TRANSCODE_FD_BIN" --extension "$ext" $TRANSCODE_FD_FILTERS --type f)
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
fix_cuefiles() {
|
||||||
|
log "INFO: Looking for cuefiles..."
|
||||||
|
cd "$TRANSCODE_INPUT_DIR" || exit 1
|
||||||
|
|
||||||
|
while IFS= read -r val; do
|
||||||
|
[[ -z "$val" ]] && continue
|
||||||
|
|
||||||
|
local output_file="$TRANSCODE_OUTPUT_DIR/$val"
|
||||||
|
local md5_filename="$TRANSCODE_DB/${val}.md5"
|
||||||
|
local replacement_text_string="FILE \"$(basename "${val%.*}").opus\" MP3"
|
||||||
|
local process_file=false
|
||||||
|
|
||||||
|
# Create output directory if it doesn't exist
|
||||||
|
mkdir -p "$(dirname "$output_file")"
|
||||||
|
mkdir -p "$(dirname "$md5_filename")"
|
||||||
|
|
||||||
|
# Check if we need to process this file
|
||||||
|
if [[ ! -f "$md5_filename" ]]; then
|
||||||
|
process_file=true
|
||||||
|
log "Processing new cuefile: $val"
|
||||||
|
elif [[ $MODE_CHECKSUM == true ]]; then
|
||||||
|
if [[ ! -f "$md5_filename" ]] || [[ "$(cat "$md5_filename" 2>/dev/null)" != "$(md5sum "$val" | awk '{ print $1 }')" ]]; then
|
||||||
|
process_file=true
|
||||||
|
log "Cuefile changed, reprocessing: $val"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $process_file == true ]]; then
|
||||||
|
cp -p "$val" "$output_file"
|
||||||
|
write_cue "$val" "$output_file" "$replacement_text_string" "$md5_filename"
|
||||||
|
fi
|
||||||
|
done < <("$TRANSCODE_FD_BIN" --extension cue $TRANSCODE_FD_FILTERS --type f)
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_absent_from_source() {
|
||||||
|
cd "$TRANSCODE_DB" || exit 1
|
||||||
|
|
||||||
|
local files
|
||||||
|
files=$("$TRANSCODE_FD_BIN" --extension md5) || return 0
|
||||||
|
|
||||||
|
while IFS= read -r val; do
|
||||||
|
[[ -z "$val" ]] && continue
|
||||||
|
|
||||||
|
local filename="$(dirname "$val")/$(basename "$val" .md5)"
|
||||||
|
if ! "$TRANSCODE_FD_BIN" . "$TRANSCODE_INPUT_DIR/$(dirname "$filename")" 2>/dev/null | grep -qF "$(basename "$filename" .md5)"; then
|
||||||
|
log "INFO: Transcoded file $filename doesn't have a source file: delete"
|
||||||
|
if [[ $MODE_DRY_RUN == false ]]; then
|
||||||
|
rm -f "$TRANSCODE_OUTPUT_DIR/$filename"*
|
||||||
|
rm -f "$TRANSCODE_DB/$filename"*
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done <<< "$files"
|
||||||
|
|
||||||
|
log "INFO: removing empty directories..."
|
||||||
|
if [[ $MODE_DRY_RUN == false ]]; then
|
||||||
|
cd "$TRANSCODE_OUTPUT_DIR" || exit 1
|
||||||
|
"$TRANSCODE_FD_BIN" --type empty --exec-batch rmdir {} \; || true
|
||||||
|
cd "$TRANSCODE_DB" || exit 1
|
||||||
|
"$TRANSCODE_FD_BIN" --type empty --exec-batch rmdir {} \; || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
cp -f ./transcode_exclude.cfg "$TRANSCODE_INPUT_DIR/.fdignore"
|
||||||
|
cp -f ./transcode_exclude.cfg "$TRANSCODE_OUTPUT_DIR/.fdignore"
|
||||||
|
|
||||||
|
if [[ $MODE_DELETE == false ]]; then
|
||||||
|
directory_structure
|
||||||
|
convert_covers
|
||||||
|
convert_music
|
||||||
|
fix_cuefiles
|
||||||
|
else
|
||||||
|
remove_absent_from_source
|
||||||
|
fi
|
@@ -5,3 +5,4 @@ tmp
|
|||||||
.thumbnails
|
.thumbnails
|
||||||
.qbittorrent
|
.qbittorrent
|
||||||
.usenet
|
.usenet
|
||||||
|
.lms
|
@@ -19,6 +19,7 @@ resources:
|
|||||||
- ./hajimari/ks.yaml
|
- ./hajimari/ks.yaml
|
||||||
- ./home-assistant/ks.yaml
|
- ./home-assistant/ks.yaml
|
||||||
- ./homebox/ks.yaml
|
- ./homebox/ks.yaml
|
||||||
|
- ./homelab/ks.yaml
|
||||||
- ./homepage/ks.yaml
|
- ./homepage/ks.yaml
|
||||||
- ./jellyfin/ks.yaml
|
- ./jellyfin/ks.yaml
|
||||||
- ./joplin/ks.yaml
|
- ./joplin/ks.yaml
|
||||||
@@ -30,7 +31,6 @@ resources:
|
|||||||
- ./lldap/ks.yaml
|
- ./lldap/ks.yaml
|
||||||
- ./lms/ks.yaml
|
- ./lms/ks.yaml
|
||||||
- ./lychee/ks.yaml
|
- ./lychee/ks.yaml
|
||||||
- ./music-transcode/ks.yaml
|
|
||||||
- ./navidrome/ks.yaml
|
- ./navidrome/ks.yaml
|
||||||
- ./outline/ks.yaml
|
- ./outline/ks.yaml
|
||||||
- ./paperless/ks.yaml
|
- ./paperless/ks.yaml
|
||||||
|
@@ -1,306 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
exec > >(awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }') 2>&1
|
|
||||||
|
|
||||||
checkForVariable()
|
|
||||||
{
|
|
||||||
local env_var=
|
|
||||||
env_var=$(declare -p "$1")
|
|
||||||
if ! [[ -v $1 && $env_var =~ ^declare\ -x ]]; then
|
|
||||||
echo "ERROR: $1 environment variable is not set"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
export MODE_DELETE=false
|
|
||||||
export MODE_CHECKSUM=false
|
|
||||||
export MODE_DRY_RUN=false
|
|
||||||
export TIMESTAMP=$(date "+%Y%m%d_%H%M%S")
|
|
||||||
|
|
||||||
checkForVariable TRANSCODE_INPUT_DIR
|
|
||||||
checkForVariable TRANSCODE_OUTPUT_DIR
|
|
||||||
|
|
||||||
if [ -z "$TRANSCODE_DB" ]; then
|
|
||||||
export TRANSCODE_DB="$TRANSCODE_OUTPUT_DIR.transcode"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$TRANSCODE_FREAC_BIN" ]; then
|
|
||||||
export TRANSCODE_FREAC_BIN="/app/freaccmd"
|
|
||||||
fi
|
|
||||||
if [ -z "$TRANSCODE_COVER_EXTENSIONS" ]; then
|
|
||||||
export TRANSCODE_COVER_EXTENSIONS="png jpg"
|
|
||||||
fi
|
|
||||||
if [ -z "$TRANSCODE_MUSIC_EXTENSIONS" ]; then
|
|
||||||
export TRANSCODE_MUSIC_EXTENSIONS="flac opus mp3 ogg wma m4a wav"
|
|
||||||
fi
|
|
||||||
if [ -z "$TRANSCODE_FD_FILTERS" ]; then
|
|
||||||
export TRANSCODE_FD_FILTERS="--changed-within 1week"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$TRANSCODE_INPUT_DIR" ]; then
|
|
||||||
echo "ERROR: Directory $TRANSCODE_INPUT_DIR does not exists"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ ! -d "$TRANSCODE_OUTPUT_DIR" ]; then
|
|
||||||
echo "ERROR: Directory $TRANSCODE_OUTPUT_DIR does not exists"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ ! -f "$TRANSCODE_FREAC_BIN" ]; then
|
|
||||||
echo "ERROR: Binary $TRANSCODE_FREAC_BIN does not exists"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
grep -q ID_LIKE=debian /etc/os-release
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
export TRANSCODE_FD_BIN="fdfind"
|
|
||||||
else
|
|
||||||
export TRANSCODE_FD_BIN="fd"
|
|
||||||
fi
|
|
||||||
export LD_LIBRARY_PATH=$(dirname $TRANSCODE_FREAC_BIN)
|
|
||||||
|
|
||||||
test ! -d $TRANSCODE_DB && mkdir -p $TRANSCODE_DB
|
|
||||||
|
|
||||||
if [ ! -f "$(pwd)/transcode_exclude.cfg" ]; then
|
|
||||||
echo "ERROR : transcode_exclude.cfg file is missing"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
while getopts ':frcd' OPTION; do
|
|
||||||
case "$OPTION" in
|
|
||||||
f)
|
|
||||||
echo "INFO: FULL MODE"
|
|
||||||
export TRANSCODE_FD_FILTERS=""
|
|
||||||
;;
|
|
||||||
r)
|
|
||||||
echo "INFO: DELETE MODE"
|
|
||||||
export MODE_DELETE=true
|
|
||||||
;;
|
|
||||||
c)
|
|
||||||
echo "INFO: CHECKSUM MODE"
|
|
||||||
export MODE_CHECKSUM=true
|
|
||||||
;;
|
|
||||||
d)
|
|
||||||
echo "INFO: DRY RUN MODE"
|
|
||||||
export MODE_DRY_RUN=true
|
|
||||||
;;
|
|
||||||
?)
|
|
||||||
echo "script usage: $(basename \$0) [-f] [-r] [-c] [-d]"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
transcode()
|
|
||||||
{
|
|
||||||
input_file=$1
|
|
||||||
output_file=$2
|
|
||||||
md5_file=$3
|
|
||||||
|
|
||||||
echo "##: Processing file $1..."
|
|
||||||
if [ $MODE_DRY_RUN == false ]; then
|
|
||||||
output=$($TRANSCODE_FREAC_BIN --encoder=opus --bitrate 96 "$input_file" -o "$output_file")
|
|
||||||
result=$(echo "$output" | grep -c "Could not process")
|
|
||||||
if [ $result -eq 1 ]; then
|
|
||||||
echo -e "$output"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
mkdir -p "$TRANSCODE_DB/$(dirname "$input_file")"
|
|
||||||
echo "$(md5sum "$input_file" | awk '{ print $1 }')" > "$md5_file"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
write_cue()
|
|
||||||
{
|
|
||||||
input_file=$1
|
|
||||||
output_file=$2
|
|
||||||
replacement_string=$3
|
|
||||||
md5_file=$4
|
|
||||||
|
|
||||||
echo "##: writing $input_file"
|
|
||||||
if [ $MODE_DRY_RUN == false ]; then
|
|
||||||
sed -i "/FILE/c $replacement_string" "$output_file"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "ERROR: writing cuefile $output_file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
mkdir -p "$TRANSCODE_DB/$(dirname "$input_file")"
|
|
||||||
echo "$(md5sum "$input_file" | awk '{ print $1 }')" > "$md5_file"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
write_jpg()
|
|
||||||
{
|
|
||||||
input_file=$1
|
|
||||||
output_file=$2
|
|
||||||
md5_file=$3
|
|
||||||
|
|
||||||
echo "##: converting cover $input_file"
|
|
||||||
if [ $MODE_DRY_RUN == false ]; then
|
|
||||||
convert "$input_file" -resize 1000 -quality 75 "$output_file"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "ERROR: converting cover $input_file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
mkdir -p "$TRANSCODE_DB/$(dirname "$input_file")"
|
|
||||||
echo "$(md5sum "$input_file" | awk '{ print $1 }')" > "$md5_file"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
directory_structure()
|
|
||||||
{
|
|
||||||
if [ $MODE_DRY_RUN == true ]; then
|
|
||||||
DRYRUN_FLAG="--dry-run"
|
|
||||||
else
|
|
||||||
DRYRUN_FLAG=""
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
echo "INFO: Creating directory structure with rsync..."
|
|
||||||
rsync -rvz $DRYRUN_FLAG --exclude-from="./transcode_exclude.cfg" --include="*/" --exclude="*" $TRANSCODE_INPUT_DIR $TRANSCODE_OUTPUT_DIR
|
|
||||||
}
|
|
||||||
|
|
||||||
convert_covers()
|
|
||||||
{
|
|
||||||
echo "INFO: Looking for covers to convert..."
|
|
||||||
cd $TRANSCODE_INPUT_DIR
|
|
||||||
|
|
||||||
trap "exit" INT
|
|
||||||
for ext in $TRANSCODE_COVER_EXTENSIONS
|
|
||||||
do
|
|
||||||
FILES=$($TRANSCODE_FD_BIN --extension $ext $TRANSCODE_FD_FILTERS)
|
|
||||||
mapfile -t StringArray <<< "$FILES"
|
|
||||||
for val in "${StringArray[@]}"; do
|
|
||||||
if [ ! -z "$val" ]; then
|
|
||||||
FLAG=false
|
|
||||||
FILENAME="$TRANSCODE_OUTPUT_DIR$(dirname "$val")/$(basename "$val" .$ext).jpg"
|
|
||||||
MD5_FILENAME="$TRANSCODE_DB/$(dirname "$val")/$(basename "$val").md5"
|
|
||||||
# Check if a MD5 checksum already exists
|
|
||||||
RESULT=$($TRANSCODE_FD_BIN . "$(dirname "$MD5_FILENAME")" 2> /dev/null | grep -F "$(basename "$MD5_FILENAME")")
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
FLAG=true
|
|
||||||
# Check if an existing MD5 checksum is different
|
|
||||||
elif [ $MODE_CHECKSUM == true ]; then
|
|
||||||
if [ "$(cat "$MD5_FILENAME")" != "$(md5sum "$val" | awk '{ print $1 }')" ]; then
|
|
||||||
FLAG=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if $FLAG; then write_jpg "$val" "$FILENAME" "$MD5_FILENAME"; fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
convert_music()
|
|
||||||
{
|
|
||||||
echo "INFO: Looking for music to transcode..."
|
|
||||||
cd $TRANSCODE_INPUT_DIR
|
|
||||||
|
|
||||||
trap "exit" INT
|
|
||||||
for ext in $TRANSCODE_MUSIC_EXTENSIONS
|
|
||||||
do
|
|
||||||
FILES=$($TRANSCODE_FD_BIN --extension $ext $TRANSCODE_FD_FILTERS)
|
|
||||||
mapfile -t StringArray <<< "$FILES"
|
|
||||||
for val in "${StringArray[@]}"; do
|
|
||||||
if [ ! -z "$val" ]; then
|
|
||||||
FLAG=false
|
|
||||||
FILEBASENAME="$TRANSCODE_OUTPUT_DIR$(dirname "$val")/$(basename "$val" .$ext)"
|
|
||||||
FILENAME="$FILEBASENAME.opus"
|
|
||||||
MD5_FILENAME="$TRANSCODE_DB/$(dirname "$val")/$(basename "$val" .$ext).md5"
|
|
||||||
# Check if a MD5 checksum already exists
|
|
||||||
RESULT=$($TRANSCODE_FD_BIN . "$(dirname "$MD5_FILENAME")" 2> /dev/null | grep -F "$(basename "$MD5_FILENAME")")
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
FLAG=true
|
|
||||||
# Check if an existing MD5 checksum is different
|
|
||||||
elif [ $MODE_CHECKSUM == true ]; then
|
|
||||||
if [ "$(cat "$MD5_FILENAME")" != "$(md5sum "$val" | awk '{ print $1 }')" ]; then
|
|
||||||
FLAG=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if $FLAG; then transcode "$val" "$FILENAME" "$MD5_FILENAME"; fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
fix_cuefiles()
|
|
||||||
{
|
|
||||||
echo "INFO: Looking for cuefiles..."
|
|
||||||
cd $TRANSCODE_INPUT_DIR
|
|
||||||
|
|
||||||
FILES=$($TRANSCODE_FD_BIN --extension cue $TRANSCODE_FD_FILTERS)
|
|
||||||
mapfile -t StringArray <<< "$FILES"
|
|
||||||
for val in "${StringArray[@]}"; do
|
|
||||||
if [ ! -z "$val" ]; then
|
|
||||||
FLAG=false
|
|
||||||
MD5_FILENAME="$TRANSCODE_DB/$val.md5"
|
|
||||||
REPLACEMENT_TEXT_STRING="FILE \"$(basename "$val" .cue).opus\" MP3"
|
|
||||||
# Check if a MD5 checksum already exists
|
|
||||||
RESULT=$($TRANSCODE_FD_BIN . "$(dirname "$MD5_FILENAME")" 2> /dev/null| grep -F "$(basename "$MD5_FILENAME")")
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
cp -pr "$val" "$TRANSCODE_OUTPUT_DIR/$val"
|
|
||||||
FLAG=true
|
|
||||||
# Check if an existing MD5 checksum is different
|
|
||||||
elif [ $MODE_CHECKSUM == true ]; then
|
|
||||||
if [ "$(cat "$MD5_FILENAME")" != "$(md5sum "$val" | awk '{ print $1 }')" ]; then
|
|
||||||
cp -pr "$val" "$TRANSCODE_OUTPUT_DIR/$val"
|
|
||||||
FLAG=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if $FLAG; then write_cue "$val" "$TRANSCODE_OUTPUT_DIR/$val" "$REPLACEMENT_TEXT_STRING" "$MD5_FILENAME"; fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_absent_from_source()
|
|
||||||
{
|
|
||||||
cd $TRANSCODE_DB
|
|
||||||
|
|
||||||
EXTENSIONS="md5"
|
|
||||||
for ext in $EXTENSIONS
|
|
||||||
do
|
|
||||||
FILES=$($TRANSCODE_FD_BIN --extension $ext)
|
|
||||||
mapfile -t StringArray <<< "$FILES"
|
|
||||||
for val in "${StringArray[@]}"; do
|
|
||||||
if [ ! -z "$val" ]; then
|
|
||||||
FILENAME=$(dirname "$val")/$(basename "$val" .$ext)
|
|
||||||
RESULT=$($TRANSCODE_FD_BIN . "$TRANSCODE_INPUT_DIR/$(dirname "$FILENAME")" 2> /dev/null | grep -F "$(basename "$FILENAME" .$ext)")
|
|
||||||
# Transcoded file don't have a source file : delete
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "INFO: Transcoded file $FILENAME don't have a source file : delete"
|
|
||||||
if [ $MODE_DRY_RUN == false ]; then
|
|
||||||
rm "$TRANSCODE_OUTPUT_DIR/$FILENAME"*
|
|
||||||
rm "$TRANSCODE_DB/$FILENAME"*
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "INFO: removing empty directories..."
|
|
||||||
|
|
||||||
if [ $MODE_DRY_RUN == false ]; then
|
|
||||||
cd "$TRANSCODE_OUTPUT_DIR"
|
|
||||||
$TRANSCODE_FD_BIN --type empty --exec-batch rmdir
|
|
||||||
cd "$TRANSCODE_DB"
|
|
||||||
$TRANSCODE_FD_BIN --type empty --exec-batch rmdir
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cp -r ./transcode_exclude.cfg $TRANSCODE_INPUT_DIR/.fdignore
|
|
||||||
cp -r ./transcode_exclude.cfg $TRANSCODE_OUTPUT_DIR/.fdignore
|
|
||||||
|
|
||||||
if [ $MODE_DELETE == false ]; then
|
|
||||||
directory_structure
|
|
||||||
|
|
||||||
convert_covers
|
|
||||||
|
|
||||||
convert_music
|
|
||||||
|
|
||||||
fix_cuefiles
|
|
||||||
else
|
|
||||||
remove_absent_from_source
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm "$TRANSCODE_INPUT_DIR/.fdignore"
|
|
||||||
rm "$TRANSCODE_OUTPUT_DIR/.fdignore"
|
|
Reference in New Issue
Block a user