Generate Markdown meeting transcripts from speech-to-text JSON.
Project description
meetdown
meetdown is a small Python CLI for turning meeting audio into a Markdown transcript.
The CLI sends a local audio or video file to a speech provider, normalizes the
response, and writes a .md file with the full text and speaker-by-speaker
transcript when the provider returns speaker information. When --provider is
omitted, meetdown auto-detects the provider from configured provider-specific
credentials.
Install and run
Run it directly with uvx; cloning this repository is not required:
uvx meetdown meeting.m4a -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key"
Use the optional Notion extra when you want meetdown to upload the saved Markdown file to Notion:
uvx "meetdown[notion]" transcribe meeting.m4a -o meeting.md --notion
For local development:
uv run meetdown meeting.m4a -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key"
Set credentials with environment variables:
$env:CLOVA_SPEECH_INVOKE_URL="https://your.invoke.url"
$env:CLOVA_SPEECH_SECRET_KEY="your-secret-key"
You can also pass them directly:
uvx meetdown meeting.m4a -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key"
Run meetdown without arguments, or use --help, to see the command list
without transcribing anything. Use quickstart for examples and defaults for
the current provider auto-detection status. In interactive terminals, the
defaults view is color-coded by area; set NO_COLOR=1 to keep plain text
output.
uvx meetdown
uvx meetdown --help
uvx meetdown quickstart
uvx meetdown defaults
uvx meetdown transcribe --help
Recognition language defaults to auto, so meetdown does not force a single
language when audio contains a mix such as English and Korean. Pass
--language ko-KR, --language en-US, or another provider-supported language
when you want to bias recognition toward one language. CLOVA Speech requires a
concrete language, so meetdown sends ko-KR for CLOVA when --language auto is
used; aliases such as ko and ko-kr are normalized to ko-KR.
Python API
Use the top-level package API when you want to call meetdown from Python instead of shelling out to the CLI:
from meetdown import render_markdown, transcribe_file, write_markdown
response = transcribe_file("meeting.m4a", provider="openai")
markdown = render_markdown(
response,
title="Weekly sync",
source_path="meeting.m4a",
)
write_markdown("meeting.md", markdown)
transcribe_file uses the same provider resolution rules as the CLI. For more
control, import resolve_provider_config and transcribe_with_provider from
meetdown and keep the provider config in your own application code.
Notion upload
Notion upload is optional. Install or run meetdown with the notion extra, then
set the Notion destination in environment variables:
$env:NOTION_TOKEN="secret_..."
$env:NOTION_PARENT_PAGE_ID="your-parent-page-id"
uvx "meetdown[notion]" transcribe meeting.m4a -o meeting.md --notion
When --notion is used, meetdown checks for the optional dependency,
NOTION_TOKEN, and a parent page ID before transcription starts. The Markdown
file is still written first; Notion upload runs only after the local file is
saved. When Notion returns a page URL, meetdown prints it after upload.
You can override the Notion page settings per run:
uvx "meetdown[notion]" transcribe meeting.m4a -o meeting.md --notion --notion-parent-page-id "page-id" --notion-title "Weekly sync" --notion-duplicate-strategy timestamp
Providers
If --provider is omitted, meetdown picks a provider only when exactly one
provider-specific API key is configured. Pass --provider explicitly when more
than one provider key is present, or when you pass only a generic --api-key or
MEETDOWN_API_KEY.
CLOVA Speech can be selected automatically when you provide a CLOVA Invoke URL and key:
uvx meetdown meeting.m4a -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key"
For CLOVA, --api-url is the CLOVA Speech Invoke URL from NAVER Cloud Platform.
You may pass either the base Invoke URL or a URL that already ends with
/recognizer/upload.
OpenAI and Gemini can be selected automatically from their provider-specific
environment variables. Use --api-url when you need to override the provider
endpoint or base URL:
$env:OPENAI_API_KEY="your-openai-key"
uvx meetdown meeting.m4a -o meeting.md --chunk-duration 10m
uvx meetdown meeting.m4a -o meeting.md --provider openai --api-url "https://api.openai.com/v1"
$env:GEMINI_API_KEY="your-gemini-key"
uvx meetdown meeting.m4a -o meeting.md --chunk-duration 10m
Use --model to override the provider default model. CLOVA does not support
--model; the CLOVA Speech model is determined by the Invoke URL/domain.
OpenAI defaults to a diarization-capable transcription model when diarization is
enabled, and to a smaller transcription model when --no-diarization is used.
Gemini uses inline audio requests, so use --chunk-duration for larger files.
Chunk long recordings
Use --chunk-duration when a recording is too long for one sync upload. The
CLI extracts audio chunks with ffmpeg, sends each chunk to the selected provider,
shifts segment timestamps back to the original file timeline, and writes one Markdown file.
If your PC does not have system ffmpeg, meetdown falls back to the bundled
imageio-ffmpeg executable installed with the package. If system ffprobe is
missing, meetdown reads duration metadata through ffmpeg instead.
uvx meetdown meeting.mp4 -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key" --chunk-duration 10m
Accepted duration forms include 600, 600s, 10m, and 1h. Uploads default
to --compress smallest, which extracts audio and uploads a 64 kbps MP3 copy.
Use --compress lossless for FLAC or --compress none to avoid compression.
When chunking or range extraction is used, --compress none creates WAV chunks:
uvx meetdown meeting.mp4 -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key" --chunk-duration 10m --compress lossless
uvx meetdown meeting.mp4 -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key" --chunk-duration 10m --compress none
You can still force the exact temporary upload format with --chunk-format mp3,
--chunk-format flac, or --chunk-format wav.
You can transcribe only part of the source file. Timestamps in the Markdown stay on the original media timeline:
uvx meetdown meeting.mp4 -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key" --start 10m --end 45m
uvx meetdown meeting.mp4 -o meeting.md --api-url "https://your.invoke.url" --api-key "your-secret-key" --start 00:10:00 --end 00:45:00 --chunk-duration 10m
Offline conversion
If you already have a CLOVA Speech JSON response, convert it without calling the API:
uvx meetdown --from-json examples/clova_response.sample.json -o sample.md --title "Sample Meeting"
Generated Markdown includes a Processing options section with the provider, model, language,
compression, chunking, range, timeout settings, and a replay command for the run.
Raw API keys are never written. They are stored only in masked form, such as
sk-p********7890. Replay commands use <...> placeholders for secret values;
replace them before running the command.
When a provider returns unnamed speakers, meetdown writes speaker placeholders
like [[SPEAKER_1]] and [[SPEAKER_2]]. These are intentionally easy to find
with Replace All and change to real names after you identify the speakers.
Initial scope
This project intentionally starts small. It supports one local file, provider-backed speech recognition, full text output, speaker-segment output, and Markdown file generation. Summaries, decisions, action items, database storage, web UI, async callbacks, and batch processing are later extensions.
Project details
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 meetdown-0.2.1.tar.gz.
File metadata
- Download URL: meetdown-0.2.1.tar.gz
- Upload date:
- Size: 27.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5db1902ec56095e85de6eac60190b58bef53db135b28b992d094124678dcda9
|
|
| MD5 |
b4df26baa738acad94388494f7c4bde9
|
|
| BLAKE2b-256 |
acc3286f61c05533ec2af65cf1150804758a15517089f89ed9832a6da3fc2193
|
File details
Details for the file meetdown-0.2.1-py3-none-any.whl.
File metadata
- Download URL: meetdown-0.2.1-py3-none-any.whl
- Upload date:
- Size: 33.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5530f146b01fb6e428c3ccb0b67398631d62ce0e3114cf67e19c3d8cf0d13df1
|
|
| MD5 |
6e5aaef4398449523cab0efe2f120e94
|
|
| BLAKE2b-256 |
bc3d30208b3e4ddb19d6dfaf0b05eeb1c2791ec9b913f65f6b127e4c4be37ce3
|