Nymbo commited on
Commit
256e85c
·
verified ·
1 Parent(s): a9decab

Create Skill.md

Browse files
Files changed (1) hide show
  1. Filesystem/Skill.md +418 -0
Filesystem/Skill.md ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: youtube-transcript
3
+ description: Download 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.
4
+ allowed-tools:
5
+ - Bash
6
+ - Read
7
+ - Write
8
+ ---
9
+
10
+ # YouTube Transcript Downloader
11
+
12
+ This skill helps download transcripts (subtitles/captions) from YouTube videos using yt-dlp.
13
+
14
+ ## When to Use This Skill
15
+
16
+ Activate this skill when the user:
17
+ - Provides a YouTube URL and wants the transcript
18
+ - Asks to "download transcript from YouTube"
19
+ - Wants to "get captions" or "get subtitles" from a video
20
+ - Asks to "transcribe a YouTube video"
21
+ - Needs text content from a YouTube video
22
+
23
+ ## How It Works
24
+
25
+ ### Priority Order:
26
+ 1. **Check if yt-dlp is installed** - install if needed
27
+ 2. **List available subtitles** - see what's actually available
28
+ 3. **Try manual subtitles first** (`--write-sub`) - highest quality
29
+ 4. **Fallback to auto-generated** (`--write-auto-sub`) - usually available
30
+ 5. **Last resort: Whisper transcription** - if no subtitles exist (requires user confirmation)
31
+ 6. **Confirm the download** and show the user where the file is saved
32
+ 7. **Optionally clean up** the VTT format if the user wants plain text
33
+
34
+ ## Installation Check
35
+
36
+ **IMPORTANT**: Always check if yt-dlp is installed first:
37
+
38
+ ```bash
39
+ which yt-dlp || command -v yt-dlp
40
+ ```
41
+
42
+ ### If Not Installed
43
+
44
+ Attempt automatic installation based on the system:
45
+
46
+ **macOS (Homebrew)**:
47
+ ```bash
48
+ brew install yt-dlp
49
+ ```
50
+
51
+ **Linux (apt/Debian/Ubuntu)**:
52
+ ```bash
53
+ sudo apt update && sudo apt install -y yt-dlp
54
+ ```
55
+
56
+ **Alternative (pip - works on all systems)**:
57
+ ```bash
58
+ pip3 install yt-dlp
59
+ # or
60
+ python3 -m pip install yt-dlp
61
+ ```
62
+
63
+ **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
64
+
65
+ ## Check Available Subtitles
66
+
67
+ **ALWAYS do this first** before attempting to download:
68
+
69
+ ```bash
70
+ yt-dlp --list-subs "YOUTUBE_URL"
71
+ ```
72
+
73
+ This shows what subtitle types are available without downloading anything. Look for:
74
+ - Manual subtitles (better quality)
75
+ - Auto-generated subtitles (usually available)
76
+ - Available languages
77
+
78
+ ## Download Strategy
79
+
80
+ ### Option 1: Manual Subtitles (Preferred)
81
+
82
+ Try this first - highest quality, human-created:
83
+
84
+ ```bash
85
+ yt-dlp --write-sub --skip-download --output "OUTPUT_NAME" "YOUTUBE_URL"
86
+ ```
87
+
88
+ ### Option 2: Auto-Generated Subtitles (Fallback)
89
+
90
+ If manual subtitles aren't available:
91
+
92
+ ```bash
93
+ yt-dlp --write-auto-sub --skip-download --output "OUTPUT_NAME" "YOUTUBE_URL"
94
+ ```
95
+
96
+ Both commands create a `.vtt` file (WebVTT subtitle format).
97
+
98
+ ## Option 3: Whisper Transcription (Last Resort)
99
+
100
+ **ONLY use this if both manual and auto-generated subtitles are unavailable.**
101
+
102
+ ### Step 1: Show File Size and Ask for Confirmation
103
+
104
+ ```bash
105
+ # Get audio file size estimate
106
+ yt-dlp --print "%(filesize,filesize_approx)s" -f "bestaudio" "YOUTUBE_URL"
107
+
108
+ # Or get duration to estimate
109
+ yt-dlp --print "%(duration)s %(title)s" "YOUTUBE_URL"
110
+ ```
111
+
112
+ **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?"
113
+
114
+ **Wait for user confirmation before continuing.**
115
+
116
+ ### Step 2: Check for Whisper Installation
117
+
118
+ ```bash
119
+ command -v whisper
120
+ ```
121
+
122
+ 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."
123
+
124
+ **Wait for user confirmation before installing.**
125
+
126
+ Install if approved:
127
+ ```bash
128
+ pip3 install openai-whisper
129
+ ```
130
+
131
+ ### Step 3: Download Audio Only
132
+
133
+ ```bash
134
+ yt-dlp -x --audio-format mp3 --output "audio_%(id)s.%(ext)s" "YOUTUBE_URL"
135
+ ```
136
+
137
+ ### Step 4: Transcribe with Whisper
138
+
139
+ ```bash
140
+ # Auto-detect language (recommended)
141
+ whisper audio_VIDEO_ID.mp3 --model base --output_format vtt
142
+
143
+ # Or specify language if known
144
+ whisper audio_VIDEO_ID.mp3 --model base --language en --output_format vtt
145
+ ```
146
+
147
+ **Model Options** (stick to `base` for now):
148
+ - `tiny` - fastest, least accurate (~1GB)
149
+ - `base` - good balance (~1GB) ← **USE THIS**
150
+ - `small` - better accuracy (~2GB)
151
+ - `medium` - very good (~5GB)
152
+ - `large` - best accuracy (~10GB)
153
+
154
+ ### Step 5: Cleanup
155
+
156
+ After transcription completes, ask user: "Transcription complete! Would you like me to delete the audio file to save space?"
157
+
158
+ If yes:
159
+ ```bash
160
+ rm audio_VIDEO_ID.mp3
161
+ ```
162
+
163
+ ## Getting Video Information
164
+
165
+ ### Extract Video Title (for filename)
166
+
167
+ ```bash
168
+ yt-dlp --print "%(title)s" "YOUTUBE_URL"
169
+ ```
170
+
171
+ Use this to create meaningful filenames based on the video title. Clean the title for filesystem compatibility:
172
+ - Replace `/` with `-`
173
+ - Replace special characters that might cause issues
174
+ - Consider using sanitized version: `$(yt-dlp --print "%(title)s" "URL" | tr '/' '-' | tr ':' '-')`
175
+
176
+ ## Post-Processing
177
+
178
+ ### Convert to Plain Text (Recommended)
179
+
180
+ YouTube's auto-generated VTT files contain **duplicate lines** because captions are shown progressively with overlapping timestamps. Always deduplicate when converting to plain text while preserving the original speaking order.
181
+
182
+ ```bash
183
+ python3 -c "
184
+ import sys, re
185
+ seen = set()
186
+ with open('transcript.en.vtt', 'r') as f:
187
+ for line in f:
188
+ line = line.strip()
189
+ if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
190
+ clean = re.sub('<[^>]*>', '', line)
191
+ clean = clean.replace('&amp;', '&').replace('&gt;', '>').replace('&lt;', '<')
192
+ if clean and clean not in seen:
193
+ print(clean)
194
+ seen.add(clean)
195
+ " > transcript.txt
196
+ ```
197
+
198
+ ### Complete Post-Processing with Video Title
199
+
200
+ ```bash
201
+ # Get video title
202
+ VIDEO_TITLE=$(yt-dlp --print "%(title)s" "YOUTUBE_URL" | tr '/' '_' | tr ':' '-' | tr '?' '' | tr '"' '')
203
+
204
+ # Find the VTT file
205
+ VTT_FILE=$(ls *.vtt | head -n 1)
206
+
207
+ # Convert with deduplication
208
+ python3 -c "
209
+ import sys, re
210
+ seen = set()
211
+ with open('$VTT_FILE', 'r') as f:
212
+ for line in f:
213
+ line = line.strip()
214
+ if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
215
+ clean = re.sub('<[^>]*>', '', line)
216
+ clean = clean.replace('&amp;', '&').replace('&gt;', '>').replace('&lt;', '<')
217
+ if clean and clean not in seen:
218
+ print(clean)
219
+ seen.add(clean)
220
+ " > "${VIDEO_TITLE}.txt"
221
+
222
+ echo "✓ Saved to: ${VIDEO_TITLE}.txt"
223
+
224
+ # Clean up VTT file
225
+ rm "$VTT_FILE"
226
+ echo "✓ Cleaned up temporary VTT file"
227
+ ```
228
+
229
+ ## Output Formats
230
+
231
+ - **VTT format** (`.vtt`): Includes timestamps and formatting, good for video players
232
+ - **Plain text** (`.txt`): Just the text content, good for reading or analysis
233
+
234
+ ## Tips
235
+
236
+ - The filename will be `{output_name}.{language_code}.vtt` (e.g., `transcript.en.vtt`)
237
+ - Most YouTube videos have auto-generated English subtitles
238
+ - Some videos may have multiple language options
239
+ - If auto-subtitles aren't available, try `--write-sub` instead for manual subtitles
240
+
241
+ ## Complete Workflow Example
242
+
243
+ ```bash
244
+ VIDEO_URL="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
245
+
246
+ # Get video title for filename
247
+ VIDEO_TITLE=$(yt-dlp --print "%(title)s" "$VIDEO_URL" | tr '/' '_' | tr ':' '-' | tr '?' '' | tr '"' '')
248
+ OUTPUT_NAME="transcript_temp"
249
+
250
+ # ============================================
251
+ # STEP 1: Check if yt-dlp is installed
252
+ # ============================================
253
+ if ! command -v yt-dlp &> /dev/null; then
254
+ echo "yt-dlp not found, attempting to install..."
255
+ if command -v brew &> /dev/null; then
256
+ brew install yt-dlp
257
+ elif command -v apt &> /dev/null; then
258
+ sudo apt update && sudo apt install -y yt-dlp
259
+ else
260
+ pip3 install yt-dlp
261
+ fi
262
+ fi
263
+
264
+ # ============================================
265
+ # STEP 2: List available subtitles
266
+ # ============================================
267
+ echo "Checking available subtitles..."
268
+ yt-dlp --list-subs "$VIDEO_URL"
269
+
270
+ # ============================================
271
+ # STEP 3: Try manual subtitles first
272
+ # ============================================
273
+ echo "Attempting to download manual subtitles..."
274
+ if yt-dlp --write-sub --skip-download --output "$OUTPUT_NAME" "$VIDEO_URL" 2>/dev/null; then
275
+ echo "✓ Manual subtitles downloaded successfully!"
276
+ ls -lh ${OUTPUT_NAME}.*
277
+ else
278
+ # ============================================
279
+ # STEP 4: Fallback to auto-generated
280
+ # ============================================
281
+ echo "Manual subtitles not available. Trying auto-generated..."
282
+ if yt-dlp --write-auto-sub --skip-download --output "$OUTPUT_NAME" "$VIDEO_URL" 2>/dev/null; then
283
+ echo "✓ Auto-generated subtitles downloaded successfully!"
284
+ ls -lh ${OUTPUT_NAME}.*
285
+ else
286
+ # ============================================
287
+ # STEP 5: Last resort - Whisper transcription
288
+ # ============================================
289
+ echo "⚠ No subtitles available for this video."
290
+
291
+ # Get file size
292
+ FILE_SIZE=$(yt-dlp --print "%(filesize_approx)s" -f "bestaudio" "$VIDEO_URL")
293
+ DURATION=$(yt-dlp --print "%(duration)s" "$VIDEO_URL")
294
+ TITLE=$(yt-dlp --print "%(title)s" "$VIDEO_URL")
295
+
296
+ echo "Video: $TITLE"
297
+ echo "Duration: $((DURATION / 60)) minutes"
298
+ echo "Audio size: ~$((FILE_SIZE / 1024 / 1024)) MB"
299
+ echo ""
300
+ echo "Would you like to download and transcribe with Whisper? (y/n)"
301
+ read -r RESPONSE
302
+
303
+ if [[ "$RESPONSE" =~ ^[Yy]$ ]]; then
304
+ # Check for Whisper
305
+ if ! command -v whisper &> /dev/null; then
306
+ echo "Whisper not installed. Install now? (requires ~1-3GB) (y/n)"
307
+ read -r INSTALL_RESPONSE
308
+ if [[ "$INSTALL_RESPONSE" =~ ^[Yy]$ ]]; then
309
+ pip3 install openai-whisper
310
+ else
311
+ echo "Cannot proceed without Whisper. Exiting."
312
+ exit 1
313
+ fi
314
+ fi
315
+
316
+ # Download audio
317
+ echo "Downloading audio..."
318
+ yt-dlp -x --audio-format mp3 --output "audio_%(id)s.%(ext)s" "$VIDEO_URL"
319
+
320
+ # Get the actual audio filename
321
+ AUDIO_FILE=$(ls audio_*.mp3 | head -n 1)
322
+
323
+ # Transcribe
324
+ echo "Transcribing with Whisper (this may take a few minutes)..."
325
+ whisper "$AUDIO_FILE" --model base --output_format vtt
326
+
327
+ # Cleanup
328
+ echo "Transcription complete! Delete audio file? (y/n)"
329
+ read -r CLEANUP_RESPONSE
330
+ if [[ "$CLEANUP_RESPONSE" =~ ^[Yy]$ ]]; then
331
+ rm "$AUDIO_FILE"
332
+ echo "Audio file deleted."
333
+ fi
334
+
335
+ ls -lh *.vtt
336
+ else
337
+ echo "Transcription cancelled."
338
+ exit 0
339
+ fi
340
+ fi
341
+ fi
342
+
343
+ # ============================================
344
+ # STEP 6: Convert to readable plain text with deduplication
345
+ # ============================================
346
+ VTT_FILE=$(ls ${OUTPUT_NAME}*.vtt 2>/dev/null || ls *.vtt | head -n 1)
347
+ if [ -f "$VTT_FILE" ]; then
348
+ echo "Converting to readable format and removing duplicates..."
349
+ python3 -c "
350
+ import sys, re
351
+ seen = set()
352
+ with open('$VTT_FILE', 'r') as f:
353
+ for line in f:
354
+ line = line.strip()
355
+ if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
356
+ clean = re.sub('<[^>]*>', '', line)
357
+ clean = clean.replace('&amp;', '&').replace('&gt;', '>').replace('&lt;', '<')
358
+ if clean and clean not in seen:
359
+ print(clean)
360
+ seen.add(clean)
361
+ " > "${VIDEO_TITLE}.txt"
362
+ echo "✓ Saved to: ${VIDEO_TITLE}.txt"
363
+
364
+ # Clean up temporary VTT file
365
+ rm "$VTT_FILE"
366
+ echo "✓ Cleaned up temporary VTT file"
367
+ else
368
+ echo "⚠ No VTT file found to convert"
369
+ fi
370
+
371
+ echo "✓ Complete!"
372
+ ```
373
+
374
+ **Note**: This complete workflow handles all scenarios with proper error checking and user prompts at each decision point.
375
+
376
+ ## Error Handling
377
+
378
+ ### Common Issues and Solutions:
379
+
380
+ **1. yt-dlp not installed**
381
+ - Attempt automatic installation based on system (Homebrew/apt/pip)
382
+ - If installation fails, provide manual installation link
383
+ - Verify installation before proceeding
384
+
385
+ **2. No subtitles available**
386
+ - List available subtitles first to confirm
387
+ - Try both `--write-sub` and `--write-auto-sub`
388
+ - If both fail, offer Whisper transcription option
389
+ - Show file size and ask for user confirmation before downloading audio
390
+
391
+ **3. Invalid or private video**
392
+ - Check if URL is correct format: `https://www.youtube.com/watch?v=VIDEO_ID`
393
+ - Some videos may be private, age-restricted, or geo-blocked
394
+ - Inform user of the specific error from yt-dlp
395
+
396
+ **4. Whisper installation fails**
397
+ - May require system dependencies (ffmpeg, rust)
398
+ - Provide fallback: "Install manually with: `pip3 install openai-whisper`"
399
+ - Check available disk space (models require 1-10GB depending on size)
400
+
401
+ **5. Download interrupted or failed**
402
+ - Check internet connection
403
+ - Verify sufficient disk space
404
+ - Try again with `--no-check-certificate` if SSL issues occur
405
+
406
+ **6. Multiple subtitle languages**
407
+ - By default, yt-dlp downloads all available languages
408
+ - Can specify with `--sub-langs en` for English only
409
+ - List available with `--list-subs` first
410
+
411
+ ### Best Practices:
412
+
413
+ - ✅ Always check what's available before attempting download (`--list-subs`)
414
+ - ✅ Verify success at each step before proceeding to next
415
+ - ✅ Ask user before large downloads (audio files, Whisper models)
416
+ - ✅ Clean up temporary files after processing
417
+ - ✅ Provide clear feedback about what's happening at each stage
418
+ - ✅ Handle errors gracefully with helpful messages