Skip to main content

Turn YouTube URLs and local videos into agent-ready transcripts.

Project description

YouTube Transcribe

A local-first CLI that turns a YouTube URL or local video file into a clean, agent-ready transcript.

YouTube Transcribe downloads YouTube audio with yt-dlp or extracts audio from a local video with FFmpeg, transcribes it locally with faster-whisper, and writes a portable Markdown file. It can also preserve word-level timestamps, WebVTT subtitles, and the downloaded or extracted audio.

  • No transcription API key or per-minute fee
  • Local speech-to-text on macOS, Linux, and Windows
  • Stable Markdown and versioned JSON outputs
  • Optional transcript cleanup with an existing Codex CLI or Claude Code login
  • Agent Skill included for Codex, Claude Code, and compatible tools

Install

Requirements:

  • Python 3.10 or newer
  • Enough disk space and memory for the selected Whisper model
  • FFmpeg on PATH only when transcribing local video files

Install the latest stable release, its dependencies, and the Agent Skill:

curl -fsSL https://raw.githubusercontent.com/kaveniohq/youtube-transcribe/main/install.sh | bash

The installer creates an isolated environment, exposes the command under ~/.local/bin, installs the skill for Codex and Claude Code, and runs youtube-transcribe doctor. If ~/.local/bin is not on your PATH, it prints the exact command to add it.

Prefer installing manually? Use pipx:

pipx install kavenio-youtube-transcribe
youtube-transcribe install-skill
youtube-transcribe doctor

Quick start

Transcribe a video:

youtube-transcribe "https://www.youtube.com/watch?v=VIDEO_ID"
youtube-transcribe "/path/to/recording.mp4"

The first run downloads the selected Whisper model. The default base model is a practical speed/quality compromise.

Usage

What you want Command Result
Transcribe YouTube youtube-transcribe "URL" transcript.md
Transcribe a local video youtube-transcribe "/path/to/video.mp4" transcript.md
Choose an output location youtube-transcribe "SOURCE" --output-dir ./transcripts One video folder inside ./transcripts
Add word and segment timestamps youtube-transcribe "SOURCE" --timestamps Markdown, versioned JSON, and WebVTT
Keep the working audio youtube-transcribe "SOURCE" --keep-audio Transcript plus downloaded or extracted audio
Refine with Codex CLI youtube-transcribe "URL" --codex Locally transcribed, then text-edited with Codex
Refine with Claude Code youtube-transcribe "URL" --claude Locally transcribed, then text-edited with Claude
Use a faster model youtube-transcribe "URL" --model tiny Faster draft with lower accuracy
Use a more accurate model youtube-transcribe "URL" --model small Slower transcript with higher accuracy
Fix the spoken language youtube-transcribe "URL" --language en Skips language auto-detection
Use NVIDIA CUDA youtube-transcribe "URL" --device cuda GPU inference with supported CUDA setup
Use browser authentication youtube-transcribe "URL" --cookies-from-browser chrome Lets yt-dlp read the selected local browser session
Protect existing artifacts youtube-transcribe "URL" --no-overwrite Fails instead of replacing output files
Install the Agent Skill youtube-transcribe install-skill Adds the skill to Codex and Claude discovery locations
Check the installation youtube-transcribe doctor Dependency and update status

Options can be combined:

youtube-transcribe "URL" \
  --output-dir ./transcripts \
  --model base \
  --timestamps \
  --codex

Run youtube-transcribe --help for the complete command reference.

Output

Each run creates a deterministic folder named from the video title and source ID:

steam-machine-8cDatzBIufQ/
└── transcript.md

With --timestamps:

steam-machine-8cDatzBIufQ/
├── transcript.md
├── transcript.json
└── timestamps.vtt

Add --keep-audio to retain the audio file in the same folder. YouTube keeps the native downloaded format; local videos keep the FFmpeg-extracted WAV.

Artifact Created when Purpose
transcript.md Always Readable transcript with source provenance
transcript.json --timestamps Versioned machine contract with raw segment and word timing
timestamps.vtt --timestamps Subtitles for players and tools that support WebVTT
audio.webm, audio.m4a, or audio.wav --keep-audio Downloaded YouTube audio or extracted local-video audio

The CLI writes progress to stderr and final artifact paths to stdout, which makes it safe to use in scripts and agent workflows:

[download]    YouTube audio           [████████████████████] 100%
[model]       Download Whisper base   [████████░░░░░░░░░░░░]  40%
[transcribe]  Speech to text          [██████████░░░░░░░░░░]  50%
[write]       Agent-ready artifacts

Transcript format

Markdown begins with YAML-compatible provenance followed by the complete transcript:

---
transcript_schema: 1
title: "Example video"
source: "https://www.youtube.com/watch?v=..."
video_id: "..."
language: "en"
transcription_model: "base"
edited_by: "none"
transcript_data: null
timestamps: null
---

# Example video

Complete transcript...

With --timestamps, transcript.json is the canonical machine-readable artifact. It keeps immutable raw Whisper timing separate from optionally edited prose. The normative schema is transcript-v1.schema.json.

Optional AI editing

