claude-code · git:20260213.c022c71 · 2026-02-13 · sha256 d6cbc8bb5f4288b7
claude-code git:20260213.c022c71C
Immutable. This exact content never changes and is served at /api/v1/blob/d6cbc8bb5f4288b7.
# YouTube Transcriber
Capture transcripts from YouTube videos using a local transcription service. The service fetches official YouTube captions when available, or transcribes locally using Whisper.
## When to Use
Use this skill when the user wants to:
- Transcribe a YouTube video
- Get the transcript or captions from a video
- Extract what was said in a YouTube video
- Capture dialogue from a YouTube video for analysis
## Prerequisites
The YouTube Transcriber service must be running at `http://127.0.0.1:19720`.
To check if it's running:
```bash
curl -s http://127.0.0.1:19720/api/transcripts | head -c 100
```
If not running, the user needs to start it in their youtube-transcriber project directory:
```bash
npm run dev
```
## API Endpoints
Base URL: `http://127.0.0.1:19720`
### Capture a Transcript
```bash
curl -X POST 'http://127.0.0.1:19720/api/transcripts' \
-H 'Content-Type: application/json' \
-d '{"url": "YOUTUBE_URL"}'
```
**Response:**
```json
{
"id": "abc123",
"videoId": "dQw4w9WgXcQ",
"title": "Video Title",
"author": "Channel Name",
"videoUrl": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"transcript": "[{\"text\":\"Hello\",\"startMs\":0,\"durationMs\":1500}]",
"source": "youtube_captions",
"createdAt": "2025-01-15T10:30:00.000Z"
}
```
The `transcript` field is a JSON string. Parse it to get an array of segments:
- `text`: The spoken words
- `startMs`: Start time in milliseconds
- `durationMs`: Duration in milliseconds
The `source` field indicates:
- `youtube_captions`: Fetched from YouTube (fast)
- `whisper_local`: Transcribed with Whisper (slower, 1-5 min)
### List All Transcripts
```bash
curl 'http://127.0.0.1:19720/api/transcripts'
```
### Search Transcripts
```bash
curl 'http://127.0.0.1:19720/api/transcripts?q=SEARCH_TERM'
```
### Get Single Transcript
```bash
curl 'http://127.0.0.1:19720/api/transcripts/ID'
```
### Delete Transcript
```bash
curl -X DELETE 'http://127.0.0.1:19720/api/transcripts/ID'
```
## Formatting Transcripts
When displaying transcripts, format timestamps as `[MM:SS]`:
```python
import json
def format_transcript(transcript_json: str) -> str:
segments = json.loads(transcript_json)
lines = []
for seg in segments:
ms = seg['startMs']
minutes = ms // 60000
seconds = (ms % 60000) // 1000
lines.append(f"[{minutes}:{seconds:02d}] {seg['text']}")
return "\n".join(lines)
```
Or in bash:
```bash
echo "$TRANSCRIPT_JSON" | python3 -c "
import json, sys
for seg in json.load(sys.stdin):
ms = seg['startMs']
print(f'[{ms//60000}:{(ms%60000)//1000:02d}] {seg[\"text\"]}')
"
```
## Example Workflow
When user asks: "Transcribe https://youtube.com/watch?v=abc123"
```bash
# 1. Capture the transcript
RESPONSE=$(curl -s -X POST 'http://127.0.0.1:19720/api/transcripts' \
-H 'Content-Type: application/json' \
-d '{"url": "https://youtube.com/watch?v=abc123"}')
# 2. Check for errors
if echo "$RESPONSE" | grep -q '"error"'; then
echo "Error: $(echo "$RESPONSE" | jq -r '.error')"
exit 1
fi
# 3. Extract metadata
TITLE=$(echo "$RESPONSE" | jq -r '.title')
AUTHOR=$(echo "$RESPONSE" | jq -r '.author')
SOURCE=$(echo "$RESPONSE" | jq -r '.source')
ID=$(echo "$RESPONSE" | jq -r '.id')
echo "✓ Captured: $TITLE"
echo " Author: $AUTHOR"
echo " Source: $SOURCE"
echo " ID: $ID"
# 4. Format and display transcript
echo ""
echo "Transcript:"
echo "$RESPONSE" | jq -r '.transcript' | python3 -c "
import json, sys
for seg in json.load(sys.stdin):
ms = seg['startMs']
print(f'[{ms//60000}:{(ms%60000)//1000:02d}] {seg[\"text\"]}')
"
```
## Error Handling
| Status | Meaning | Action |
|--------|---------|--------|
| 200/201 | Success | Process response |
| 400 | Invalid URL | Check URL format |
| 404 | Video not found | Verify URL is correct |
| 429 | Rate limited | Wait 1-2 minutes, retry |
| 500 | Server error | Check if service is running |
| Connection refused | Service not running | User needs to run `npm run dev` |
## Supported URL Formats
- `https://www.youtube.com/watch?v=VIDEO_ID`
- `https://youtu.be/VIDEO_ID`
- `https://www.youtube.com/shorts/VIDEO_ID`
- `https://www.youtube.com/embed/VIDEO_ID`
- URLs with additional parameters (playlists, timestamps)
## Notes
- Submitting a duplicate URL returns the existing transcript (no re-processing)
- Videos without captions use local Whisper transcription (can take several minutes)
- Transcripts are stored locally in SQLite and persist across sessions