Smart Audiobook Library Organizer with Multi-Source Metadata & AI Verification
Automatically fix messy audiobook folders using real book databases + AI intelligence
beta.115 - 🔒 HMAC Request Signing (Issue #119)
- Cryptographic Signatures - All Skaldleita API requests now signed with HMAC-SHA256
- Prevents Unauthorized Use - Requests without valid signatures are rejected
- Timestamp Protection - Replay attacks blocked via time-based validation
beta.114 - 🔐 Secure API Key Registration (Issue #117)
- Email-Only Delivery - API keys no longer shown on screen, sent to email only
- Prevents Key Theft - Someone who knows your email can't see your key
- Auto-Applied - Key is still saved automatically, just not displayed
beta.113 - 🔑 In-App Skaldleita Registration (Issue #115)
- Register from Settings - Get your API key directly in Library Manager
- Instance ID - Unique
SKALD-XXXXXXidentifier for your installation- Key Validation - Verify your key works with one click
- Rate Limits - 1000 req/hr with key, 500 without
beta.112 - ✅ File Validation Module (Issue #110)
- Pre-rename Checks - Validates files before attempting renames
- Path Safety - Checks for invalid characters, path length limits
- Better Errors - Clear messages when files can't be renamed
beta.111 - 🎯 Precog Consensus Voting (Issue #102)
- Multi-Source Voting - Audio, metadata, API, and AI sources vote on book identity
- Weighted Consensus - Audio (90) > Metadata (80) > API (70) > AI (55) > Path (30)
- Generic Title Protection - Ambiguous titles require 85% consensus instead of 70%
- Human Review Flags - Split votes and drastic changes flagged for review
beta.110 - 📊 Enhanced Status Bar (transparency for users)
- Know Your APIs - Status bar shows exactly which API is processing your books
- FREE Badge - Green badge shows when using free APIs (Skaldleita, Ollama) vs your quota
- Current Step - See "Transcribing audio...", "Querying database...", "Verifying with AI..."
- Provider Icons - Soundwave for Skaldleita, stars for Gemini, PC for Ollama
- Crash Fix - Truncated author names like "James S. A" no longer crash
{author_last}template
beta.109 - 🛡️ AI Hallucination Prevention (Issue #79)
- Generic Title Protection - Titles like "Match Game", "The Game", "Home" no longer get fake authors
- AI prompts now warn about ambiguous titles and require reasoning
- Validation flags "generic title + no author" as low confidence
- Better to return null than invent "Doc Raymond" for a Craig Alanson book
beta.108 - 🎯 Author Format & Duplicate History Fix (Issues #96, #88, #79)
- Author Name Templates - New
{author_lf}(LastName, FirstName),{author_last},{author_first}for custom naming- Database Cleanup Button - Settings → Advanced now has button to remove @eaDir, #recycle entries
- Duplicate History Fix - Centralized insert function prevents same book appearing 15x in history
- All 16 INSERT paths now use deduplication helper - finally kills the duplicate bug
beta.107 - 🔧 Series Path Fix (Issue #94)
- Series Number Without Name - Custom naming templates no longer create broken paths
- Template
{author}/{series}/{series_num} - {title}now falls back correctly when series is missing- Previously created paths like
Author/01 - Title, now properly omits orphan numbers
beta.106 - 🧹 Title Cleanup (Issue #92)
- Strip "Unabridged" Toggle - New option removes
(Unabridged)from titles- Garbage Prevention - Validation rejects bad author/title suggestions before saving
beta.105 - 📚 ISBN Lookup (Issue #67)
- Ebook ISBN Extraction - Extracts ISBN from EPUB, PDF, MOBI metadata for better matching
- New BookDB endpoint for direct ISBN lookup
beta.104 - 🔧 Synology @eaDir Fix (Issue #88)
- Accurate Dashboard Counts - Pending/fixed/error counts now match actual items
- No More Duplicate History - Fixed entries no longer accumulate duplicates
- Request Tracking - API requests now identify Library Manager version
beta.102 - 🎨 UI Theming System & Bug Fixes (Issue #86)
- Theme Selector - Switch between Default and Skaldleita (Norse-inspired) themes
- Theme Persistence - Theme no longer resets when navigating between pages
- Pyannote Fix - No more "No module named 'pyannote'" warnings at startup
- Worker Crash Fix - Queue processing no longer crashes on malformed AI responses
beta.101 - 🌍 Multi-Language Audiobook Naming (Issue #81)
- Three Naming Modes - Native (keep original language), Preferred (translate all), Tagged (add language labels)
- Flexible Tagging - Four formats
(Polish),[pl],Polish,_pl+ three positions (after/before title, subfolder)- Custom Templates - New
{language}and{lang_code}tags for full control- Polish Language Fix - Strict language matching now works correctly for all 28 supported languages
beta.100 - 📊 Dashboard Activity Log & Skaldleita IDs
- Real-time Activity Log - See processed books with full metadata on dashboard
- Skaldleita IDs - Audio fingerprints and narrator IDs embedded in files
- Extended Metadata - Enables instant identification when files are shared/moved
beta.99 - 👁️ Live Status Bar - See what's happening in real-time!
- Persistent Status Bar - Always visible below navbar on every page
- Current Book Display - Shows author/title of book being processed
- Layer Indicator - See which processing stage is active (Audio, AI, API, Fallback)
beta.97 - 🔍 Series Mismatch Detection & SearXNG Fallback (Issues #76, #77)
- Series Mismatch Fix - Books with series info now correctly reject wrong matches
- SearXNG Fallback - New web search provider when APIs fail (Amazon, Audible, Goodreads parsing)
- Whisper Setting Fix - Speech-to-Text model selection now saves correctly
beta.96 - 🐛 Watch Folder Duplicates Fix (Issue #76)
- Atomic Directory Move - Prevents partial moves creating "Version B" folders
- Partial Move Detection - Completes interrupted moves instead of duplicating
beta.95 - 🔧 Major Code Refactoring
- 32% Code Reduction -
app.pyreduced from 15,491 to 10,519 lines- Modular Architecture - New
library_manager/package with organized modules
beta.94 - 🐛 Bug Fixes (Issues #64, #71, #74)
- Queue Hanging Fix - Circuit breaker now properly advances queue when providers fail (#74)
- Community Toggle - "Contribute to Community" setting now saves correctly (#71)
- Whisper Install - Docker permission error fixed (#63)
- API Key Visibility - Keys now shown in settings (hidden by default, eye toggle reveals)
- Apply All Fix - History entries now store paths to prevent "Source no longer exists" errors
- Dashboard Counts - Fixed inflated counts by excluding series folders from totals
- Title Cleaning - Strips torrent naming junk (bitrates, timestamps, editor names, year prefixes)
beta.93 - 🌐 P2P Cache & Resilience (Issue #62)
- P2P Book Cache - Optional decentralized cache shares BookDB results with other users
- Helps During Outages - Get results from P2P network when BookDB is temporarily down
- Opt-in & Private - Disabled by default, only metadata shared (no file paths)
- BookDB Retry Logic - 5 retries with backoff when no fallback configured
- Data Validation - Rejects malformed/malicious P2P cache entries
beta.92 - 🔒 Security & Stability
- Confidence Threshold - Books only marked "verified" when confidence ≥40%, prevents false positives
- API Keys Hidden - Keys no longer exposed in HTML source, shows "Key configured" instead
- Issue #59 Complete Fix - Placeholder authors ("Unknown Author") now detected during scan
- Issue #63 Fix - Docker Whisper install permission error resolved
- BookDB Stability - Circuit breaker for rate limiting, improved multi-user fairness
- Layer 2 Recovery - Stuck items now properly advanced when Layer 2 disabled
beta.92 - 🎧 Audio-First Identification (Major Feature)
- Revolutionary Approach - Now identifies books from narrator introductions FIRST
- 52% Identification Rate - Half of books identified from audio alone in Layer 1
- 4-Layer Pipeline - Audio transcription → AI parsing → API enrichment → Folder fallback
- faster-whisper Integration - Local, free speech-to-text via Python venv
- Known Narrator Detection - Prevents AI from confusing narrators with authors
beta.90 - 🎯 Layer 4 Content Analysis (Major Feature)
- The Final Layer - Transcribes actual story content to identify books when all else fails
- Whisper + OpenRouter Fallback - Local transcription + free AI when Gemini unavailable
- No GPU Required - faster-whisper runs on CPU, model downloads automatically
beta.89 - Watch Folder Reliability (Issue #57)
- Track number stripping, local BookDB support, confidence threshold fix
beta.87-88 - Watch Folder Verification & Scan Locking (Issues #57, #59-61)
- API result verification, parent folder hints, concurrent scan fix, password toggles
beta.84-86 - Status & Output Fixes (Issues #57, #59)
- Placeholder author detection, output folder routing, author initials standardization
beta.78-83 - SQLite Locking, Setup Wizard, Orphan Organization
- 3-phase processing, first-run wizard, duplicate detection fix
beta.72-77 - Multi-Edit, Media Filters, Author Initials
- Edit all queue items, media type filter, "J R R Tolkien" → "J. R. R. Tolkien"
Audiobook libraries get messy. Downloads leave you with:
Your Library (Before):
├── Shards of Earth/Adrian Tchaikovsky/ # Author/Title swapped!
├── Boyett/The Hollow Man/ # Missing first name
├── Metro 2033/Dmitry Glukhovsky/ # Reversed structure
├── [bitsearch.to] Dean Koontz - Watchers/ # Junk in filename
├── The Great Gatsby Full Audiobook.m4b # Loose file, no folder
└── Unknown/Mistborn Book 1/ # No author at all
Library Manager combines real book databases (50M+ books) with AI verification to fix your library:
Your Library (After):
├── Adrian Tchaikovsky/Shards of Earth/
├── Steven Boyett/The Hollow Man/
├── Dmitry Glukhovsky/Metro 2033/
├── Dean Koontz/Watchers/
├── F. Scott Fitzgerald/The Great Gatsby/
└── Brandon Sanderson/Mistborn/1 - The Final Empire/
- Works backwards from audio files to understand folder structure
- Database-backed author/series detection (50M+ books)
- Fuzzy matching ("Dark Tower" finds "The Dark Tower")
- AI fallback for ambiguous cases
- Safe fallback - connection failures don't cause misclassification
Layer 1: Audio Transcription + AI Parsing (Most Reliable)
Transcribes 45-second intro → AI extracts author/title/narrator
✓ 52% of books identified from audio alone
Layer 2: AI Audio Analysis (Deeper Analysis)
Sends audio directly to Gemini for unclear transcripts
Layer 3: API Enrichment (Add Metadata)
BookDB → Audnexus → OpenLibrary → Google Books → Hardcover
Layer 4: Folder Name Fallback (Last Resort)
Uses folder structure when audio identification fails
Works even when file has zero metadata or intro credits
Each layer only runs if the previous layer couldn't confidently identify the book.
- Drastic changes require approval - author swaps need manual review
- Garbage match filtering - rejects unrelated results (<30% similarity)
- Undo any fix - every rename can be reverted
- Structure reversal detection - catches Metro 2033/Author patterns
- System folders ignored - skips
metadata,cache,@eaDir, etc.
Brandon Sanderson/Mistborn/1 - The Final Empire/
Brandon Sanderson/Mistborn/2 - The Well of Ascension/
James S.A. Corey/The Expanse/1 - Leviathan Wakes/
Build your own folder structure:
{author}/{title} → Brandon Sanderson/The Final Empire/
{author}/{series}/{series_num} - {title} → Brandon Sanderson/Mistborn/1 - The Final Empire/
{author} - {title} ({narrator}) → Brandon Sanderson - The Final Empire (Kramer)/
{author}/{language}/{title} → Dmitry Glukhovsky/Russian/Metro 2033/
{author}/{title} [{lang_code}] → Antoine de Saint-Exupéry/Le Petit Prince [fr]/
- 28 languages - German, French, Spanish, Italian, Portuguese, Dutch, Swedish, Norwegian, Danish, Finnish, Polish, Russian, Japanese, Chinese, Korean, Arabic, Hebrew, Hindi, Turkish, Czech, Hungarian, Greek, Thai, Vietnamese, Ukrainian, Romanian, Indonesian
- Multi-language naming - intelligent folder naming based on detected book language:
- Native mode - Russian books get Russian titles, English books get English titles
- Preferred mode - all books named in your preferred language
- Tagged mode - preferred language + language tag ("Metro 2033 (Russian)")
- Flexible tagging - four formats
(Polish),[pl],Polish,_pl+ subfolder option - Preserve original titles - keeps "Der Bücherdrache" instead of translating to English
- Regional Audible search - queries audible.de, audible.fr, etc. for localized results
- Audio language detection - use Gemini to detect spoken language in audiobooks
- Web dashboard with dark theme
- Watch folder mode - monitor downloads folder, auto-organize new audiobooks
- Manual book matching - search 50M+ database directly
- Edit & lock metadata - correct wrong matches, lock to prevent overwriting
- Library search - find any book by author or title
- Loose file detection - auto-creates folders for dumped files
- Ebook management (Beta) - organize ebooks alongside audiobooks with ISBN lookup
- Health scan - detect corrupt/incomplete audio files
- Audio analysis (Beta) - extract metadata from audiobook intros via Gemini
- In-browser updates - update from the web UI
- Backup & restore - protect your configuration
- Version-aware renaming - different narrators get separate folders
# Pull from GitHub Container Registry
docker run -d \
--name library-manager \
-p 5757:5757 \
-v /path/to/audiobooks:/audiobooks \
-v library-manager-data:/data \
ghcr.io/deucebucket/library-manager:latestOr with Docker Compose:
version: '3.8'
services:
library-manager:
image: ghcr.io/deucebucket/library-manager:latest
container_name: library-manager
ports:
- "5757:5757"
volumes:
- /your/audiobooks:/audiobooks
- library-manager-data:/data
restart: unless-stopped
volumes:
library-manager-data:git clone https://github.com/deucebucket/library-manager.git
cd library-manager
pip install -r requirements.txt
python app.py- Open http://localhost:5757
- Go to Settings
- Add library path (
/audiobooksfor Docker, or your actual path) - Add AI API key (Gemini recommended - 14,400 free calls/day)
- Save and Scan Library
Docker containers are isolated. Mount your audiobook folder:
volumes:
- /your/audiobooks:/audiobooks # LEFT = host, RIGHT = container
- library-manager-data:/data # Persistent config/databaseUse /audiobooks (container path) in Settings.
| Platform | Volume Mount |
|---|---|
| UnRaid | /mnt/user/media/audiobooks:/audiobooks |
| Synology | /volume1/media/audiobooks:/audiobooks |
| Linux | /home/user/audiobooks:/audiobooks |
| Windows | C:/Users/Name/Audiobooks:/audiobooks |
See docs/DOCKER.md for detailed setup guides.
| Option | Default | Description |
|---|---|---|
library_paths |
[] |
Folders to scan |
naming_format |
author/title |
Folder structure |
series_grouping |
false |
Audiobookshelf-style series folders |
auto_fix |
false |
Auto-apply vs manual approval |
protect_author_changes |
true |
Require approval for author swaps |
scan_interval_hours |
6 |
Auto-scan frequency |
Google Gemini (Recommended)
- 14,400 free API calls/day
- Get key at aistudio.google.com
OpenRouter
- Multiple model options
- Free tier available
| Endpoint | Method | Description |
|---|---|---|
/api/scan |
POST | Trigger library scan |
/api/deep_rescan |
POST | Re-verify all books |
/api/process |
POST | Process queue items |
/api/queue |
GET | Get queue |
/api/library |
GET | Get library with filters |
/api/stats |
GET | Dashboard stats |
/api/apply_fix/{id} |
POST | Apply pending fix |
/api/reject_fix/{id} |
POST | Reject suggestion |
/api/undo/{id} |
POST | Revert applied fix |
/api/edit_book |
POST | Edit & lock book metadata |
/api/unlock_book/{id} |
POST | Unlock book for reprocessing |
/api/analyze_path |
POST | Test path analysis |
Wrong author detected? → Go to Pending → Click Reject (✗)
Want to undo a fix? → Go to History → Click Undo (↩)
Series not detected? → Enable Series Grouping in Settings → General
Docker can't see files? → Check volume mounts in docker-compose.yml
# Full integration test suite (pulls from ghcr.io)
./test-env/run-integration-tests.sh
# Build from local source instead
./test-env/run-integration-tests.sh --local
# Rebuild 2GB test library first
./test-env/run-integration-tests.sh --rebuildpython app.py # Runs on http://localhost:5757We take testing seriously. Every release is validated against real-world chaos scenarios.
Before every release, we test against a 500-book "chaos library" - a nightmare collection designed to break the app:
| Chaos Type | Example | What We're Testing |
|---|---|---|
| Wrong Author | Stephen King - The Martian |
Can we detect misattribution? |
| Narrator as Author | Ray Porter - Project Hail Mary |
Common audiobook mistake |
| Swapped Fields | The Final Empire - Brandon Sanderson |
Structure reversal detection |
| Foreign Characters | Nick Offerman - 罪と罰 |
Unicode handling |
| Heavy Typos | Nil Gaiman - Annsi Boys |
Fuzzy matching resilience |
| Torrent Prefixes | [MAM] Dean Koontz - Watchers (2021) |
Junk stripping |
| Missing Info | Audiobook_574 |
Identification from nothing |
| Wrong Series Number | Mistborn Book 15 - The Final Empire |
Series validation |
| Mixed Languages | Харуки Мураками - Dune |
Cross-language chaos |
The chaos library uses symlinks to real audiobook files (166GB represented, ~0 disk usage), so we're testing with actual audio content - not just filename patterns.
Every GitHub issue becomes a test case. When users report bugs, we:
- Reproduce the exact scenario
- Fix the underlying issue
- Add a test that catches this specific case
- Run tests before every commit to ensure we never revert fixes
Our test suite (test-env/test-naming-issues.py) currently validates 184+ edge cases derived from real user issues:
# Run naming/path edge case tests
python test-env/test-naming-issues.py
# Example output:
# --- Issue #57: Watch folder verification ---
# [PASS] Watch folder verifies drastic author changes
# [PASS] Watch folder detects same-title-different-author
# --- Issue #60: Password visibility toggles ---
# [PASS] templates/settings.html has togglePasswordVisibility
# ...
# RESULTS: 184 passed, 0 failedBefore pushing any changes, we run:
- Syntax check -
python -m py_compile app.py - Regression tests - All 184+ edge cases
- Code review - Adversarial review of changes
- Security audit - Check for common vulnerabilities
- Chaos library scan - Full 500-book identification test
This project wouldn't be what it is without the community. Special thanks to:
The idea for Skaldleita (audio fingerprinting + narrator voice identification) came from Merijeek's suggestion in Issue #72 about MAM hashing. His vision of "Shazam for audiobooks" became the foundation for Skaldleita - instant audiobook identification via voice fingerprints. Beyond that, his thorough testing on the :develop branch has caught countless edge cases and made Library Manager far more robust. His blunt feedback pushes the project to be better.
- Dennis - Remote Pi testing, ARM/low-resource environment validation
- WickedT53 - BookDB stability testing, Unraid platform support
- greggh - UI bug reports, Docker testing
- freitagdavid - Code quality feedback
- Chromaprint/fpcalc - Audio fingerprinting technology
- faster-whisper - Speech-to-text transcription
- WeSpeaker - Voice embedding models for narrator identification
Pull requests welcome! Ideas:
- Ollama/local LLM support
- Cover art fetching
- Metadata embedding (added in v0.9.0-beta.20)
- Movie/music library support
- Issues/Bugs: GitHub Issues
- Email: hello@deucebucket.com
AGPL-3.0 License - See LICENSE for details.
What this means:
- Free to use, modify, and distribute
- If you modify and run this as a service, you must release your source code
- Commercial use requires either open-sourcing your changes OR obtaining a commercial license