# Youtube Transcript

> This skill should be used when the user provides a YouTube URL and wants to "download transcript", "get captions", "get subtitles", "transcribe video", or extract text content from a YouTube video. Handles manual subtitles, auto-generated captions, and Whisper transcription as fallback.

- **Type:** Skill
- **Install:** `agentstack add skill-ryanhudson-tapestry-skills-for-claude-code-youtube-transcript`
- **Verified:** Pending review
- **Seller:** [ryanhudson](https://agentstack.voostack.com/s/ryanhudson)
- **Installs:** 0
- **Category:** [Content & Media](https://agentstack.voostack.com/c/content-and-media)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ryanhudson](https://github.com/ryanhudson)
- **Source:** https://github.com/ryanhudson/tapestry-skills-for-claude-code/tree/main/skills/youtube-transcript

## Install

```sh
agentstack add skill-ryanhudson-tapestry-skills-for-claude-code-youtube-transcript
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# YouTube Transcript Downloader

Extract transcripts from YouTube videos using yt-dlp. Supports manual subtitles, auto-generated captions, and Whisper transcription as a last resort.

## Prerequisites

This skill requires [UV](https://docs.astral.sh/uv/) for dependency management. Run from the tapestry-skills project root.

## Workflow

```
URL → Validate → Check yt-dlp → List Subtitles → Download → Convert to Text → Save
```

**Priority order**:
1. Manual subtitles (highest quality)
2. Auto-generated captions (usually available)
3. Whisper transcription (requires user consent)

## Security Requirements

All security utilities are available via UV from the project root.

### URL Validation

```bash
# Validate YouTube URL (must also be a valid YouTube domain)
if [[ ! "$URL" =~ ^https?://(www\.)?(youtube\.com|youtu\.be)/ ]]; then
    echo "Error: Not a valid YouTube URL"
    exit 1
fi

# Run general security validation (SSRF protection, etc.)
uv run tapestry-validate-url "$URL" || exit 1
```

### Filename Sanitization

```bash
# Use tapestry sanitization utility
SAFE_TITLE=$(uv run tapestry-sanitize-filename "$VIDEO_TITLE")
```

## Step 1: Check yt-dlp Installation

yt-dlp is included in the project dependencies. Use via UV:

```bash
# yt-dlp is available through uv run
uv run yt-dlp --version
```

## Step 2: Check Available Subtitles

Always check what's available first:

```bash
uv run yt-dlp --list-subs "$URL"
```

Look for:
- `Available subtitles` (manual, higher quality)
- `Available automatic captions` (auto-generated)

## Step 3: Download Subtitles

### Try Manual First

```bash
TEMP_DIR=$(mktemp -d)
trap "rm -rf '$TEMP_DIR'" EXIT

if uv run yt-dlp --write-sub --skip-download --sub-langs en -o "$TEMP_DIR/transcript" "$URL" 2>/dev/null; then
    echo "Downloaded manual subtitles"
else
    # Fall back to auto-generated
    uv run yt-dlp --write-auto-sub --skip-download --sub-langs en -o "$TEMP_DIR/transcript" "$URL"
    echo "Downloaded auto-generated captions"
fi
```

## Step 4: Convert VTT to Clean Text

Use the tapestry VTT converter which handles deduplication automatically:

```bash
VIDEO_TITLE=$(uv run yt-dlp --print "%(title)s" "$URL" 2>/dev/null)
SAFE_TITLE=$(uv run tapestry-sanitize-filename "$VIDEO_TITLE")

VTT_FILE=$(find "$TEMP_DIR" -name "*.vtt" | head -n 1)

# Convert VTT to clean text (handles deduplication, HTML tags, entities)
uv run tapestry-vtt-to-text "$VTT_FILE" --output "${SAFE_TITLE}.txt"

echo "Saved: ${SAFE_TITLE}.txt"
```

## Whisper Transcription (Last Resort)

**Only offer when no subtitles are available. Requires explicit user consent.**

### Check File Size First

```bash
DURATION=$(uv run yt-dlp --print "%(duration)s" "$URL" 2>/dev/null)
TITLE=$(uv run yt-dlp --print "%(title)s" "$URL" 2>/dev/null)

echo "No subtitles available for: $TITLE"
echo "Duration: $((DURATION / 60)) minutes"
echo ""
echo "Download audio and transcribe with Whisper? (requires ~1-3GB for model)"
echo "Type 'yes' to proceed:"
```

**Wait for explicit "yes" before proceeding.**

### Download and Transcribe

```bash
TEMP_DIR=$(mktemp -d)
trap "rm -rf '$TEMP_DIR'" EXIT

# Download audio only
uv run yt-dlp -x --audio-format mp3 -o "$TEMP_DIR/audio.%(ext)s" "$URL"

# Transcribe with Whisper (installs on first use)
uv run --with openai-whisper whisper "$TEMP_DIR/audio.mp3" --model base --output_format vtt --output_dir "$TEMP_DIR"

# Convert VTT to text
VTT_FILE=$(find "$TEMP_DIR" -name "*.vtt" | head -n 1)
uv run tapestry-vtt-to-text "$VTT_FILE" --output "${SAFE_TITLE}.txt"
```

## Complete Workflow Script

```bash
#!/bin/bash
set -e

URL="$1"

# Validate YouTube URL
if [[ ! "$URL" =~ ^https?://(www\.)?(youtube\.com|youtu\.be)/ ]]; then
    echo "Error: Not a valid YouTube URL"
    exit 1
fi

# Run security validation
uv run tapestry-validate-url "$URL" || exit 1

# Get video info
VIDEO_TITLE=$(uv run yt-dlp --print "%(title)s" "$URL" 2>/dev/null)
SAFE_TITLE=$(uv run tapestry-sanitize-filename "$VIDEO_TITLE")

echo "Video: $VIDEO_TITLE"
echo ""

# Create temp directory
TEMP_DIR=$(mktemp -d)
trap "rm -rf '$TEMP_DIR'" EXIT

# Try to download subtitles
echo "Checking for subtitles..."
if uv run yt-dlp --write-sub --skip-download --sub-langs en -o "$TEMP_DIR/transcript" "$URL" 2>/dev/null; then
    echo "Found manual subtitles"
elif uv run yt-dlp --write-auto-sub --skip-download --sub-langs en -o "$TEMP_DIR/transcript" "$URL" 2>/dev/null; then
    echo "Found auto-generated captions"
else
    echo "No subtitles available"
    # Offer Whisper option here (with user consent)
    exit 1
fi

# Find VTT file
VTT_FILE=$(find "$TEMP_DIR" -name "*.vtt" | head -n 1)

if [ -z "$VTT_FILE" ]; then
    echo "Error: No VTT file found"
    exit 1
fi

# Convert to clean text
uv run tapestry-vtt-to-text "$VTT_FILE" --output "${SAFE_TITLE}.txt"

WORD_COUNT=$(wc -w < "${SAFE_TITLE}.txt" | tr -d ' ')

echo ""
echo "Transcript saved: ${SAFE_TITLE}.txt"
echo "Words: $WORD_COUNT"
```

## Error Handling

| Issue | Solution |
|-------|----------|
| UV not installed | Install with `curl -LsSf https://astral.sh/uv/install.sh \| sh` |
| Invalid URL | Reject non-YouTube URLs |
| No subtitles | Offer Whisper with user consent |
| Private/restricted video | Inform user, cannot access |
| SSL errors | Try `--no-check-certificate` (with warning) |
| Download timeout | Retry or inform user |

## Dependencies

All dependencies are managed via UV and `pyproject.toml`:

- **yt-dlp**: YouTube downloads (pinned version)
- **openai-whisper** (optional): For videos without subtitles

## Security Reference

For complete security guidelines: `../shared/references/security-guidelines.md`

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ryanhudson](https://github.com/ryanhudson)
- **Source:** [ryanhudson/tapestry-skills-for-claude-code](https://github.com/ryanhudson/tapestry-skills-for-claude-code)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ryanhudson-tapestry-skills-for-claude-code-youtube-transcript
- Seller: https://agentstack.voostack.com/s/ryanhudson
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
