AudiobookBuilder
Build chaptered .m4b audiobooks for Apple Books from folders of audio files.
AudiobookBuilder turns naturally ordered MP3, M4A, WAV, or FLAC tracks into one Apple Books-ready audiobook. It encodes AAC audio, writes a chapter for every source file, embeds useful metadata and optional cover art, and supports whole-series batch jobs.
Why it exists
A folder of narration tracks is not quite an audiobook. Apple Books expects an MPEG-4 audiobook container, consistent AAC audio, useful metadata, and chapter boundaries. AudiobookBuilder handles that assembly in one command without hiding the FFmpeg pipeline behind a fragile desktop wrapper.
Highlights
- One chapter per source file, ordered with natural filename sorting
- AAC
.m4boutput optimized for Apple Books withfaststart - Title, author, album, genre, and optional JPEG/PNG cover art
- Exact duplicate detection before encoding
- Flat-folder and one-book-per-subfolder batch workflows
- Parallel batch encoding with safe temporary outputs
- Native Apple AudioToolbox AAC selection when FFmpeg provides it
- Dry runs and explicit overwrite controls
Install
AudiobookBuilder supports macOS and Python 3.9 or newer.
brew install ffmpeg pipx
pipx ensurepath
pipx install audiobook-builder
Open a new terminal after pipx ensurepath, then confirm both tools are available:
audiobook-build --version
ffmpeg -version
To install the latest source directly from GitHub:
pipx install git+https://github.com/AhHamedi/AudiobookBuilder.git
Quick start
Given a folder like this:
The Long Way Home/
├── 01 Opening.mp3
├── 02 The Journey.mp3
└── 03 Homecoming.mp3
Run:
audiobook-build build "The Long Way Home" \
--title "The Long Way Home" \
--author "A. Narrator"
The default output is The Long Way Home/The_Long_Way_Home.m4b. Add it to Books by double-clicking the file or choosing File → Add to Library.
Add cover art or choose another destination when needed:
audiobook-build build "The Long Way Home" \
--title "The Long Way Home" \
--author "A. Narrator" \
--cover cover.jpg \
--out ~/Audiobooks/the-long-way-home.m4b
Batch builds
One subfolder per audiobook
Library/
├── Book One/
│ ├── 01 Intro.mp3
│ └── 02 Chapter.mp3
└── Book Two/
├── 01 Intro.flac
└── 02 Chapter.flac
audiobook-build batch Library \
--one-subfolder-per-book \
--author "A. Narrator"
Numbered groups in one flat folder
Files beginning with the same number become one audiobook. This is useful when a series was exported into a single directory:
01 Earthsea Book 1 01.mp3
01 Earthsea Book 1 02.mp3
02 Earthsea Book 2 01.mp3
02 Earthsea Book 2 02.mp3
audiobook-build batch Series --author "A. Narrator"
Batch output defaults to the parent of the input directory. Use --out-dir, --jobs, --skip-existing, or --force to control larger runs. Run with --dry-run first to inspect the grouping and output names without encoding.
Command reference
audiobook-build build DIRECTORY --author TEXT [OPTIONS]
--title, -t TEXT Audiobook title; inferred from the first filename
--out, -o PATH Output file; .m4b is added automatically
--bitrate TEXT AAC bitrate (default: 96k)
--encoder TEXT auto, aac, or aac_at (default: auto)
--cover, -c FILE JPEG or PNG artwork
--dry-run Inspect tracks without encoding
--force, -f Overwrite an existing output
audiobook-build batch ROOT --author TEXT [OPTIONS]
--out-dir, -o PATH Output directory; defaults to ROOT's parent
--one-subfolder-per-book
Treat each immediate child directory as one book
--title-template TEXT Use {n} for the detected group or folder name
--jobs, -j INTEGER Parallel encodes; 0 selects automatically
--skip-existing Keep outputs that already exist
--force, -f Overwrite without prompting
--cover FILE Apply one cover to every output
--dry-run Show the batch plan without encoding
Run audiobook-build COMMAND --help for the authoritative option list.
Verify an output
Inspect the container metadata and chapter boundaries with FFprobe:
ffprobe -v error \
-show_entries format_tags=title,artist,genre:chapter=start_time,end_time:chapter_tags=title \
-of json "The_Long_Way_Home.m4b"
A successful file reports AAC audio, the requested metadata, and one contiguous chapter per source track.
How it works
- Discover supported files in the selected folder and sort their names naturally.
- Remove byte-for-byte duplicates while preserving the first occurrence.
- Read each duration with FFprobe and generate FFMETADATA chapter boundaries.
- Concatenate and encode the tracks to AAC in a temporary
.m4b. - Attach optional cover art and atomically move the completed file into place.
All media processing is performed locally. AudiobookBuilder does not upload audio or contact an external service.
Troubleshooting
ffmpeg and ffprobe were not found
Install FFmpeg with brew install ffmpeg. If you keep custom binaries elsewhere, point AudiobookBuilder to their directory:
export AUDIOBOOK_FFMPEG_DIR="/path/to/ffmpeg/bin"
The directory must contain executable files named ffmpeg and ffprobe.
The output title is not what I expected
Pass --title for a single book or --title-template 'Series {n}' for a batch.
Books shows no cover
Use a JPEG or PNG file with --cover. Square artwork around 1400–3000 px is the most reliable choice.
Encoding is using too much CPU
For a batch, reduce concurrency with --jobs 1 or another explicit value.
Limitations
- macOS and Apple Books are the supported v1 target.
- Input discovery is intentionally limited to immediate MP3, M4A, WAV, and FLAC files.
- MP4/MOV video extraction, DRM-protected media, tag-based track ordering, and cue sheets are not supported.
- Audio is re-encoded to AAC for consistent
.m4bcompatibility; this is not a lossless remuxer.
Development
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
ruff check .
ruff format --check .
pytest
See CONTRIBUTING.md for the complete contributor workflow and CHANGELOG.md for release history.
License
AudiobookBuilder is available under the MIT License.
Metadata
Release files for audiobook-builder 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| audiobook_builder-1.0.0.tar.gz | 21.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| audiobook_builder-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.7 kB
Release files / audiobook_builder-1.0.0.tar.gz
| Download URL | audiobook_builder-1.0.0.tar.gz |
|---|---|
| Size | 21.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c41785646e2c94ae3a80e4d9793dd41c72f98c080c4e4b6f216365a915fce29
|
|
BLAKE2b-256 checksum How to use checksums |
63a2a598bf818ff0c1d8d40da309448ce1bf7fa3ccb5d899d973fd2e1a61e45f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.
Transparency logRelease files / audiobook_builder-1.0.0-py3-none-any.whl
| Download URL | audiobook_builder-1.0.0-py3-none-any.whl |
|---|---|
| Size | 16.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
814376ca3bac9c0fee9ba12ed274b9b716be695947c4bf32ecea9b4bb8c24a16
|
|
BLAKE2b-256 checksum How to use checksums |
7d448716969fac271a17d29c41be7c4519cbbb5655f68bd4dd77d797aa034093
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.
Transparency log