-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconvert_audiobook.sh.backup
executable file
·115 lines (96 loc) · 3.79 KB
/
convert_audiobook.sh.backup
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
#!/bin/bash
# Basic error handling
set -e
# Check ffmpeg dependency
if ! command -v "ffmpeg" &> /dev/null; then
echo "Error: ffmpeg is required but not found."
echo "Please install ffmpeg before running this script."
exit 1
fi
# Display usage instructions if no directory provided
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <directory_path>"
echo "Example: $0 ~/Downloads/MyAudiobook"
exit 1
fi
# Get absolute path and book title from directory name
WORKDIR=$(cd "$1" && pwd)
BOOK_TITLE=$(basename "$WORKDIR")
echo "Processing audiobook: $BOOK_TITLE"
# Change to working directory
cd "$WORKDIR"
# Create list of audio files
echo "Creating list of audio files..."
find . -maxdepth 1 -name "*.mp3" -type f | sort | sed "s/^\\.\\/*/file '/;s/$/\'/" > audiofiles.txt
if [ -f audiofiles.txt ]; then
echo "Audio files list created:"
cat audiofiles.txt
else
echo "Error: Failed to create audiofiles.txt"
exit 1
fi
# Get the bitrate of the first file
FIRST_FILE=$(head -n 1 audiofiles.txt | sed "s/file '//;s/'//")
BITRATE=$(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "$FIRST_FILE")
# If bitrate detection fails, provide a warning and default to input file's bitrate
if [ -z "$BITRATE" ] || [ "$BITRATE" = "N/A" ]; then
echo "Warning: Could not detect input bitrate, will maintain input file's bitrate"
BITRATE_OPT=""
else
BITRATE_OPT="-b:a ${BITRATE}"
fi
# Check if metadata.json exists
if [ -f "metadata/metadata.json" ]; then
echo "Found metadata.json, using it for chapter information..."
python3 ~/bin/convert_chapters.py metadata/metadata.json
python3 ~/bin/convert_to_ffmpeg_chapters.py chapters.txt
else
echo "No metadata.json found, using MP3 filenames for chapters..."
# Create chapters metadata from MP3 files
echo "Generating chapter metadata..."
echo ";FFMETADATA1" > ffmpeg_chapters.txt
current_time=0
while IFS= read -r line; do
# Extract filename without path and extension
filename=$(basename "$line" .mp3)
filename=${filename#"file '"}
filename=${filename%"'"}
# Get duration of current file
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$filename")
duration=${duration%.*} # Remove decimal places
# Write chapter metadata
echo "[CHAPTER]" >> ffmpeg_chapters.txt
echo "TIMEBASE=1/1" >> ffmpeg_chapters.txt
echo "START=$current_time" >> ffmpeg_chapters.txt
next_time=$((current_time + duration))
echo "END=$next_time" >> ffmpeg_chapters.txt
echo "title=$filename" >> ffmpeg_chapters.txt
current_time=$next_time
done < audiofiles.txt
fi
# Convert to M4B with chapters
echo "Converting to M4B format..."
# Get the bitrate of the first file
FIRST_FILE=$(head -n 1 audiofiles.txt | sed "s/file '//;s/'//")
BITRATE=$(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "$FIRST_FILE")
# If bitrate detection fails, provide a warning and default to input file's bitrate
if [ -z "$BITRATE" ] || [ "$BITRATE" = "N/A" ]; then
echo "Warning: Could not detect input bitrate, will maintain input file's bitrate"
BITRATE_OPT=""
else
BITRATE_OPT="-b:a ${BITRATE}"
fi
# Convert to M4B with chapters
echo "Converting to M4B format..."
ffmpeg -f concat -safe 0 -i audiofiles.txt \
-i ffmpeg_chapters.txt \
-map_metadata 1 \
-c:a aac $BITRATE_OPT \
-movflags +faststart \
"${BOOK_TITLE}.m4b"
echo "Conversion complete!"
echo "Output file: ${BOOK_TITLE}.m4b"
echo "You can now test the audiobook in your preferred player."
# Cleanup temporary files
echo "Cleaning up temporary files..."
rm -f audiofiles.txt ffmpeg_chapters.txt chapters.json