publicapidata
Guide

Conference talk transcripts: read a whole track

How to turn a conference playlist into searchable text, find the talks worth watching, and cite quotes with timestamps that link to the moment.

A recorded conference track is usually 25 to 40 talks and 20 to 30 hours of video. Reading it as text takes an afternoon, and you can search it. This guide covers finding the playlist, getting the text out, searching across all the talks at once, quoting with a timestamp that links back to the video, and what to do about the talks that have no captions.

Nothing here needs a YouTube API key. The official Data API does not return auto-generated captions at all, which is what most conference recordings have.

What you actually get from a conference playlist

You get one plain-text transcript per talk, plus the metadata that makes the set usable: the talk title, the speaker’s channel, the video URL, the duration, and whether the captions were human-authored or machine-generated.

FieldWhy it matters for a conference track
titleThe talk title, as the organisers published it
videoUrlWhat you link back to when you quote something
durationSecondsLets you sort a track by length — lightning talks versus keynotes
fullTextThe whole talk as one string. This is what you search
isAutoGeneratedtrue means machine captions: expect wrong names and mangled jargon
segmentsTimestamped chunks, so a quote can carry the moment it was said
success / errorCodeTells you which talks came back empty, and why

Two things that are not in there and cannot be: speaker labels, and slide content. Captions are one undifferentiated stream of words. If a talk is a panel, you get everything everyone said with no indication of who said it.

Find the playlist for the track

Conference channels are inconsistent. Some publish one playlist per track, some one per day, some dump everything into the channel and never build a playlist at all.

  1. Open the conference’s YouTube channel and click Playlists. Sort by Date added — the current year’s tracks are usually at the top.
  2. Look for the track name in the playlist title. Large conferences name them plainly: “Observability track”, “Day 2 — Main stage”.
  3. Open the playlist and check the video count against the published schedule. A playlist with 12 videos against a 30-talk schedule means the upload is still in progress, or the track is split.
  4. Copy the URL. It looks like youtube.com/playlist?list=PL.... The list= value is the playlist ID and is the only part that matters.
  5. If you are on a watch page rather than the playlist page, the URL still carries &list=PL.... That works as an input too.

If there is no playlist for the track, you have two options: collect the individual video URLs from the schedule page, or take the whole channel and filter afterwards by title and upload date. For a single-day event, the channel-wide approach is usually less work than assembling 30 URLs by hand.

Watch for the UU prefix. A playlist ID beginning UU rather than PL is a channel’s automatic uploads playlist, not a curated track. It contains everything the channel has ever posted.

Get the text out

The mechanics are the same whichever tool you use: give it the playlist, cap the number of videos, and ask for timestamps if you plan to cite anything.

Three decisions worth making before you run anything:

DecisionRecommendation for a conference track
Video capSet it slightly above the talk count. It is your cost and runtime ceiling
LanguagePick the language the talks were given in, not your own
TimestampsTurn them on. Retro-fitting them means running the whole track again

Timestamps roughly triple the size of the output, because every few seconds of speech becomes its own record with a start time and a duration. For a 30-talk track that is the difference between a file you can open in a text editor and one you cannot. Keep the plain text for reading and the timestamped version for citation, and store them separately.

Run it once, keep the raw output, and do all your filtering on the saved copy. Conference playlists get edited after the fact — talks are re-uploaded, embargoed talks appear late — so a dated snapshot is worth more than a live query.

Search across every talk at once

This is the reason to do any of it. Once the track is text, one search tells you which talks discuss the thing you care about, and you watch only those.

With the output saved as JSON Lines, one row per talk:

# Which talks mention Postgres at all, and how often
grep -c -i postgres track.jsonl

# List the titles of talks that mention it
jq -r 'select(.fullText | test("postgres"; "i")) | .title' track.jsonl

# Rank talks by how much they dwell on a topic
jq -r 'select(.success) |
  [ (.fullText | ascii_downcase | [splits("postgres")] | length - 1), .title ]
  | @tsv' track.jsonl | sort -rn | head -10

That last one is the useful one. A talk that says “Postgres” forty times is about Postgres. A talk that says it twice mentioned it in passing, and you can skip it.

For reading rather than filtering, dump each transcript to its own file named after the talk, then use whatever you normally use to search a folder — ripgrep, an editor’s project search, Obsidian, anything:

jq -r 'select(.success) |
  "\(.videoId)\t\(.title)\t\(.fullText)"' track.jsonl |
while IFS=$'\t' read -r id title text; do
  printf '%s\n\n%s\n' "$title" "$text" > "talks/${id}.txt"
done

Naming files by video ID rather than by title avoids the whole class of problems that arise when a talk is called Scaling Kafka: 0 -> 1M msg/s (a war story).

Reading a track efficiently

A three-pass approach costs about two hours for a 30-talk track:

  1. Skim the openings. The first 200 words of a talk state its thesis. Extract them for all 30 and read them as one document — that is 6,000 words and it tells you what the track is about.
  2. Grep for your questions. Not topics: questions. “How did anyone deal with X” is a search for the phrase people use when they hit X.
  3. Read three talks properly, watch one. The talk you watch should be the one where the demo matters, because the demo is exactly what the transcript cannot give you.

