Video Summarize (from YouTube text metadata)
When to use
- The user posts a YouTube URL/short/ID and asks to summarize or explain it.
- The goal is the video's topic/content (title + description + chapters), not a word-for-word spoken transcript.
Core problem (2026-10-16)
yt-dlp's subtitle path is blocked by YouTube's bot check — it returns
Sign in to confirm you're not a bot and --write-sub / --list-subs fail
before downloading. Transcript APIs and timedtext endpoints behave the same
without cookies. Do not spend tool-calls fighting yt-dlp.
The video's own HTML page embeds everything needed to summarize: title + full description (which includes a chapter list). Summarizing only needs that text.
Procedure
-
Fetch the page. Save it locally.
curl -sL --max-time 60 "https://www.youtube.com/watch?v=<ID>" \ -H "User-Agent: Mozilla/5.0 ...Chrome/120.0 Safari/537.36" -o yt_page.htmlAlways quote the URL. A bare
?/&is shell-special. A 1–4 MB HTML file is expected and fine. -
Extract text metadata. Use the helper (handles the payload quirks described in Pitfalls):
python3 skills/video-summarize/scripts/extract.py "https://www.youtube.com/watch?v=<ID>" > video_meta.txtThe helper prints
TITLE:, optionalLENGTH_SEC:/VIEW_COUNT:/PUBLISH:, the fullDESCRIPTION:, and aCHAPTERS:list. If the helper returns empty, see Pitfalls for the manual extraction pattern. (yt-dlp is optional here — only run it if cookies are available, e.g. to add captions. If it fails on the bot check, rely on the page extraction.) -
Summarize from the extracted text.
- Use the title as the topic; use description body as the substance; use
CHAPTERSto structure the summary by time code (the chapters usually are an accurate outline). - Do not invent timestamps, quotes, or facts not present in the extracted text. If descriptions/chapters are missing, state that the summary is from available metadata only.
- Use the title as the topic; use description body as the substance; use
-
Deliver. Send the summary in the user's session. Optionally note the creator and where to learn more (links are in the description).
Completion
The summary is done when it reflects the extracted title + description body + chapters, with no fabricated details. If the page fetch failed or the metadata was empty, report the blocker and offer the yt-dlp+cookies path.
Pitfalls
The description is stored in the page as a single JSON run whose internal
line breaks are the literal two-character sequence \n and whose value is
JSON-escaped (", \u0026, \xa0, etc.). Extracting it correctly:
- Read the substring from
attributedDescriptionto thecommandRunsboundary, take the content value between its surrounding quotes. html.unescape()first, then replace the literal\nwith real newlines (.replace("\\n", "\n")). Without this, the description is one line and the chapter list is not detectable.- Do not try to JSON-parse the whole page (the payload is huge, nested, and partially unquoted). Targeted slicing works; full parse reliably fails.
- YouTube also blocks direct
timedtextAPI calls without cookies.
See also
local-sttskill — transcribe spoken audio/voice messages to text.firecrawl-scrapeskill — scrape other websites to markdown.
