3.6 KiB
Aletheia audiobook receiver for VoiceStudio on CMP
The receiver accepts EPUB and FB2, stores persistent jobs and device credentials,
extracts text, and sends it to the existing VoiceStudio /audiobook API.
VoiceStudio runs on three GPUs and uses the saved Russian narrator db7928a3.
The receiver does not load TTS models or manage other inference services.
Deployment
- Receiver:
/home/sevenhill/apps/aletheia-audiobook/service - Python:
/home/sevenhill/apps/VoiceStudio/.venv/bin/python - State:
/home/sevenhill/apps/aletheia-audiobook/audiobook-jobs/jobs.db3 - VoiceStudio:
http://127.0.0.1:3900, outputs in~/voicestudio-data/outputs - Public API:
https://argus.kusoft.xyz/aletheia-tts/ - User unit:
aletheia-audiobook-cmp.service, port 8765
Copy service Python files and the unit, then run systemctl --user daemon-reload
and systemctl --user enable --now aletheia-audiobook-cmp. User lingering enables
startup without an SSH session. Back up the SQLite database before upgrades.
The Pi Caddy route strips /aletheia-tts/ and proxies to CMP port 8765.
aletheia-audio-cleanup.service runs audio_cleanup.py independently, so it can
be deployed while a book is rendering. Android acknowledges delivery with DELETE
only after saving the M4A; a SQLite trigger retains that acknowledgement across
restarts. The cleaner removes the corresponding VoiceStudio M4B, work directory
and chapter WAVs, plus old disposable segment cache when all renderers are idle.
Models, voice profiles and other finished books are retained. New jobs record the
exact VoiceStudio output before becoming ready; an already-running legacy worker
is matched by SHA-256 while its output is being delivered. Unknown matches are
retained rather than guessing which book to delete.
The health endpoint checks VoiceStudio availability. Device enrollment is required:
run manage_devices.py pair with the service Python, then enter the single-use code
in Aletheia Settings → «Подключить аудиосервис». Codes normally expire in ten minutes.
Credentials are independent per device; job status, file and deletion check ownership.
Use manage_devices.py list and manage_devices.py revoke DEVICE_ID for revocation.
Processing and progress
Android checks availability before resetting a book and uploading it. The receiver
consumes VoiceStudio chapter/assembly events and exposes progress through job status.
Long EPUB/FB2 sections are split at sentence/word boundaries into parts of at most
1600 characters. Each free GPU immediately takes the next part from a shared queue;
it never waits for the other two GPUs to finish a batch. Progress events are sent
after each part and counted by completed text length. Repeated events from GPU
rendering and assembly are counted once. The deployed scheduler and regression
test are mirrored in cmp/ and installed in VoiceStudio's backend/services/
and cmp/ directories respectively.
VoiceStudio's M4B MP4/AAC container is copied as M4A, preserving chapter metadata.
The app downloads it to persistent storage and reports 100% only after saving it.
Jobs interrupted by a receiver restart are requeued; VoiceStudio reuses its chapter cache. Cancellation is checked between stream events; a chapter already rendering can finish before the cancellation is observed. VoiceStudio keeps its own output/cache.
Verification
Run python -m unittest discover -s server/audiobook -p 'test_*.py' -v.
smoke_live.py, run on CMP, performs real EPUB upload, VoiceStudio synthesis and
public M4A download with a disposable device, then revokes it. Set
AUDIOBOOK_SMOKE_FORMAT=fb2 for the same test with FB2. Unit tests mock synthesis.