EpisodePlayer
An episode player for a podcast or a read-aloud letter.
View code
<EpisodePlayer
src="/demos/newsletter/episode-63.mp3"
type="audio/mpeg"
captions={{ src: "/demos/newsletter/episode-63.vtt", srclang: "en", label: "English" }}
title="The pressure at the top of the hill"
meta="Episode 63 · 14:20"
chaptersLabel="Chapters"
transcriptLabel="Read the transcript"
fallback={<a href="/demos/newsletter/episode-63.mp3">Download the episode</a>}
chapters={[
{ start: 0, title: "The shower on the ninth floor" },
{ start: 112, title: "What pressure means at a tap" },
{ start: 270, title: "The tower on Linden Hill" },
{ start: 785, title: "Credits" },
]}
transcript={[
{ start: 0, speaker: "Tove", text: "This is Undercurrent. I'm Tove Adler." },
{ start: 112, speaker: "Rafi", text: "Pressure is height you borrow from a tank." },
]}
/>Demo landings
Whole pages built only from @sdxc/ui, each for an invented product with its own palette and type. They open in a new tab.
- MarginAn invented AI note-taker for recorded meetings: summaries, decisions and to-dos that each link to the transcript line they came from./demo/ai
- RooftreeRooftree keeps a household's groceries, chores, calendar and meals on one encrypted list that syncs across iPhone, Android, Mac and Windows./demo/app
- Hollyhock BakeryHollyhock Bakery on Alder Street: today's bake, the menu and prices, opening hours that know the time, pickup orders, directions, step-free access and parking./demo/bakery
- The MeasureA book and video course on web typography for designers and engineers: measure, rhythm, scale and fonts, with CSS for every chapter./demo/book
- Overprint 2027Overprint is one day of talks on what browsers ship, in two rooms of an old foundry in Rotterdam, on Thursday 15 April 2027./demo/conference
- CenteredCentered is a video course in wheel-throwing pottery: 24 lessons in six modules with chapters and transcripts, self-paced or with a cohort, ending in a lidded jar./demo/course
- Strata TwoStrata Two is a 75% keyboard in a one-piece aluminium case with a gasket-mounted plate. Preorder batch 03 for $279, shipping 9 March 2027./demo/hardware
- plumbPlumb compiles a TypeScript schema to straight-line JavaScript once, so parsing runs the checks you would have written by hand./demo/library
- UndercurrentA fortnightly letter and podcast about the water mains, power lines, signals and post under an ordinary day, read aloud with the people who run them./demo/newsletter
- KeelKeel meters every event your product emits, prices it on any plan and sends the invoice on the first of the month./demo/saas
- QuoinQuoin designs and builds everyday software for transit, libraries and makers, and measures what it changed. Booking from March./demo/studio
Every demo, landings and docs sites alike, is listed in the demo gallery.
Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/ui remiximport "@sdxc/ui/theme.css";Usage
import { EpisodePlayer } from "@sdxc/ui/landing";The audio, chapter links and a closed transcript; with no script a time link opens the file
at its moment. Map EpisodeSync (@sdxc/ui/landing/episode-player) in the browser entry
to seek in place and mark what plays. --ui-landing-hairline colours the chapter rules.
Examples
<EpisodePlayer src="/audio/63.mp3" type="audio/mpeg" captions={{ src: "/audio/63.vtt", srclang: "en", label: "English" }} title="No. 63" meta="Episode 63 · 14:20" chaptersLabel="Chapters" transcriptLabel="Read the transcript" fallback={<a href="/audio/63.mp3">Download</a>} chapters={[{ start: 0, title: "Opening" }, { start: 112, title: "Pressure" }]} transcript={[{ start: 0, speaker: "Tove", text: "This is Undercurrent." }]} />Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
| Prop | Type | Required | Description |
|---|---|---|---|
src | string | Yes | Address of the audio file; every time link appends #t=<whole seconds> to it. |
type | string | No | Media type of the file, such as audio/mpeg, so a browser skips a format it cannot play. |
title | RemixNode | Yes | The episode's title, rendered as a heading at the surrounding level. |
meta | RemixNode | No | A line under the title, such as the number, date and running time. |
chapters | readonly Chapter[] | No | Chapters in playing order; the list is left out when empty. |
transcript | readonly Cue[] | No | Transcript passages in playing order; the disclosure is left out when empty. |
chaptersLabel | string | Yes | Accessible name of the chapter list, such as "Chapters". |
transcriptLabel | string | Yes | Visible label of the transcript disclosure, such as "Read the transcript". |
captions | { src: string; srclang: string; label: string } | Yes | The WebVTT captions file for the audio, which assistive technology can read out. |
fallback | RemixNode | Yes | Rendered inside <audio> for a browser without audio support, such as a download link. |
note | RemixNode | No | A line under the player, such as a credit or a download link. |
Also accepts everything in Omit<TagProps<"div">, "title">.
Also exported
Other components this module publishes.
formatEpisodeTime