Skip to content

About

No description, website, or topics provided.

Resources

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Local Transcription

License: MIT

App screenshot

A local-first audio transcription and analysis pipeline. All processing happens on your machine — no cloud APIs, no data leaving your system.

What this project is

This is a Rust workspace that bundles a desktop GUI and a CLI tool for transcribing audio and video. It uses whisper.cpp for speech recognition, pyannote for speaker diarization, yt-dlp for downloading from URLs, and Ollama for AI-powered summarization — all running locally.

Workspace layout

apps/cli/               — Command-line interface (transcribe, diarize, verify)
apps/desktop/           — Tauri desktop app (GUI)
crates/transcription-core/  — Shared pipeline logic
scripts/                — Build helpers for whisper.cpp

Features

Transcription

  • Local speech-to-text via whisper.cpp (GPU-accelerated with ROCm/HIP or CUDA)
  • Supports audio files (MP3, MP4, WAV, M4A, OGG, FLAC, WebM) and YouTube/web URLs via yt-dlp
  • Configurable audio quality and language
  • Inline transcript editing in the desktop app

Speaker diarization

  • Identifies who spoke when using pyannote speaker diarization
  • Configurable speaker count
  • Speaker name assignment in the desktop UI

AI Summarization

  • Generates summaries from transcripts using a locally running Ollama model
  • Custom prompts and output language selection
  • Combine multiple transcripts into one summary
  • Streaming output in the desktop app

Desktop app

  • Drag-and-drop audio files or paste a URL
  • Audio playback with volume control
  • Tag-based organization
  • Copy transcript to clipboard
  • Per-job summaries with delete confirmation

Prerequisites

Install these before anything else. Each link points to the official documentation, which is the authoritative source for installation steps — they change between releases and differ by platform.

Tool Purpose Link
Rust (stable, ≥ 1.85) Build everything https://rustup.rs
Node.js + pnpm Desktop app frontend https://nodejs.org / https://pnpm.io
FFmpeg Audio normalization https://ffmpeg.org/download.html
yt-dlp YouTube/URL download https://github.com/yt-dlp/yt-dlp#installation
Python 3 + venv Diarization sidecar https://www.python.org
whisper.cpp Speech-to-text engine https://github.com/ggerganov/whisper.cpp
Ollama Local LLM for summaries https://ollama.com/download

Platform notes

These sections describe the general approach, not step-by-step instructions. GPU drivers, ROCm, CUDA, and WSL2 compatibility change frequently. Always refer to the official documentation for your specific OS version, GPU model, and driver version.

Linux (native)

The smoothest path. Install system dependencies via your package manager, build whisper.cpp with the GPU backend that matches your hardware (see GPU section below), and run directly.

Windows (native)

The simplest route is the installer built from WSL — see Windows installer. It ships a Vulkan build of whisper.cpp, which uses AMD, NVIDIA and Intel GPUs through the regular graphics driver. To build whisper.cpp natively instead (CUDA, ROCm-for-Windows), check the whisper.cpp build documentation — it changes as the project evolves.

For Ollama on Windows, download the installer from https://ollama.com/download. AMD GPU support on Windows goes through ROCm; NVIDIA goes through CUDA. If Ollama falls back to CPU, it may need environment variables set before the process starts — refer to the Ollama FAQ and GPU documentation for the current guidance.

WSL2 (Windows Subsystem for Linux)

Warning: GPU passthrough in WSL2 has significant limitations that are architecture- and driver-dependent. What works today may not reflect the current state of the project.

NVIDIA: CUDA passthrough via dxgkrnl is well-supported. Refer to the CUDA on WSL2 guide for setup.

AMD: ROCm GPU compute on WSL2 is more complex. AMD GPUs appear through the dxgkrnl paravirtualization driver but not through the standard KFD interface that ROCm expects. Support depends heavily on your GPU architecture, driver version, and ROCm version. Check the AMD ROCm documentation and WSL2 compatibility notes before investing time here.

Alternative for AMD on WSL2: Run Ollama natively on Windows (with full DirectML/ROCm GPU support) and access it from WSL2 over the virtual network interface. The Windows host is reachable from WSL2 at the default gateway IP, which you can find with:

