Local-first CLI for transcribing webinar videos and audio recordings.
Project description
Webinar Transcriber
Contents
Overview
webinar-transcriber turns webinar recordings into transcripts, structured notes, diagnostics, and
machine-readable report artifacts. It accepts audio-only files and slide-based video. Video runs add
scene detection and representative frames; audio-only runs keep the same transcript and report
contract without visual context.
webinar-transcriber is local-first: speech detection, transcription, window reconciliation, and
report sectioning all run on your machine with local models and heuristics. Optional LLM refinement
runs only after that deterministic report exists; it polishes section text and refines titles,
summaries, action items, and section TL;DRs, but never replaces the base pipeline.
For per-stage detail and the artifact each stage produces, see docs/pipeline.md.
Install
Prerequisites
- Python 3.12+ and uv
Install from PyPI
Install the published package as a standalone CLI:
uv tool install webinar-transcriber
Or with pipx, or into the current environment with pip (add the llm extra for cloud LLM
refinement):
pipx install webinar-transcriber
pip install "webinar-transcriber[llm]"
Install from a GitHub release
Pin a tagged release directly from GitHub when you want a fixed version and do not need a checkout:
uv tool install --reinstall git+https://github.com/megabyde/webinar-transcriber.git@v1.2.0
Replace v1.2.0 with the release tag you want. Wheel and source distribution files are also
attached to the GitHub Releases page.
Install the CLI from this checkout
From the repository root, run the target that matches the runtime you need:
| Command | Installs |
|---|---|
make install |
Standard local CLI install. |
make install-llm |
CLI plus optional OpenAI/Anthropic LLM dependencies. |
make install-cuda |
CLI with pywhispercpp rebuilt from source for NVIDIA. |
make uninstall |
Removes the installed webinar-transcriber uv tool. |
make install registers webinar-transcriber as a uv tool from the local source tree. No virtual
environment activation is needed. Re-run the install target after pulling changes when the installed
command should track the checkout.
[!TIP] Without
make, install the local checkout with uv directly:uv tool install --reinstall .
Run make help to list every project target.
The default large-v3-turbo Whisper model downloads on the first transcription run, not during
installation.
NVIDIA CUDA
[!CAUTION] CUDA installs rebuild
pywhispercpplocally and depend on the host CUDA toolkit. Use the standard install unless you specifically need NVIDIA acceleration.
CUDA is the only supported path that builds pywhispercpp from source. It requires
CMake, a C/C++ compiler, and a working
CUDA toolkit with nvcc on PATH and CUDA_HOME
set.
make install-cudainstalls the CLI tool with CUDA support.make sync-cudaprepares the checkout development environment with CUDA support.
If the build fails, see CUDA install fails.
Usage
Quick start
By default, each input gets a fresh run directory under runs/. Multiple inputs are processed
sequentially. --output-dir is allowed only with one input.
Any container PyAV can decode is accepted, including common formats such as .mp4, .mkv, .mov,
.webm, .mp3, .wav, and .m4a.
[!TIP] Use a fresh
--output-dirfor reproducible comparisons. Existing output directories are refused, not overwritten.
webinar-transcriber INPUT
webinar-transcriber INPUT1 INPUT2 INPUT3
webinar-transcriber INPUT --keep-audio
webinar-transcriber INPUT --output-dir runs/custom-demo
Cloud LLM
--llm enables provider-backed report refinement after deterministic sectioning. The LLM step can
polish section transcript text with light cleanup and paragraphing, and refine summary bullets,
action items, section titles, and section TL;DRs. Supported providers are openai and anthropic;
OpenAI is the default.
The base install does not include provider SDKs. Install the LLM extra first:
make install-llm
[!IMPORTANT]
--llmsends report text and transcript excerpts to the configured provider. Do not use it for recordings that must stay entirely local.
Configure the provider with environment variables:
LLM_PROVIDER:openai(default) oranthropic.OPENAI_API_KEY/OPENAI_MODEL: API key and model identifier for the OpenAI provider.ANTHROPIC_API_KEY/ANTHROPIC_MODEL: API key and model identifier for the Anthropic provider.
The CLI does not pin a default model name for either provider; pass any model the provider supports.
OPENAI_API_KEY=... \
OPENAI_MODEL=<openai-model> \
webinar-transcriber INPUT --llm
LLM_PROVIDER=anthropic \
ANTHROPIC_API_KEY=... \
ANTHROPIC_MODEL=<anthropic-model> \
webinar-transcriber INPUT --llm
For missing environment variables, missing extras, or unsupported provider names, see Troubleshooting.
Speaker diarization
Pass --diarize to label transcript segments with anonymous local speaker IDs:
webinar-transcriber INPUT --diarize
webinar-transcriber INPUT --diarize --diarize-speakers 4
[!WARNING] Pass
--diarize-speakersonly when the exact speaker count is known. A wrong count can force poor speaker labels. Omit the option to let Sherpa estimate the count.
Diarization runs locally through sherpa-onnx and does not use an API key. The first diarized run
downloads the segmentation and speaker-embedding models into
~/.cache/webinar-transcriber/diarization. Set WEBINAR_DIARIZATION_CACHE_DIR to override that
cache directory.
When diarization is enabled, reports label each speaker turn with stable anonymous labels ordered by
first appearance in the timeline: S1, S2, and so on (one label per turn, even when a turn spans
several paragraphs). JSON artifacts include a speaker field on transcript segments and a separate
diarization.json file with raw speaker turns. If labels look wrong, see
Poor diarization labels.
Advanced Usage
ASR model
webinar-transcriber uses pywhispercpp to resolve whisper.cpp models. By default it uses
large-v3-turbo (downloaded on the first run, as noted in Install). You can pass
another model identifier or a local GGML model path with --asr-model.
webinar-transcriber INPUT --asr-model large-v3-turbo
webinar-transcriber INPUT --asr-model large-v3
webinar-transcriber INPUT --asr-model models/whisper-cpp/ggml-large-v3-turbo.bin
To manage the model file yourself, download it directly:
mkdir -p models/whisper-cpp
curl -L \
-o models/whisper-cpp/ggml-large-v3-turbo.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin
Use --asr-model large-v3 when transcription accuracy matters more than local runtime.
ASR controls
The default ASR path uses the selected whisper.cpp model, automatic language detection, and an
automatically selected thread count.
--language CODE: force a Whisper language code such asenorru.--threads N: set the CPU worker count passed towhisper.cpp.
GPU-enabled builds can offload supported model work to the GPU, but whisper.cpp still uses CPU
threads for scheduling, language detection, and non-offloaded work. The same --threads value is
also used by local VAD, local diarization, and concurrent LLM section polishing. By default, the CLI
uses the host CPU count capped at 8. Lower it when the machine needs CPU capacity for other work.
Troubleshooting
Common errors and their fixes, indexed by the message the CLI prints, live in docs/troubleshooting.md.
Reference
Output layout
Successful runs can write:
runs/<timestamp>_<basename>/
├─ metadata.json # probed media type, duration, streams
├─ transcript.json # reconciled transcript with timestamps and optional speakers
├─ report.md
├─ report.docx
├─ report.json # final report in markdown, docx, and json
├─ diagnostics.json # stage timings, counts, warnings, ASR and optional LLM info
├─ asr/
│ ├─ speech_regions.json # VAD ranges
│ └─ decoded_windows.json # per-window decode output
├─ diarization.json # anonymous speaker turns; --diarize only
├─ scenes.json # scene boundaries; video only
├─ frames/ # representative frames; video only
└─ transcription-audio.mp3 # normalized audio copy; --keep-audio only
Failed runs still write diagnostics.json with the failed stage and any partial intermediate
artifacts already produced, as long as the run directory exists.
Development
Checkout setup, running from source, the make target reference, and the quality gate live in docs/development.md. Coding conventions, testing notes, and the Definition of Done live in AGENTS.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file webinar_transcriber-1.3.0.tar.gz.
File metadata
- Download URL: webinar_transcriber-1.3.0.tar.gz
- Upload date:
- Size: 4.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1a66aad22668674d892873c0548d74741f368d8d570bb807d5594bed751636c
|
|
| MD5 |
62aa71291051a7cfb9b3f0abb96e8ddc
|
|
| BLAKE2b-256 |
ab88794311212818d70182feae06d55e0303ba2709339003b0da34afec748554
|
Provenance
The following attestation bundles were made for webinar_transcriber-1.3.0.tar.gz:
Publisher:
release.yml on megabyde/webinar-transcriber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
webinar_transcriber-1.3.0.tar.gz -
Subject digest:
f1a66aad22668674d892873c0548d74741f368d8d570bb807d5594bed751636c - Sigstore transparency entry: 1893048015
- Sigstore integration time:
-
Permalink:
megabyde/webinar-transcriber@077c30ef856df3805917f13cd7cf716cd1fe73db -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/megabyde
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@077c30ef856df3805917f13cd7cf716cd1fe73db -
Trigger Event:
push
-
Statement type:
File details
Details for the file webinar_transcriber-1.3.0-py3-none-any.whl.
File metadata
- Download URL: webinar_transcriber-1.3.0-py3-none-any.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
547aef379f1a49d12cdf0fc72d54f040182f0eccf62ace7aeb7a5da5044b56ed
|
|
| MD5 |
38bea9c18160dd865ad830a7a5bc8da4
|
|
| BLAKE2b-256 |
5f3e6953f9f35e8db9bd641606c0d48a3cf1f20a9d1cee58af5a92b68911cdae
|
Provenance
The following attestation bundles were made for webinar_transcriber-1.3.0-py3-none-any.whl:
Publisher:
release.yml on megabyde/webinar-transcriber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
webinar_transcriber-1.3.0-py3-none-any.whl -
Subject digest:
547aef379f1a49d12cdf0fc72d54f040182f0eccf62ace7aeb7a5da5044b56ed - Sigstore transparency entry: 1893048095
- Sigstore integration time:
-
Permalink:
megabyde/webinar-transcriber@077c30ef856df3805917f13cd7cf716cd1fe73db -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/megabyde
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@077c30ef856df3805917f13cd7cf716cd1fe73db -
Trigger Event:
push
-
Statement type: