Skip to main content

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"

After an API-backed transcription, generated Markdown includes a Processing options section with the provider, model, language, compression, chunking, range, timeout settings, estimated API cost, and a replay command for the run. The CLI prints the same cost estimate. OpenAI estimates use provider-reported token usage when available and otherwise use the published estimated per-minute rate. Gemini estimates use provider-reported modality token usage for the standard paid tier. CLOVA estimates include base speech recognition at 5 KRW per 15-second request unit; speaker diarization and other optional feature charges are not included.

Rates are maintained as dated list prices, with the pricing date and source saved alongside the estimate. Free-tier allowances, credits, taxes, and account-specific adjustments are excluded, so the provider invoice can differ. Cost is reported as unavailable for unrecognized models, custom OpenAI or Gemini endpoints, or responses without enough usage metadata. See the official OpenAI, Gemini, and CLOVA pricing pages for current rates.

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.

Metadata

Release files for meetdown 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for meetdown 0.3.0
File Size Uploaded
meetdown-0.3.0.tar.gz 31.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for meetdown 0.3.0
File Interpreter ABI Platform
meetdown-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 69.6 kB

Release files / meetdown-0.3.0.tar.gz

Download URL meetdown-0.3.0.tar.gz
Size 31.9 kB
Tags Source
SHA-256 checksum
How to use checksums
156e6f0d6b4ac8dc71870bc68a397dc5fed4259b521c69654835d34e4165b4d0
BLAKE2b-256 checksum
How to use checksums
d4c1926c5136f789c7debc3a11d0aca8a8dabaedf248f5e86291dc27cbc93a74
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","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}

Release files / meetdown-0.3.0-py3-none-any.whl

Download URL meetdown-0.3.0-py3-none-any.whl
Size 37.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b7a62ba02f89ebc4a9ea42febc034caccdccf025227eb76b4c64a424681eaea6
BLAKE2b-256 checksum
How to use checksums
1a602893a6c7d1da21831c14259d94d778e6efe39d79af67202880b8dfe2bf78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","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}

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page