ip route | grep default | awk '{print $3}'

Then set OLLAMA_BASE_URL=http://<that-ip>:11434 in your .env.


GPU notes

Warning: GPU architecture support in whisper.cpp and Ollama changes with every release. The information here reflects the state when this was written. Always check the upstream documentation for your GPU model before troubleshooting.

NVIDIA

Both whisper.cpp and Ollama have mature CUDA support. Build whisper.cpp with -DGGML_CUDA=ON. Ollama detects CUDA automatically if the driver and CUDA toolkit are installed.

AMD

ROCm support varies significantly by GPU architecture. Newer architectures (RDNA 3, RDNA 4) may not be in the pre-built kernels of a given whisper.cpp or Ollama release, requiring an architecture override (HSA_OVERRIDE_GFX_VERSION) to use a compatible fallback. This has performance and correctness implications.

For Ollama on Windows with AMD, Vulkan is an alternative backend that does not depend on ROCm and supports a broader range of GPU architectures. Set OLLAMA_VULKAN=1 before starting Ollama and check the Ollama GPU documentation for current status.


Configuration

Copy .env.example to .env and fill in the values. The file is gitignored.

# Path to ffmpeg (defaults to "ffmpeg" on PATH)
FFMPEG_PATH=ffmpeg

# whisper.cpp binary — build it for your GPU, see the section below
WHISPER_CLI=whisper.cpp-vulkan/build-linux-hip-clang/bin/whisper-cli
WHISPER_MODEL=models/whisper/ggml-large-v3-turbo.bin

# Output directory for all jobs
TRANSCRIPTION_OUTPUT_DIR=data/runs

# Whisper threads (tune to your CPU core count)
WHISPER_THREADS=8

# Hugging Face token (required for pyannote diarization)
HF_TOKEN=hf_...

# Optional — defaults to "yt-dlp" on PATH
# YTDLP_PATH=/path/to/yt-dlp

# Optional — defaults to http://localhost:11434
# OLLAMA_BASE_URL=http://localhost:11434

The .env file is never read by the shell. It is parsed by the Rust pipeline at startup. Do not use shell variable syntax like $(...) inside it.


Building whisper.cpp

Fetch the source (clones the upstream whisper.cpp repo into whisper.cpp-vulkan/, which is gitignored):

bash scripts/bootstrap_whisper_cpp.sh

Build for ROCm/HIP (AMD):

bash scripts/build_whisper_hip.sh

For other backends (CUDA, CPU, Vulkan), refer to the whisper.cpp build documentation and build manually. Point WHISPER_CLI in .env to the resulting binary.

You will also need a model file. The recommended starting point is ggml-large-v3-turbo. Download from Hugging Face and place it under models/whisper/.


Diarization setup

Install the Python dependencies into a virtualenv:

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-diarization.txt

Diarization uses pyannote, which requires accepting model terms on Hugging Face and a Hugging Face access token. See the pyannote access instructions.

In the desktop app, paste the token under Settings → Models → Hugging Face token. It is stored in the OS credential store (Windows Credential Manager, the macOS Keychain, or the Secret Service keyring on Linux), is never written to disk by the app, and cannot be read back into the UI — only replaced or removed. HF_TOKEN in .env or the environment still works as a fallback, and is what the CLI uses. WSL usually runs no Secret Service, so there the app reports that no credential store is available and .env remains the way to set it.


Ollama setup

Install Ollama from https://ollama.com/download and pull a model:

ollama pull qwen2.5:7b

The qwen2.5:7b model is a reasonable default (~4 GB). Larger models produce better summaries but require more VRAM. Any model available on ollama.com/library will work.

Set OLLAMA_BASE_URL in .env to wherever Ollama is listening.


Running the desktop app

On Linux, install the Tauri system dependencies first:

sudo apt-get install -y \
  libwebkit2gtk-4.1-dev \
  libgtk-3-dev \
  libayatana-appindicator3-dev \
  librsvg2-dev

Then:

cd apps/desktop
pnpm install
pnpm tauri dev

For a production build:

pnpm tauri build

Windows installer (built from WSL)