No editor is selected by default. --codex and --claude deliberately start a separate command-line editor process after local transcription; they may use the allowance associated with your existing login.

The editor receives transcript text through standard input and cannot change the raw timestamp data:

youtube-transcribe "URL" --codex --timestamps
youtube-transcribe "URL" --claude --timestamps

Codex runs ephemerally in a read-only sandbox without user execution rules. Claude runs without built-in tools, MCP servers, slash commands, Chrome integration, or session persistence. Both run from an empty temporary directory.

Use with AI agents

The repository includes a portable Agent Skill that teaches compatible agents when to run the CLI, which options to select, and which generated file to read.

The CLI package bundles this skill. Install it with:

youtube-transcribe install-skill

This works on Linux, macOS, and Windows and writes:

~/.agents/skills/youtube-transcribe  # Codex and compatible agents
~/.claude/skills/youtube-transcribe  # Claude Code

Use --target codex or --target claude to install only one copy. Rerunning the command safely updates an unchanged managed skill. Locally modified files are preserved unless you explicitly pass --force. Run it again after upgrading the CLI to install the bundled skill version.

Restart an already-running agent, then ask naturally:

Transcribe https://www.youtube.com/watch?v=VIDEO_ID
Transcribe /path/to/local-video.mp4
Transcribe this video with timestamps: https://youtu.be/VIDEO_ID
Use $youtube-transcribe to turn this video into notes: https://youtu.be/VIDEO_ID
Use /youtube-transcribe to create subtitles for https://youtu.be/VIDEO_ID

The active agent does not need --codex or --claude; those options start a second editor process.

Local development

git clone https://github.com/kaveniohq/youtube-transcribe.git
cd youtube-transcribe
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
pytest

On Windows PowerShell, activate the environment with:

.venv\Scripts\Activate.ps1

Before submitting a change, run:

ruff check src tests
ruff format --check src tests
pytest --cov=youtube_transcript --cov-fail-under=80
python -m build
python -m twine check dist/*

Development references:

  • AGENT.md — setup, architecture, invariants, and agent-facing implementation guidance
  • CONTRIBUTING.md — contribution and verification rules
  • ARCHITECTURE.md — detailed contracts, design decisions, and implementation evidence
  • RELEASING.md — versioning and release procedure

Default tests are offline: they do not download videos or models and do not invoke Codex or Claude.

How it works

YouTube URL or local video path
  -> yt-dlp native audio download or FFmpeg audio extraction
  -> local faster-whisper transcription
  -> optional Codex or Claude text editing
  -> atomic Markdown / JSON / WebVTT output

Provider-specific code stays behind small adapters. Temporary downloads are cleaned automatically, and final artifacts are written only after the requested pipeline succeeds.

Current limitations

  • One video per invocation; playlists and channels are not supported.
  • Local video transcription requires ffmpeg on PATH and an audio stream FFmpeg can decode.
  • Transcripts over 600,000 characters are not sent to an optional editor.
  • Live streams, members-only videos, regional restrictions, and YouTube bot challenges depend on yt-dlp and may require browser cookies.
  • The first transcription for a model requires a model download.

The package supplies yt-dlp's supported Deno runtime and uses faster-whisper's PyAV decoder for YouTube audio. A global JavaScript runtime and FFprobe are not required. FFmpeg is not required for YouTube URLs, but is required for local video files.

Updates

After a successful interactive run, the CLI checks PyPI at most once every seven days and prints a notice when a newer version is available. It never installs updates, changes stdout, or sends transcript/source metadata.

Set YOUTUBE_TRANSCRIBE_NO_UPDATE_CHECK=1 to disable update checks.

Contributing

Issues and focused pull requests are welcome. Please read CONTRIBUTING.md before making a change and include tests for behavior changes.

License

Licensed under the MIT License.

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

kavenio_youtube_transcribe-0.2.0.tar.gz (47.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kavenio_youtube_transcribe-0.2.0-py3-none-any.whl (34.6 kB view details)

Uploaded Python 3

File details

Details for the file kavenio_youtube_transcribe-0.2.0.tar.gz.

File metadata

File hashes

Hashes for kavenio_youtube_transcribe-0.2.0.tar.gz
Algorithm Hash digest
SHA256 bd552cd715e6dde7b3fe58fb7cb9d1176926a537109171fd967337929e4eff86
MD5 03542cb4d110bccf7f7e98758ef8cadd
BLAKE2b-256 9bac7b0783e36e0eb25e0df65645312d9761a5395173d692475d42307907ee5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for kavenio_youtube_transcribe-0.2.0.tar.gz:

Publisher: release.yml on kaveniohq/youtube-transcribe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kavenio_youtube_transcribe-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for kavenio_youtube_transcribe-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 90b52713579ae4dfe352304dcf3aef666128bb1a18f4bfe4d497ce5115dceeae
MD5 269abf4c04d3a94e3059daf535eb140e
BLAKE2b-256 94fdd107137aab2f119e91d780953ed7098270b2d7e647d9d81587d6932baeab

See more details on using hashes here.

Provenance

The following attestation bundles were made for kavenio_youtube_transcribe-0.2.0-py3-none-any.whl:

Publisher: release.yml on kaveniohq/youtube-transcribe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page