Download YouTube audio as MP3 and transcribe with Parakeet-MLX (Apple Silicon/MLX)
Project description
podkeet
Download a YouTube video's audio as MP3 with yt-dlp and transcribe it using Parakeet-MLX (MLX on Apple Silicon).
Requirements
- macOS on Apple Silicon (M1/M2/M3/M4)
- Python
>= 3.13 ffmpeg(foryt-dlppost-processing)- Install on macOS:
brew install ffmpeg
- Install on macOS:
Parakeet-MLX is installed as a dependency and will use MLX (Metal) on Apple Silicon when device=auto.
Quick start
Run directly with uvx (no virtualenv needed):
uvx podkeet transcribe "https://www.youtube.com/watch?v=dQw4w9WgXcQ" --out-dir ./outputs
Note: The first run will install the podkeet CLI automatically. If you prefer a persistent install:
uvx pip install -U podkeet
Or, if you prefer working in a virtual environment:
uv venv --python 3.13
uv sync --extra dev
podkeet transcribe "https://www.youtube.com/watch?v=dQw4w9WgXcQ" --out-dir ./outputs
This will:
- Check for
ffmpegand instruct you to install it if missing. - Download the best audio stream and convert it to MP3.
- Transcribe the MP3 with Parakeet-MLX, saving a transcript next to the audio (and in
--out-dir).
Installation (PyPI)
Once released on PyPI, you can install directly:
uvx pip install -U podkeet
CLI reference
podkeet download URL --out-dir PATH [--no-timing]podkeet transcribe URL_OR_FILE --out-dir PATH [--keep-audio] [--language auto|en|…] [--model NAME] [--format txt|srt|vtt|json] [--device auto|mps|cpu] [--no-timing] [--version]
Notes:
- If
ffmpegis missing, a clear message explains how to install it. - The first transcription may download Parakeet-MLX models; subsequent runs use the local cache.
- On Apple Silicon,
device=autoprefers MLX (mps) and falls back to CPU if needed. - Timing: The CLI shows elapsed time for download and transcription; hide with
--no-timing. - JSON: When
--format jsonis used, the CLI prints a compact JSON summary to stdout (suitable for automation).
Robustness
- Filenames with special characters: We detect the actual file written by
yt-dlpinstead of guessing by title, avoiding path mismatches. - Large files / memory: If a full-file transcription hits a Metal/MLX memory error, the tool automatically falls back to chunked transcription (~10-minute segments) and merges results with correct timestamps.
- Network hiccups: The downloader uses retries, socket timeouts, and exponential backoff to handle transient network failures.
Examples
# Download only
podkeet download "https://www.youtube.com/watch?v=8P7v1lgl-1s" --out-dir ./podcasts
# Transcribe from URL with a specific start (yt-dlp handles t=)
podkeet transcribe "https://www.youtube.com/watch?v=8P7v1lgl-1s&t=121s" --out-dir ./podcasts
# Transcribe a local file to SRT
podkeet transcribe ./podcasts/example.mp3 --out-dir ./podcasts --format srt
# JSON summary output (includes timings):
podkeet transcribe "https://www.youtube.com/watch?v=dQw4w9WgXcQ" --format json | jq
Development
Install dev extras and set up the environment:
uv venv --python 3.13
uv sync --extra dev
Format with Ruff:
uvx ruff format
Lint with Ruff:
uvx ruff check
uvx ruff check --fix
Type-check with Ty (pre-release):
uvx ty check
Run tests:
uv run pytest -q
Build package (sdist + wheel):
uvx --from build pyproject-build
ls dist/
CI/CD
- CI (lint, type, tests, build) runs on pushes and PRs.
- Releases are automated:
- Conventional Commits drive version bumps and
CHANGELOG.mdvia Python Semantic Release. - A tag
vX.Y.Zis created onmain. - The Release workflow builds and publishes to PyPI using OIDC (Trusted Publishing).
- Conventional Commits drive version bumps and
Commit message hints (Conventional Commits):
feat: …→ minor version bumpfix: …→ patch version bumpfeat!: …or footerBREAKING CHANGE:→ major version bump
Troubleshooting
ffmpegnot found:brew install ffmpeg(then re-run).- MLX out-of-memory: The tool will switch to chunked transcription automatically; if still failing, try a smaller model.
- Network or YouTube rate limiting: The downloader retries with backoff; re-run later if persistent.
License
MIT
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 podkeet-1.1.1.tar.gz.
File metadata
- Download URL: podkeet-1.1.1.tar.gz
- Upload date:
- Size: 85.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c6d9c34817c493caa1f247c435ac9948a0809e821dbb8d76aa6b20358cc6513
|
|
| MD5 |
7f85e19fd36ac549f0eef9cf95b8e642
|
|
| BLAKE2b-256 |
c68042178689718cc88e221692a41693336ee5a23745bc988e7ea4656145e0ec
|
Provenance
The following attestation bundles were made for podkeet-1.1.1.tar.gz:
Publisher:
release.yml on chrisdoc/podkeet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
podkeet-1.1.1.tar.gz -
Subject digest:
5c6d9c34817c493caa1f247c435ac9948a0809e821dbb8d76aa6b20358cc6513 - Sigstore transparency entry: 1306880970
- Sigstore integration time:
-
Permalink:
chrisdoc/podkeet@fa3e1e1ae6ab53864345d5234198acc0fa1ba71f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chrisdoc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fa3e1e1ae6ab53864345d5234198acc0fa1ba71f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file podkeet-1.1.1-py3-none-any.whl.
File metadata
- Download URL: podkeet-1.1.1-py3-none-any.whl
- Upload date:
- Size: 11.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
797013e7d2aa9f808f97171227367b153725bca49a047c8d361910f957c6867e
|
|
| MD5 |
1b200c8a838376d65eba71ce3d7c0ed1
|
|
| BLAKE2b-256 |
ca21e92a36b9807398cf3c36aed1effd2600a4ec6b1da19d8173bd933fb4f1f2
|
Provenance
The following attestation bundles were made for podkeet-1.1.1-py3-none-any.whl:
Publisher:
release.yml on chrisdoc/podkeet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
podkeet-1.1.1-py3-none-any.whl -
Subject digest:
797013e7d2aa9f808f97171227367b153725bca49a047c8d361910f957c6867e - Sigstore transparency entry: 1306880974
- Sigstore integration time:
-
Permalink:
chrisdoc/podkeet@fa3e1e1ae6ab53864345d5234198acc0fa1ba71f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chrisdoc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fa3e1e1ae6ab53864345d5234198acc0fa1ba71f -
Trigger Event:
workflow_dispatch
-
Statement type: