Add live transcription progress and Docker Whisper.

Surface stage, percent, and elapsed time while jobs run, and ship Compose so local confidential transcription can use faster-whisper on port 8090.
This commit is contained in:
ben
2026-08-12 14:32:56 +02:00
parent 67c1941833
commit e0400aadef
14 changed files with 695 additions and 177 deletions
+49 -11
View File
@@ -1,18 +1,19 @@
# AndyTranscribe
Upload pocket-recorder MP3s, extract ID3 metadata, and transcribe them with OpenAI Whisper, a local faster-whisper server, or a remote OpenAI-compatible endpoint.
Upload pocket-recorder audio (MP3, WAV, OGG, and more), extract embedded metadata, and transcribe with OpenAI Whisper, a local faster-whisper server, or a remote OpenAI-compatible endpoint.
Built with Laravel 13, Blade, Tailwind CSS 4, and [Laravel AI](https://github.com/laravel/ai).
## Features
- Upload MP3s (up to 100 MB) and store them on the local disk
- Automatic ID3 metadata extraction (title, artist, album, duration, recorded date)
- 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 transcription with three engines:
- **Cloud** — OpenAI Whisper (`whisper-1`)
- **Local** — confidential; OpenAI-compatible [faster-whisper-server](https://github.com/fedirz/faster-whisper-server) (e.g. Docker on this machine)
- **Local** — confidential; OpenAI-compatible [faster-whisper-server](https://github.com/fedirz/faster-whisper-server) via Docker
- **Ollama host** — user-supplied host URL exposing `/v1/audio/transcriptions`
- Live transcription progress (stage, %, elapsed time)
- Copy finished transcripts from the recording detail page
## Requirements
@@ -21,9 +22,9 @@ Built with Laravel 13, Blade, Tailwind CSS 4, and [Laravel AI](https://github.co
- Composer
- Node.js & npm
- SQLite (default) or another supported database
- For cloud transcription: an OpenAI API key
- For local transcription: a running faster-whisper-server
- For remote transcription: a host with an OpenAI-compatible transcription API
- For **cloud** transcription: an OpenAI API key
- For **local** transcription: [Docker](https://docs.docker.com/get-docker/) (runs Whisper in a container)
- For **remote** transcription: a host with an OpenAI-compatible transcription API
## Setup
@@ -45,6 +46,36 @@ npm install
npm run build
```
## Local Whisper (Docker)
The **Local** engine does not run Whisper inside PHP. It calls an OpenAI-compatible HTTP API. This project ships Compose for that:
```bash
# CPU (works everywhere; slower on long files)
docker compose up -d whisper
# Optional: NVIDIA GPU
docker compose --profile gpu up -d whisper-gpu
```
First start downloads the model into a Docker volume (can take a few minutes).
Check it:
```bash
curl -s http://127.0.0.1:8090/health
```
Laravel talks to it at `LOCAL_WHISPER_URL` (default `http://127.0.0.1:8090/v1`). Port **8090** is used so it does not conflict with `php artisan serve` on 8000.
Stop:
```bash
docker compose down
```
Without this container, **Cloud** and **Ollama host** still work; only **Local** needs Docker.
## Configuration
Copy values from `.env.example`. The transcription-related settings are:
@@ -53,10 +84,11 @@ Copy values from `.env.example`. The transcription-related settings are:
| --- | --- |
| `OPENAI_API_KEY` | Required for cloud Whisper |
| `OPENAI_URL` | OpenAI API base URL (default `https://api.openai.com/v1`) |
| `LOCAL_WHISPER_URL` | Local faster-whisper base URL (default `http://localhost:8000/v1`) |
| `LOCAL_WHISPER_URL` | Local faster-whisper base URL (default `http://127.0.0.1:8090/v1`) |
| `LOCAL_WHISPER_API_KEY` | API key for local server (often unused) |
| `LOCAL_WHISPER_MODEL` | Model name for local transcription |
| `REMOTE_WHISPER_MODEL` | Model name for Ollama-host transcription |
| `WHISPER_HOST_PORT` | Host port published by Compose (default `8090`) |
| `TRANSCRIPTION_TIMEOUT` | Job/HTTP timeout in seconds (default `600`) |
| `QUEUE_CONNECTION` | Use `database` (default) so transcription runs in the background |
@@ -70,6 +102,12 @@ Start the app, queue worker, and Vite together:
composer run dev
```
For confidential local transcription, also start Whisper:
```bash
docker compose up -d whisper
```
Or separately:
```bash
@@ -84,9 +122,9 @@ Transcription jobs are queued — keep a queue worker running or jobs will stay
## Usage
1. **Upload** an MP3 from Recordings → Upload (optional title override).
1. **Upload** audio from Recordings → Upload (optional title override).
2. Open the recording and choose a transcription engine.
3. Wait for the queue job to finish, then refresh to view or copy the transcript.
3. Watch live progress on the recording page until the transcript appears.
4. Search the list by title, artist, or transcript text.
## Transcription engines
@@ -94,7 +132,7 @@ Transcription jobs are queued — keep a queue worker running or jobs will stay
| Driver | When to use | Needs |
| --- | --- | --- |
| `cloud` | Fastest path; audio leaves your machine | `OPENAI_API_KEY` |
| `local` | Confidential; audio stays on this machine | faster-whisper-server at `LOCAL_WHISPER_URL` |
| `local` | Confidential; audio stays on this machine | `docker compose up -d whisper` |
| `ollama` | Another machine on your network | Host URL + OpenAI-compatible `/v1/audio/transcriptions` |
## Tests