Recorded meetings, tutorials and announcements need accurate captions with speakers and meaningful sounds, not only a transcript or raw auto-captions.
A school district posts a recording of its board meeting. A parent who is deaf opens it and sees people talking. Without captions the recording is a silent film.
WCAG 1.2.2 (Level A) requires captions for all prerecorded audio content in synchronized media, meaning video that has a soundtrack. The only exception is media that is an alternative for text and is clearly labeled as such.
Captions can be open (burned into the picture) or closed (a track viewers switch on). Both satisfy the criterion; closed captions let viewers restyle the text.
Start with the video element. A caption track is a separate file linked from the video.
<video controls src="/media/board-2026-05-14.mp4"></video><video controls src="/media/board-2026-05-14.mp4">
<track kind="captions"
src="/media/board-2026-05-14.en.vtt"
srclang="en" label="English captions">
</video>The file matters as much as the markup. A track that is only a stream of lowercase words, with no speakers and no sounds, passes a tool and fails a person.
WEBVTT
00:00:02.000 --> 00:00:05.000
we'll start with public comment
00:00:05.500 --> 00:00:09.000
thank you madam chairWEBVTT
00:00:02.000 --> 00:00:05.000
CHAIR OKAFOR: We'll start with public comment.
00:00:05.500 --> 00:00:08.000
[Applause]
00:00:08.500 --> 00:00:11.000
SPEAKER: Thank you, Madam Chair.Custom players frequently hide the captions switch. If you replace the native controls, rebuild this one.
<video id="v" src="board.mp4">
<track kind="captions" src="board.en.vtt" srclang="en" label="English">
</video>
<button id="play">Play</button>
<button id="mute">Mute</button><video id="v" src="board.mp4">
<track kind="captions" src="board.en.vtt" srclang="en" label="English">
</video>
<button id="play">Play</button>
<button id="mute">Mute</button>
<button id="cc" aria-pressed="false">Captions</button>
<script>
const video = document.getElementById('v');
document.getElementById('play').addEventListener('click', () => {
video.paused ? video.play() : video.pause();
});
document.getElementById('mute').addEventListener('click', () => {
video.muted = !video.muted;
});
const track = video.textTracks[0];
track.mode = 'hidden';
document.getElementById('cc').addEventListener('click', e => {
const on = track.mode !== 'showing';
track.mode = on ? 'showing' : 'hidden';
e.currentTarget.setAttribute('aria-pressed', String(on));
});
</script>Public bodies produce a steady stream of video: meeting recordings, "how to apply" walkthroughs, safety announcements and recorded webinars. The usual failures are a video with no track at all, a track generated by speech recognition that was never read through, and videos hosted by a vendor whose player has no captions button. The Department of Justice's guidance lists videos without captions among the common barriers on state and local government sites.
Auto-generated captions are a starting point. Proper names, addresses and numbers (a hearing date, a phone number) are exactly where they fail, and exactly what a resident needs to get right. Vendor-hosted players are a frequent source of the problem; see vendors and third-party content.
Native apps that play recorded video need the same captions. The built-in iOS and Android players can show caption and subtitle tracks that you supply, so the main work is producing a correct caption file and making sure your own controls expose the switch; no separate code is needed for the criterion itself.
[Alarm sounds], [Phone rings].Tools can see a track element; they cannot read the text for accuracy.