Elevating Video Transcripts as Searchable Content
I helped work on the Jamstack TV project (now dormant with the rest of the jamstack.org site, though the feature is still up), which used a lovely Algolia integration to allow deep searching of video transcripts. It was a really cool feature.
In The Static Chronicles Twitch stream (episode 1 and episode 2), Mike and I explored an 11ty plugin to output the transcript of a YouTube video to allow video transcripts to be embedded into video posts, thus extending some of this feature to work with Pagefind (the static search engine).
I’ve wired this up on a few video posts on my site (that I know have higher quality transcripts/captions):
- Live Editing an Eleventy Project in CloudCannon with Bookshop
- Building a multi-language Taylor Swift fan site (10 Minute Version) (Zach's Version)
- Eleventy and CloudCannon: New Best Friends
- The Eleventy v2.0 Release, a talk at the Eleventy Meetup
- Exploring the Bounds of Jamstack on What the Jam
The really cool part of these demos is that the actively playing video highlights the currently active portion of the transcript—and you can click any portion of the transcript to skip around on the video!
The Pieces
There are a few web components at play here, but I don’t currently have the energy to formally publish them, so I’ll just link them up here:
- An asynchronous Eleventy
fetchYoutubeTranscript
filter to server-fetch the transcript markup (caching it locally for 7 days). - A WebC component (
youtube-deep-link.webc
) enhances the caption content (fetched from thefetchYoutubeTranscript
filter) with a<youtube-deep-link>
custom element for timestamped buttons that point to alite-youtube
element.- Notably, this required upstream changes to
paulirish/lite-youtube-embed
to access the YouTube Iframe JavaScript API (Update: these changes are available inv0.3.2
+).Until those are merged, you can use this drop-in fork on npm@zachleat/lite-youtube-embed
.
- Notably, this required upstream changes to
- A tiny
<off-viewport>
web component to toggle a class when an element is visible in the viewport. I use this to put the video in the lower corner of the viewport as you scroll through the transcript. This one is a little tricky to use because it can take you into a rendering loop if you absolute/fixed/sticky the position of theoff-viewport
host element directly (so, uh—don’t do that).
Conclusion
I’ve been making more and more videos and I really like escalating that content as first-party text on my static site too. Investing in high quality closed captions (as a way to make the videos more accessible) elevates the content and aligns it more closely with my existing stack of tools.
3 Comments
Brandon
@zachleat gee it's like we should have just written blog posts @hexagoncircle
Zach Leatherman :verify:
@brandonscript @hexagoncircle whew, I agree.
haliphax ????
@zachleat Holy crap, that is seriously cool ????