Builds a normal Windows setup .exe from WSL, so Windows needs no Rust, Node or project checkout. The installer bundles the app with:

  • whisper-cli.exe cross-compiled with the Vulkan backend (GPU through the regular driver; the build reads headers and vulkan-1.lib from the Windows Vulkan SDK under /mnt/c/VulkanSDK, override with WINDOWS_VULKAN_SDK)
  • ffmpeg.exe (gyan.dev essentials build) and yt-dlp.exe, at versions pinned and checksum-verified in scripts/build_windows_installer.sh
  • the Whisper model at models/whisper/ggml-large-v3-turbo.bin (override with WHISPER_MODEL_FILE)

Not bundled: Ollama — install it on Windows; the app talks to http://localhost:11434. Speaker diarization (Python + pyannote) — the toggle is disabled in the installed app.

One-time setup in WSL (plus cmake, ninja, glslc and pnpm, which the Linux build already uses). The MSVC C++ headers that cargo xwin downloads require Clang 19 or newer, and Ubuntu 24.04's default clang is 18, so install the versioned LLVM 20 packages (clang-cl lives in clang-tools-20):

sudo apt install -y nsis clang-20 clang-tools-20 lld-20 llvm-20
cargo install --locked cargo-xwin

Build:

bash scripts/build_windows_installer.sh

The setup file lands in target/x86_64-pc-windows-msvc/release/bundle/nsis/. It installs per user (no admin rights) into %LOCALAPPDATA%\Local Transcription; transcripts are stored in %APPDATA%\com.miguel.transcription-desktop\runs. That data folder and the saved Hugging Face token are keyed on the app identifier, so they survive a reinstall — keep identifier in tauri.conf.json unchanged. When uninstalling, leave "Delete the application data" unchecked unless you want the transcripts gone. The installer is unsigned, so Windows SmartScreen warns on first run (More info → Run anyway).

Notes:

  • cargo xwin downloads the MSVC CRT and Windows SDK, which come under Microsoft's license terms.
  • An NSIS installer cannot exceed 2 GiB, so one large model is the most it can carry. Compression is off: the model barely compresses and LZMA over ~1.8 GB takes a long time.
  • The installed app reads a .env from its install folder when one is present (for example WHISPER_THREADS=16).
  • The app icon is generated from apps/desktop/app-icon.svg: edit it, run pnpm tauri icon app-icon.svg in apps/desktop, then delete the android/, ios/ and 64x64.png outputs that desktop builds do not use.
  • The bundled yt-dlp ages as sites change; bump the pinned version and rebuild when URL downloads start failing.
  • The essentials ffmpeg build is GPL-licensed. That is fine for personal use; publishing the installer brings GPL obligations for ffmpeg.

Running the CLI

Verify environment. This checks required transcription tools, optional URL/diarization tools, detected hardware, and local Whisper models:

cargo run -p transcription-cli -- verify

Transcribe a file:

cargo run -p transcription-cli -- transcribe path/to/audio.mp3

Transcribe with diarization:

cargo run -p transcription-cli -- transcribe path/to/audio.mp3 --diarize --num-speakers 2

Transcribe a stereo call where each channel is one speaker (skips diarization):

cargo run -p transcription-cli -- transcribe path/to/call.mp4 --two-channel

Run diarization on an existing normalized WAV:

cargo run -p transcription-cli -- diarize data/runs/<job-id>/work/audio.wav --num-speakers 2

Output is written to data/runs/<job-id>/:

job.json
work/audio.wav
output/transcript.txt
output/transcript.srt
output/transcript.json
output/speakers.txt
output/speaker-transcript.txt

Security

This project is local-first and supports local/private model endpoints only. See SECURITY.md before changing endpoint validation, subprocess execution, file serving, export, or deletion behavior.

Development

cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace

Disclaimers

  • This project is a personal tool, not a polished product. Breaking changes can happen at any time.
  • GPU acceleration setup is environment-specific. What works on one machine may not work on another.
  • .env is local-only and gitignored. Never commit it — it contains API tokens and local paths.
  • Do not commit audio files, transcripts, model binaries, or Hugging Face tokens.
  • pyannote requires accepting license terms on Hugging Face before use.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages