# AndyTranscribe Upload pocket-recorder audio (MP3, WAV, OGG, and more), extract embedded metadata, and transcribe locally with [faster-whisper-server](https://github.com/fedirz/faster-whisper-server) via Docker. Audio never leaves your machine. Built with Laravel 13, Blade, Alpine.js, Tailwind CSS 4, [Laravel Reverb](https://laravel.com/docs/reverb), FrankenPHP, and [Laravel AI](https://github.com/laravel/ai). ## Features - Upload common audio formats (MP3, WAV, OGG, FLAC, M4A, AAC, WebM, WMA, AIFF — up to 100 MB) - 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](https://docs.docker.com/get-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) ```bash 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](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) ```bash 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: ```bash docker compose down ``` ## Native PHP development (optional) ```bash 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 1. **Upload** audio from Recordings → Upload (single file or batch dropzone). 2. Transcription queues automatically — the Compose `queue` service (or `php artisan queue:work`) must be running. 3. Watch live progress on the recordings list or detail page (Reverb); stop and restart anytime. 4. Search the list by title, artist, or transcript text. 5. If older uploads still show **Queued** with no progress, use **Queue pending transcriptions** on the recordings list. ## Tests ```bash composer test # or php artisan test ``` ## License MIT