-
Notifications
You must be signed in to change notification settings - Fork 35
/
auto-m4b-tool.sh
executable file
·160 lines (138 loc) · 5.38 KB
/
auto-m4b-tool.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/bin/bash
# set m to 1
m=1
#variable defenition
inputfolder="${INPUT_FOLDER:-"/temp/merge/"}"
outputfolder="${OUTPUT_FOLDER:-"/temp/untagged/"}"
originalfolder="${ORIGINAL_FOLDER:-"/temp/recentlyadded/"}"
fixitfolder="${FIXIT_FOLDER:-"/temp/fix"}"
backupfolder="${BACKUP_FOLDER:-"/temp/backup/"}"
binfolder="${BIN_FOLDER:-"/temp/delete/"}"
m4bend=".m4b"
logend=".log"
#ensure the expected folder-structure
mkdir -p "$inputfolder"
mkdir -p "$outputfolder"
mkdir -p "$originalfolder"
mkdir -p "$fixitfolder"
mkdir -p "$backupfolder"
mkdir -p "$binfolder"
#fix of the user for the new created folders
username="$(whoami)"
userid="$(id -u $username)"
groupid="$(id -g $username)"
chown -R $userid:$groupid /temp
#adjust the number of cores depending on the ENV CPU_CORES
if [ -z "$CPU_CORES" ]
then
echo "Using all CPU cores as not other defined."
CPUcores=$(nproc --all)
else
echo "Using $CPU_CORES CPU cores as defined."
CPUcores="$CPU_CORES"
fi
#adjust the interval of the runs depending on the ENV SLEEPTIME
if [ -z "$SLEEPTIME" ]
then
echo "Using standard 1 min sleep time."
sleeptime=1m
else
echo "Using $SLEEPTIME min sleep time."
sleeptime="$SLEEPTIME"
fi
#change to the merge folder, keeps this clear and the script could be kept inside the container
cd "$inputfolder" || return
# continue until $m 5
while [ $m -ge 0 ]; do
#copy files to backup destination
if [ "$MAKE_BACKUP" == "N" ]; then
echo "Skipping making a backup"
else
echo "Making a backup of the whole $originalfolder"
cp -Ru "$originalfolder"* $backupfolder
fi
#make sure all single file mp3's & m4b's are in their own folder
echo "Making sure all books are in their own folder"
for file in "$originalfolder"*.{m4b,mp3}; do
if [[ -f "$file" ]]; then
mkdir "${file%.*}"
mv "$file" "${file%.*}"
fi
done
# Finds folders with nested subfolders - renames and flattens files into a single folder
echo "Flattening nested subfolders 3 levels deep or more and renaming files..."
find "$originalfolder" -mindepth 3 -type f \( -name '*.mp3' -o -name '*.m4b' -o -name '*.m4a' \) -print0 |
while IFS= read -r -d '' file; do
# Get the relative path from the original folder
relative_path="${file#$originalfolder/}"
# Split the path into an array
IFS='/' read -ra path_parts <<< "$relative_path"
# Only process if the file is at least 3 levels deep
if [ ${#path_parts[@]} -ge 4 ]; then
# Get the filename (last element)
filename="${path_parts[-1]}"
# Get the grandparent directory
grandparent="${path_parts[3]}"
# Construct the new filename
new_filename=""
for ((i=4; i<${#path_parts[@]}-1; i++)); do
new_filename+="${path_parts[i]} - "
done
new_filename+="$filename"
# Create the new path (2 levels deep)
new_path="$originalfolder/$grandparent/$new_filename"
# Create the grandparent directory if it doesn't exist
mkdir -p "$(dirname "$new_path")"
# Move and rename the file
mv -v "$file" "$new_path"
fi
done
#Move folders with multiple audiofiles to inputfolder
echo "Moving folders with 2 or more audiofiles to $inputfolder "
find "$originalfolder" -maxdepth 2 -mindepth 2 -type f \( -name '*.mp3' -o -name '*.m4b' -o -name '*.m4a' \) -print0 | xargs -0 -L 1 dirname | sort | uniq -c | grep -E -v '^ *1 ' | sed 's/^ *[0-9]* //' | while read i; do mv -v "$i" $inputfolder; done
#Move single file mp3's to inputfolder
echo "Moving single file mp3's to $inputfolder "
find "$originalfolder" -maxdepth 2 -type f \( -name '*.mp3' \) -printf "%h\0" | xargs -0 mv -t "$inputfolder"
#Moving the single m4b files to the untagged folder as no Merge needed
echo "Moving all the single m4b books to $outputfolder "
find "$originalfolder" -maxdepth 2 -type f \( -iname \*.m4b -o -iname \*.mp4 -o -iname \*.m4a -o -iname \*.ogg \) -printf "%h\0" | xargs -0 mv -t "$outputfolder"
# clear the folders
rm -r "$binfolder"* 2>/dev/null
if ls -d */ 2>/dev/null; then
echo Folder Detected
for book in *; do
if [ -d "$book" ]; then
mpthree=$(find "$book" -maxdepth 2 -type f \( -name '*.mp3' -o -name '*.m4b' \) | head -n 1)
m4bfile="$outputfolder$book/$book$m4bend"
logfile="$outputfolder$book/$book$logend"
chapters=$(ls "$inputfolder$book"/*chapters.txt 2> /dev/null | wc -l)
if [ "$chapters" != "0" ]; then
echo Adjusting Chapters
mp4chaps -i "$inputfolder""$book"/*$m4bend
mv "$inputfolder$book" "$outputfolder"
else
echo Sampling $mpthree
bit=$(ffprobe -hide_banner -loglevel 0 -of flat -i "$mpthree" -select_streams a -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1)
echo Bitrate = $bit
echo The folder "$book" will be merged to "$m4bfile"
echo Starting Conversion
m4b-tool merge "$book" -n -q --audio-bitrate="$bit" --skip-cover --use-filenames-as-chapters --no-chapter-reindexing --audio-codec=libfdk_aac --jobs="$CPUcores" --output-file="$m4bfile" --logfile="$logfile"
mv "$inputfolder$book" "$binfolder"
fi
echo Finished Converting
#make sure all single file m4b's are in their own folder
echo Putting the m4b into a folder
for file in $outputfolder*.m4b; do
if [[ -f "$file" ]]; then
mkdir "${file%.*}"
mv "$file" "${file%.*}"
fi
done
echo Deleting duplicate mp3 audiobook folder
fi
done
else
echo No folders detected, next run $sleeptime min...
sleep $sleeptime
fi
done