Quote a talk with a timestamp

A timestamped transcript lets you link to the second a point was made. YouTube accepts a t parameter in seconds on any watch URL:

https://www.youtube.com/watch?v=VIDEO_ID&t=1284s

Each timestamped segment carries a start value in seconds and the text spoken from that point. To find the link for a phrase, search the segments and take the start of the matching one:

jq -r 'select(.success) | . as $v | .segments[] |
  select(.text | test("blast radius"; "i")) |
  "\($v.title)\n  https://www.youtube.com/watch?v=\($v.videoId)&t=\(.start | floor)s\n  \(.text)"' \
  track.jsonl

Two practical notes. Segments break mid-sentence, so a phrase that spans a boundary will not match — search for three or four words, not a whole sentence. And start the link five to ten seconds early, because a quote landed cold is confusing; the sentence before it is usually the setup.

Before you publish a quote from machine-generated captions, watch those ten seconds and check the wording. Auto-captions get the shape of a sentence right and the specifics wrong, and the specifics are what you are quoting.

Talks with no captions

Some talks have no captions, and no transcript tool can produce one. If the uploader disabled captions and YouTube’s automatic system did not run or was turned off, there is nothing published to extract. This is a property of the video, not a fault in the extraction.

In a conference track, it is usually a small and predictable set:

SituationWhy it has no captionsWhat you can do
Uploaded within the last few hoursAutomatic captions have not finished processingWait a day and re-run
Talk given in a language YouTube does not auto-captionNo automatic track is generatedNothing, unless the organisers upload subtitles
Captions disabled by the uploaderA deliberate channel settingAsk the organisers; they often enable it on request
Heavy music or poor room audioAutomatic captioning declines to produce a trackNothing
Video is private, unlisted or region-lockedNot publicly retrievableNothing

Handle it by filtering rather than by worrying about it. Split the output into the talks that returned text and the ones that did not, and treat the second list as your manual watch list:

jq -r 'select(.success | not) | [.errorCode, .title] | @tsv' track.jsonl

For a handful of caption-less talks, the fallback is a speech-to-text model run over the audio locally. That is a different job with a different cost profile, and it is worth doing for three talks, not thirty.

Limitations

Stated plainly, because most of these cannot be worked around:

  • Videos without captions return nothing. No tool can extract a transcript that was never published. Expect a few per track.
  • Private and unlisted playlists return no videos. If you cannot open the playlist in a logged-out browser, extraction cannot see it either.
  • No speaker labels. Captions are a single stream. Panels and Q&A sections come back as one undivided block of text.
  • Automatic captions contain errors, concentrated exactly where a conference talk is dense: names, library names, acronyms, numbers. Verify anything you quote.
  • No slides, no diagrams, no code on screen. A talk that leans on its visuals reads as gibberish in text. “As you can see here” is a marker that you need to watch that section.
  • Punctuation and paragraphing are approximate. Automatic captions produce a run-on stream. It is readable, but it is not prose.
  • Playlists change. Videos are removed, re-uploaded and re-ordered after the event. Two runs a month apart will not match.
  • Timestamps drift slightly relative to the spoken word, typically by under a second. Fine for citation, not for frame-accurate clipping.

Do I need a YouTube API key for this?

No. Caption tracks are not served by the official Data API — it cannot return auto-generated captions under any circumstances, which is what the majority of conference uploads have. Transcript extraction reads the publicly served caption data instead, so there is no key, no OAuth flow and no quota to manage.

How long does a conference track take to process?

Extraction is bounded by the number of videos, not their length: a three-hour keynote costs the same as a five-minute lightning talk. A 30-talk track runs in a few minutes with concurrency in the region of ten. The reading is the slow part.

Can I get the transcript of a live-streamed talk?

Only after the stream has ended and been processed into a normal video. During the stream there is a live caption feed, but it is not published as a retrievable track. Wait for the VOD.

What about a conference that publishes to Vimeo or its own site?

This approach is specific to YouTube’s caption data. For talks hosted elsewhere, check whether the player exposes a WebVTT subtitle track — most do, and it is usually a plain file request away. Failing that, it is a speech-to-text job.

How accurate are the automatic captions on technical talks?

Good enough to search, not good enough to quote without checking. General English comes back close to verbatim. Product names, surnames and version numbers are where the errors cluster, and those are precisely the words you searched for. Treat a search hit as a pointer to a moment in the video, then confirm the wording by watching it.

Can I feed a whole track into a language model?

Yes, and it is one of the better uses of a track-wide extraction — “which of these talks disagree with each other” is a question no search box can answer. Watch the context window: 30 talks is roughly 400,000 to 700,000 words. Summarise each talk individually first, then reason over the summaries.

Reading publicly published caption data is not the issue; what you then do with it is. Personal research, search and note-taking are ordinary uses. Republishing a speaker’s transcript in full is a copyright question, and the answer is usually no without permission. Quote with attribution and a link to the timestamp, as you would with any source.

Hosted version

This page describes the problem. The hosted tool solves it at scale — bulk input, structured output, and no charge for videos that return nothing.

Run it on Apify