$npx -y skills add michalparkola/tapestry-skills --skill youtube-transcriptDownload YouTube video transcripts when user provides a YouTube URL or asks to download/get/fetch a transcript from YouTube. Also use when user wants to transcribe or get captions/subtitles from a YouTube video.
| 1 | # YouTube Transcript Downloader |
| 2 | |
| 3 | This skill helps download transcripts (subtitles/captions) from YouTube videos using yt-dlp. |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | Activate this skill when the user: |
| 8 | - Provides a YouTube URL and wants the transcript |
| 9 | - Asks to "download transcript from YouTube" |
| 10 | - Wants to "get captions" or "get subtitles" from a video |
| 11 | - Asks to "transcribe a YouTube video" |
| 12 | - Needs text content from a YouTube video |
| 13 | |
| 14 | ## How It Works |
| 15 | |
| 16 | ### Priority Order: |
| 17 | 1. **Check if yt-dlp is installed** - install if needed |
| 18 | 2. **List available subtitles** - see what's actually available |
| 19 | 3. **Try manual subtitles first** (`--write-sub`) - highest quality |
| 20 | 4. **Fallback to auto-generated** (`--write-auto-sub`) - usually available |
| 21 | 5. **Last resort: Whisper transcription** - if no subtitles exist (requires user confirmation) |
| 22 | 6. **Confirm the download** and show the user where the file is saved |
| 23 | 7. **Optionally clean up** the VTT format if the user wants plain text |
| 24 | |
| 25 | ## Installation Check |
| 26 | |
| 27 | **IMPORTANT**: Always check if yt-dlp is installed first: |
| 28 | |
| 29 | ```bash |
| 30 | which yt-dlp || command -v yt-dlp |
| 31 | ``` |
| 32 | |
| 33 | ### If Not Installed |
| 34 | |
| 35 | Attempt automatic installation based on the system: |
| 36 | |
| 37 | **macOS (Homebrew)**: |
| 38 | ```bash |
| 39 | brew install yt-dlp |
| 40 | ``` |
| 41 | |
| 42 | **Linux (apt/Debian/Ubuntu)**: |
| 43 | ```bash |
| 44 | sudo apt update && sudo apt install -y yt-dlp |
| 45 | ``` |
| 46 | |
| 47 | **Alternative (pip - works on all systems)**: |
| 48 | ```bash |
| 49 | pip3 install yt-dlp |
| 50 | # or |
| 51 | python3 -m pip install yt-dlp |
| 52 | ``` |
| 53 | |
| 54 | **If installation fails**: Inform the user they need to install yt-dlp manually and provide them with installation instructions from https://github.com/yt-dlp/yt-dlp#installation |
| 55 | |
| 56 | ## Check Available Subtitles |
| 57 | |
| 58 | **ALWAYS do this first** before attempting to download: |
| 59 | |
| 60 | ```bash |
| 61 | yt-dlp --list-subs "YOUTUBE_URL" |
| 62 | ``` |
| 63 | |
| 64 | This shows what subtitle types are available without downloading anything. Look for: |
| 65 | - Manual subtitles (better quality) |
| 66 | - Auto-generated subtitles (usually available) |
| 67 | - Available languages |
| 68 | |
| 69 | ## Download Strategy |
| 70 | |
| 71 | ### Option 1: Manual Subtitles (Preferred) |
| 72 | |
| 73 | Try this first - highest quality, human-created: |
| 74 | |
| 75 | ```bash |
| 76 | yt-dlp --write-sub --skip-download --output "OUTPUT_NAME" "YOUTUBE_URL" |
| 77 | ``` |
| 78 | |
| 79 | ### Option 2: Auto-Generated Subtitles (Fallback) |
| 80 | |
| 81 | If manual subtitles aren't available: |
| 82 | |
| 83 | ```bash |
| 84 | yt-dlp --write-auto-sub --skip-download --output "OUTPUT_NAME" "YOUTUBE_URL" |
| 85 | ``` |
| 86 | |
| 87 | Both commands create a `.vtt` file (WebVTT subtitle format). |
| 88 | |
| 89 | ## Option 3: Whisper Transcription (Last Resort) |
| 90 | |
| 91 | **ONLY use this if both manual and auto-generated subtitles are unavailable.** |
| 92 | |
| 93 | ### Step 1: Show File Size and Ask for Confirmation |
| 94 | |
| 95 | ```bash |
| 96 | # Get audio file size estimate |
| 97 | yt-dlp --print "%(filesize,filesize_approx)s" -f "bestaudio" "YOUTUBE_URL" |
| 98 | |
| 99 | # Or get duration to estimate |
| 100 | yt-dlp --print "%(duration)s %(title)s" "YOUTUBE_URL" |
| 101 | ``` |
| 102 | |
| 103 | **IMPORTANT**: Display the file size to the user and ask: "No subtitles are available. I can download the audio (approximately X MB) and transcribe it using Whisper. Would you like to proceed?" |
| 104 | |
| 105 | **Wait for user confirmation before continuing.** |
| 106 | |
| 107 | ### Step 2: Check for Whisper Installation |
| 108 | |
| 109 | ```bash |
| 110 | command -v whisper |
| 111 | ``` |
| 112 | |
| 113 | If not installed, ask user: "Whisper is not installed. Install it with `pip install openai-whisper` (requires ~1-3GB for models)? This is a one-time installation." |
| 114 | |
| 115 | **Wait for user confirmation before installing.** |
| 116 | |
| 117 | Install if approved: |
| 118 | ```bash |
| 119 | pip3 install openai-whisper |
| 120 | ``` |
| 121 | |
| 122 | ### Step 3: Download Audio Only |
| 123 | |
| 124 | ```bash |
| 125 | yt-dlp -x --audio-format mp3 --output "audio_%(id)s.%(ext)s" "YOUTUBE_URL" |
| 126 | ``` |
| 127 | |
| 128 | ### Step 4: Transcribe with Whisper |
| 129 | |
| 130 | ```bash |
| 131 | # Auto-detect language (recommended) |
| 132 | whisper audio_VIDEO_ID.mp3 --model base --output_format vtt |
| 133 | |
| 134 | # Or specify language if known |
| 135 | whisper audio_VIDEO_ID.mp3 --model base --language en --output_format vtt |
| 136 | ``` |
| 137 | |
| 138 | **Model Options** (stick to `base` for now): |
| 139 | - `tiny` - fastest, least accurate (~1GB) |
| 140 | - `base` - good balance (~1GB) ← **USE THIS** |
| 141 | - `small` - better accuracy (~2GB) |
| 142 | - `medium` - very good (~5GB) |
| 143 | - `large` - best accuracy (~10GB) |
| 144 | |
| 145 | ### Step 5: Cleanup |
| 146 | |
| 147 | After transcription completes, ask user: "Transcription complete! Would you like me to delete the audio file to save space?" |
| 148 | |
| 149 | If yes: |
| 150 | ```bash |
| 151 | rm audio_VIDEO_ID.mp3 |
| 152 | ``` |
| 153 | |
| 154 | ## Getting Video Information |
| 155 | |
| 156 | ### Extract Video Title (for filename) |
| 157 | |
| 158 | ```bash |
| 159 | yt-dlp --print "%(title)s" "YOUTUBE_URL" |
| 160 | ``` |
| 161 | |
| 162 | Use this to create meaningful filenames based on the video title. Clean the title for filesystem compatibility: |
| 163 | - Replace `/` with `-` |
| 164 | - Replace special characters that might cause issues |
| 165 | - Consider using sanitized version: `$(yt-dlp --print "%(title)s" "URL" | tr '/' '-' | tr ':' '-')` |
| 166 | |
| 167 | ## Post-Processing |
| 168 | |
| 169 | ### Convert to Plain Text (Recommended) |
| 170 | |
| 171 | YouTube's auto-generated VTT files contain **duplicate lines** because captions a |