Requires captions for the audio of prerecorded video with sound, so that deaf and hard of hearing users get the speech and meaningful sounds as synchronized text.
A person who cannot hear a video gets nothing from its soundtrack unless it is also available as text. Captions turn the audio into synchronized text shown with the picture: who is speaking, what is said and which sounds matter.
This criterion requires captions for all prerecorded audio in synchronized media, that is, video that has a soundtrack. Captions are more than a transcript of the words. They include speaker identification and meaningful non-speech sounds such as music cues, laughter, a door closing or an alarm.
Deaf and hard of hearing users rely on captions to follow what is said and what is heard. Captions also help people who watch without sound (in a public place, at work, on a noisy train), people who are not native speakers of the language, people with auditory processing or attention differences, and anyone watching a video with poor audio quality or strong accents. Captions make video content searchable and quotable as well.
The European Accessibility Act (Directive (EU) 2019/882) applies to in-scope products and services placed on the market after 28 June 2025. Recital 47 names four principles for websites and mobile applications: perceivable, operable, understandable and robust. Captions are a core part of "perceivable".
The technical counterpart is the standard EN 301 549, which incorporates WCAG 1.2.2 by reference and turns it into separate clauses for each kind of ICT. In addition, clause 7 of the standard sets requirements for the video players and technologies themselves.
| Clause | Type of ICT | What it requires |
|---|---|---|
| 9.1.2.2 | Web pages | Web content must satisfy WCAG success criterion 1.2.2. |
| 10.1.2.2 | Non-web documents (PDF, Office files) | The same criterion applies to video embedded in documents. |
| 11.1.2.2 | Non-web software (native mobile apps) | Software that supports screen readers must satisfy the criterion. |
| 7.1 | Video technologies (players and software that show video with sound) | The player must be able to display captions, keep them synchronized, preserve them when the video is passed on, and let users adjust how they look. |
Clause numbers follow the "9. + WCAG number" pattern of EN 301 549. In V3.2.1 the software clause is divided into further subclauses for open and closed functionality, and clause 7.1 is divided into sub-requirements for caption playback, synchronization, preservation and characteristics. Check the exact numbers in the standard when you cite them.
Standard version: EN 301 549 V4.1.1 (September 2026) is based on WCAG 2.2 and is the first version prepared specifically for the EAA. It has not yet been cited in the Official Journal of the European Union, so for now it is best treated as a voluntary technical route to the EAA's requirements. Once cited, it will give a presumption of conformity. The text of criterion 1.2.2 is the same in WCAG 2.1 and 2.2.
A note on EAA scope: Article 2(4) excludes pre-recorded time-based media published before 28 June 2025, and third-party content that the business neither funds, develops nor controls. Videos you publish after that date, and older videos you republish or substantially change, are not covered by the exclusion. Even where an exclusion may apply, captions are good practice and widely used.
Directive (EU) 2019/882, EUR-Lex, opens in a new tab
Add a track element with a caption file in the WebVTT format.
<video controls src="intro.mp4"></video><video controls src="intro.mp4">
<track kind="captions" src="intro.en.vtt"
srclang="en" label="English" default>
</video>Captions identify who speaks and describe sounds that matter. They are split into short, readable lines that match the timing of the audio.
WEBVTT
00:00:01.000 --> 00:00:09.000
welcome to the demo first open the settings menu
and then choose securityWEBVTT
00:00:01.000 --> 00:00:04.000
<v Anna>Welcome to the demo.
00:00:04.500 --> 00:00:06.000
[Door closes]
00:00:06.500 --> 00:00:09.000
<v Anna>First, open the settings menu
and then choose Security.An embedded video is still your content. Upload a reviewed caption file to the platform, and where the platform allows it, turn captions on by default.
<!-- No reviewed captions uploaded, relying on
unchecked automatic captions -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
title="Product tour"></iframe><!-- A reviewed caption file is uploaded to the platform -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID?cc_load_policy=1"
title="Product tour"></iframe>If you build your own player, the captions control must be a real button with a name and a state. It must work with the keyboard and with screen readers.
<div class="cc-icon" onclick="toggleCaptions()"></div><button type="button" id="cc" aria-pressed="false">
Captions
</button>
<script>
const video = document.querySelector("video");
const track = video.textTracks[0];
const btn = document.getElementById("cc");
btn.addEventListener("click", () => {
const on = track.mode !== "showing";
track.mode = on ? "showing" : "hidden";
btn.setAttribute("aria-pressed", String(on));
});
</script>Give every track its own language and a label users can read, so the player can offer the right choice.
<video controls src="intro.mp4">
<track kind="captions" src="intro.en.vtt">
<track kind="captions" src="intro.tr.vtt">
</video><video controls src="intro.mp4">
<track kind="captions" src="intro.en.vtt"
srclang="en" label="English" default>
<track kind="captions" src="intro.tr.vtt"
srclang="tr" label="Türkçe">
</video>The same rule applies in native mobile apps. Use the platform's own video player, which provides a captions menu and honours the user's system settings, and make sure the stream or file you play actually contains a captions track.
import SwiftUI
import AVKit
struct LessonVideoView: View {
// The HLS stream must contain a captions track (WebVTT or
// CEA-608), marked with the characteristics for spoken
// dialogue and non-speech sound.
@State private var player = AVPlayer(
url: URL(string: "https://example.com/lesson.m3u8")!
)
var body: some View {
// AVKit shows the captions menu and follows the
// "Closed Captions + SDH" system setting. Do not set
// appliesMediaSelectionCriteriaAutomatically to false.
VideoPlayer(player: player)
.frame(height: 220)
.accessibilityLabel("Lesson 1: Getting started")
}
}import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.MimeTypes
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
fun lessonMediaItem(): MediaItem {
val captions = MediaItem.SubtitleConfiguration.Builder(
Uri.parse("https://example.com/lesson.en.vtt") // Your file
)
.setMimeType(MimeTypes.TEXT_VTT)
.setLanguage("en")
.setLabel("English captions")
.setRoleFlags(C.ROLE_FLAG_CAPTION)
.build()
return MediaItem.Builder()
.setUri("https://example.com/lesson.mp4") // Your video
.setSubtitleConfigurations(listOf(captions))
.build()
}
@Composable
fun LessonVideo(player: ExoPlayer) {
AndroidView(factory = { context ->
PlayerView(context).apply {
this.player = player
// Shows the captions button in the controls
setShowSubtitleButton(true)
}
})
}video element without a track, but they cannot judge whether captions are complete, accurate and in sync. Only a person can decide that.