first
This commit is contained in:
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
name: youtube-transcript
|
||||
description: Extract transcripts from YouTube videos. Use when the user asks for a transcript, subtitles, or captions of a YouTube video and provides a YouTube URL (youtube.com/watch?v=, youtu.be/, or similar). Supports output with or without timestamps.
|
||||
---
|
||||
|
||||
# YouTube Transcript
|
||||
|
||||
Extract transcripts from YouTube videos using the youtube-transcript-api.
|
||||
|
||||
## Usage
|
||||
|
||||
Run the script with a YouTube URL or video ID:
|
||||
|
||||
```bash
|
||||
uv run scripts/get_transcript.py "VIDEO_URL_OR_ID"
|
||||
```
|
||||
|
||||
With timestamps:
|
||||
|
||||
```bash
|
||||
uv run scripts/get_transcript.py "VIDEO_URL_OR_ID" --timestamps
|
||||
```
|
||||
|
||||
## Defaults
|
||||
|
||||
- **Without timestamps** (default): Plain text, one line per caption segment
|
||||
- **With timestamps**: `[MM:SS] text` format (or `[HH:MM:SS]` for longer videos)
|
||||
|
||||
## Supported URL Formats
|
||||
|
||||
- `https://www.youtube.com/watch?v=VIDEO_ID`
|
||||
- `https://youtu.be/VIDEO_ID`
|
||||
- `https://youtube.com/embed/VIDEO_ID`
|
||||
- Raw video ID (11 characters)
|
||||
|
||||
## Output
|
||||
|
||||
- CRITICAL: YOU MUST NEVER MODIFY THE RETURNED TRANSCRIPT
|
||||
- If the transcript is without timestamps, you SHOULD clean it up so that it is arranged by complete paragraphs and the lines don't cut in the middle of sentences.
|
||||
- If you were asked to save the transcript to a specific file, save it to the requested file.
|
||||
- If no output file was specified, use the YouTube video ID with a `-transcript.txt` suffix.
|
||||
|
||||
## Notes
|
||||
|
||||
- Fetches auto-generated or manually added captions (whichever is available)
|
||||
- Requires the video to have captions enabled
|
||||
- Falls back to auto-generated captions if manual ones aren't available
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env -S uv run --script
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = ["youtube-transcript-api>=1.0.0"]
|
||||
# ///
|
||||
"""
|
||||
Extract transcript from a YouTube video.
|
||||
|
||||
Usage:
|
||||
uv run scripts/get_transcript.py <video_id_or_url> [--timestamps]
|
||||
"""
|
||||
|
||||
import sys
|
||||
import re
|
||||
import argparse
|
||||
from youtube_transcript_api import YouTubeTranscriptApi
|
||||
|
||||
|
||||
def extract_video_id(url_or_id: str) -> str:
|
||||
"""Extract video ID from various YouTube URL formats or return as-is if already an ID."""
|
||||
patterns = [
|
||||
r'(?:youtube\.com/watch\?v=|youtu\.be/|youtube\.com/embed/|youtube\.com/v/)([a-zA-Z0-9_-]{11})',
|
||||
r'^([a-zA-Z0-9_-]{11})$'
|
||||
]
|
||||
for pattern in patterns:
|
||||
match = re.search(pattern, url_or_id)
|
||||
if match:
|
||||
return match.group(1)
|
||||
raise ValueError(f"Could not extract video ID from: {url_or_id}")
|
||||
|
||||
|
||||
def format_timestamp(seconds: float) -> str:
|
||||
"""Convert seconds to HH:MM:SS or MM:SS format."""
|
||||
hours = int(seconds // 3600)
|
||||
minutes = int((seconds % 3600) // 60)
|
||||
secs = int(seconds % 60)
|
||||
if hours > 0:
|
||||
return f"{hours:02d}:{minutes:02d}:{secs:02d}"
|
||||
return f"{minutes:02d}:{secs:02d}"
|
||||
|
||||
|
||||
def get_transcript(video_id: str, with_timestamps: bool = False) -> str:
|
||||
"""Fetch and format transcript for a YouTube video."""
|
||||
api = YouTubeTranscriptApi()
|
||||
transcript = api.fetch(video_id)
|
||||
|
||||
if with_timestamps:
|
||||
lines = [f"[{format_timestamp(snippet.start)}] {snippet.text}" for snippet in transcript.snippets]
|
||||
else:
|
||||
lines = [snippet.text for snippet in transcript.snippets]
|
||||
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Get YouTube video transcript')
|
||||
parser.add_argument('video', help='YouTube video URL or video ID')
|
||||
parser.add_argument('--timestamps', '-t', action='store_true',
|
||||
help='Include timestamps in output')
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
video_id = extract_video_id(args.video)
|
||||
transcript = get_transcript(video_id, with_timestamps=args.timestamps)
|
||||
print(transcript)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user