Getting material out of video — yt-dlp + speech-to-text
What this chapter covers The order of operations for turning a video into something you can read — and where in that order you get to skip the download entirely.
First — do you actually need the video?
Same question as the previous chapter. A video file is the heaviest and most fragile input in this guide. Work down this list.
| What you need | What to fetch | Rough size |
|---|---|---|
| What was said | Subtitles | KB |
| Title, description, length, view count | Metadata (JSON) | KB |
| The content of a video with no subtitles | Audio only | MB |
| What was on screen (slides, a product, on-screen text) | The video | Hundreds of MB |
Most real tasks end on the first two rows. "What has this channel been talking about lately", "summarise ten competitor launch videos" — none of that needs a video file.
graph TD
A["I need something out of a video"] --> B{"Are there subtitles"}
B -->|Yes| C["Fetch subtitles only — done"]
B -->|No| D["Fetch audio only"]
D --> E["Speech to text"]
C --> F["Summarise, classify, tabulate"]
E --> F
A --> G{"Do I need to see the screen"}
G -->|Yes| H["Only now, the video"]Then — are you allowed to?
This comes before the technical part. The tool solves none of it.
- Terms of service. Most video platforms restrict downloading in their terms. What is technically possible and what is permitted are different questions.
- Copyright. A video is a copyrighted work. Summarising a transcript for an internal decision and redistributing or re-editing the file you downloaded are entirely different things. The second is out of scope here.
- Behind a login or private. That runs into account terms. Downloading your own uploads from your own account is not the same as getting around a barrier.
- Personal data. A public video with people in it still needs a lawful basis to process.
- Load on their servers. Don't scrape a whole channel in one burst. Space the requests out.
The easiest case by far is your own channel, your own videos. Collecting your own subtitles or rewriting your past scripts sidesteps almost all of the above. For anything else, staying at the level of summarising for internal reading is the safe line.
The tool — yt-dlp, and that's it
There is effectively one choice here.
| What | State | |
|---|---|---|
| yt-dlp | Thousands of sites, YouTube · Instagram · TikTok included | The de facto standard. Updated weekly |
| youtube-dl | What yt-dlp was forked from | Stalled. Doesn't keep up with platform changes |
| Node libraries | Mostly YouTube-only | Break every time the platform shifts |
You need ffmpeg alongside it. yt-dlp calls it internally to merge separately downloaded video and audio streams, and to convert audio. Without it you get a half-finished file and a "could not merge" message.
Four commands
1. Metadata only — the cheapest
Title, duration, upload date, description and view count come back as one JSON blob. Use it for deciding what is worth watching. For a channel listing:
2. Subtitles only — usually the end of the job
--write-subs gets subtitles the uploader added; --write-auto-subs gets
the platform's machine-generated ones. Turn both on and use whichever
exists.
Auto-generated subtitles are not a faithful transcript. Proper nouns, numbers and product names are frequently wrong. Fine for a summary or for following the argument — but check the source before quoting or copying a number.
3. Audio only — when there are no subtitles
-x extracts audio only, which drops the size to single-digit percentages of
the video. The speech-to-text step that follows needs nothing more.
4. The video — only when you need the screen
-S "res:720" picks the best option that doesn't exceed 720p. There is
rarely a reason to pull the original quality — 720p is plenty for reading
material off the screen, and the size difference is several-fold.
Not downloading things twice
Records the id of everything fetched and skips it on the next run. Without this, a daily pipeline re-downloads the same videos forever.
Turning it into text
Once you have the audio, use the path from Working with speech and images as-is.
At this point the video has become text, and everything after it is the same as earlier in this guide. Create a task over the REST API and hand it the summarising, classifying and tabulating.
graph TD
A["1 Listing<br/>terminal"] --> B["2 Subtitles or audio<br/>terminal"]
B --> C["3 Speech to text<br/>model API"]
C --> D["4 Summarise<br/>task"]
D --> E["out/summary.md"]Step 3 is skipped entirely when subtitles exist. It is the most expensive box in the pipeline, so simply checking for subtitles in step 2 removes most of the cost.
Running it in HyperTeams
Collection has no judgement in it, so it belongs to terminal, not task —
the same slot as the collection step in
Case study — the content factory.
- Keep the files inside the working directory.
out/fills with binaries, so leave it out of version control. - It takes a while. Ten videos is minutes; with speech-to-text attached, more. That is a job for a schedule, not for sitting in front of the screen.
- Leave interpretation to the next
task. Mixing collection and judgement into one slot means you can't tell which half failed.
When you just want one video, in Connect
If all you need is a summary of a single video, right there in a team workspace, none of the above wiring applies. The web tool in tool settings already covers fetching YouTube content. Come back to this chapter when you want a whole channel, every day.
Upkeep — this one doesn't stay built either
| What | How |
|---|---|
| The platforms | Change without notice — Instagram and TikTok far more often than YouTube |
| yt-dlp | Follows behind and patches. A version a few days old may already fail |
| Subtitle availability | Auto-captions that existed yesterday can be gone today |
So do not pin the version. This is the opposite of your other dependencies.
And don't build a pipeline that assumes success. Quietly passing an empty result downstream is the worst outcome — the next step will invent a plausible summary out of nothing.
Common mistakes
Downloading the video before checking for subtitles
The most common one by far. Hundreds of megabytes and a speech-to-text run spent on something one subtitle check would have finished. That is why the order is subtitles → audio → video.
Quoting auto-captions as if they were the transcript
Said above, worth repeating: don't trust the numbers and proper nouns in machine-generated captions.
Scraping an entire channel in one go
You get blocked, it takes forever, and most of those videos weren't needed. Choose from metadata first, then fetch only what you chose.
Re-uploading what you downloaded
This chapter is about collecting material to read. Redistribution and re-editing are copyright questions, and no tool answers them for you.
Check yourself
1. You need to summarise ten videos. What do you fetch first?
Answer
Metadata and subtitles. If subtitles exist you are done — no video file and no speech-to-text step. You fetch the video only when you need to see the screen.
2. Why don't you pin the yt-dlp version?
Answer
Because the platforms keep changing and yt-dlp follows behind patching them. A pinned version fails silently one day. Unlike your other dependencies,
3. What should happen when collection returns zero items?
Answer
Don't write the result file — report failure. An empty result passed downstream becomes a plausible-sounding summary built on nothing, and at an hour when nobody is watching, that is what sticks.
Next, the extension that stops most Korean document automation → Korean official documents — hwp and hwpx