Update validation, dropzone checks, Docker PHP ini, and docs so multi-hour recordings can be uploaded.
AndyTranscribe
Upload pocket-recorder audio (MP3, WAV, OGG, and more), extract embedded metadata, and transcribe locally with faster-whisper-server via Docker. Audio never leaves your machine.
Built with Laravel 13, Blade, Alpine.js, Tailwind CSS 4, Laravel Reverb, FrankenPHP, and Laravel AI.
Features
- Upload common audio formats (MP3, WAV, OGG, FLAC, M4A, AAC, WebM, WMA, AIFF — up to 2 GB)
- Automatic metadata extraction when tags are present (title, artist, album, duration, recorded date)
- Search recordings by title, artist, or transcript
- Queued local transcription (faster-whisper in Docker)
- Live transcription progress over WebSockets (Reverb) on the list and detail pages
- Stop or restart a run anytime
- Copy finished transcripts from the recording detail page
Requirements
- Docker and Docker Compose (primary way to run the app)
- For native PHP development: PHP 8.3+ (8.5 recommended), Composer, Node.js & npm, SQLite
Quick start (Docker + FrankenPHP)
cp .env.example .env
# Set a key (required by the app container):
php artisan key:generate # or: docker run --rm -v "$PWD":/app -w /app composer:2 php artisan key:generate
docker compose up --build
Open http://localhost:8080/recordings.
| Service | Host port | Role |
|---|---|---|
app |
8080 |
FrankenPHP (Laravel) |
reverb |
8081 |
WebSockets for live status |
whisper |
8090 |
faster-whisper API |
queue |
— | queue:work for transcription jobs |
Persistent data mounts
These host directories are bind-mounted into app, queue, and reverb:
| Host path | Container path | Contents |
|---|---|---|
./database |
/app/database |
SQLite database |
./storage/app |
/app/storage/app |
Uploaded audio (private/recordings) |
./storage/logs |
/app/storage/logs |
Application logs |
Whisper model cache uses the named volume whisper-huggingface-cache.
GPU Whisper (optional)
docker compose --profile gpu up -d --build
Point LOCAL_WHISPER_URL at the GPU service if you run it instead of the CPU whisper service.
Useful Compose env
Copy values from .env.example. Important Docker-oriented variables:
| Variable | Purpose |
|---|---|
APP_KEY |
Required — containers refuse to start without it |
APP_URL |
Default http://localhost:8080 |
APP_HOST_PORT |
Host port for FrankenPHP (default 8080) |
REVERB_HOST_PORT |
Host port for Reverb WebSockets (default 8081) |
WHISPER_HOST_PORT |
Host port for Whisper (default 8090) |
REVERB_APP_* |
Reverb credentials (baked into frontend at image build for VITE_REVERB_*) |
LOCAL_WHISPER_MODEL |
Model name for local transcription |
TRANSCRIPTION_TIMEOUT |
Job/HTTP timeout in seconds (default 600) |
Inside Compose, Laravel talks to Whisper at http://whisper:8000/v1 and publishes broadcasts to the reverb service. The browser connects to Reverb on localhost:8081.
Stop:
docker compose down
Native PHP development (optional)
composer setup
docker compose up -d whisper reverb
# In separate terminals:
php artisan serve --port=8000
php artisan queue:work
php artisan reverb:start
npm run dev
Set APP_URL=http://localhost:8000, LOCAL_WHISPER_URL=http://127.0.0.1:8090/v1, and Reverb REVERB_HOST=localhost / REVERB_PORT=8080 (match VITE_REVERB_*).
Configuration
Finished transcripts are stored on the recording (transcript column) and are included in the recordings search box (title, artist, album, filename, and transcript).
DB_QUEUE_RETRY_AFTER must exceed TRANSCRIPTION_TIMEOUT so long Whisper jobs are not re-queued mid-run.
Usage
- Upload audio from Recordings → Upload (single file or batch dropzone).
- Transcription queues automatically — the Compose
queueservice (orphp artisan queue:work) must be running. - Watch live progress on the recordings list or detail page (Reverb); stop and restart anytime.
- Search the list by title, artist, or transcript text.
- If older uploads still show Queued with no progress, use Queue pending transcriptions on the recordings list.
Tests
composer test
# or
php artisan test
License
MIT