"""YouTube transcript retrieval without downloading video media.""" from __future__ import annotations import re def video_id(url: str) -> str: match = re.search(r"(?:v=|youtu\.be/|shorts/)([A-Za-z0-9_-]{11})", url) if not match: raise ValueError("Could not parse a YouTube video id") return match.group(1) def fetch_youtube_transcript(url: str, languages: tuple[str, ...] = ("en",)) -> str: """Return a timestamped YouTube transcript using the public transcript API.""" from youtube_transcript_api import YouTubeTranscriptApi identifier = video_id(url) api = YouTubeTranscriptApi() fetched = api.fetch(identifier, languages=list(languages)) snippets = [] for item in fetched: start = float(getattr(item, "start", 0.0)) text = str(getattr(item, "text", "")).replace("\n", " ").strip() snippets.append(f"[{start:.1f}s] {text}") if not snippets: raise RuntimeError("YouTube returned an empty transcript") return "\n".join(snippets) def find_transcript_context(transcript: str, quote: str, window: int = 3) -> str: """Find a quoted dialogue line and return nearby timestamped transcript lines.""" lines = transcript.splitlines() needle = re.sub(r"[^a-z0-9 ]", "", quote.lower()) for index, line in enumerate(lines): haystack = re.sub(r"[^a-z0-9 ]", "", line.lower()) if needle and needle in haystack: return "\n".join(lines[max(0, index - window) : index + window + 1]) return transcript