Back to Remotion

Voluntary Product Accessibility Template (VPAT)

packages/compliance/a11y/player/VPAT-2026-04-14.md

4.0.4577.5 KB
Original Source

Voluntary Product Accessibility Template (VPAT)

Date: April 14, 2026

VPAT 2.4 Rev — WCAG 2.1 Edition

Product Information

FieldValue
Product Name@remotion/player (<Player> component)
Instance testedDemo Player on https://www.remotion.dev/player
Report Date2026-04-14
Contactremotion.dev/contact
Evaluation MethodsLive DOM / accessibility-tree inspection in Chrome; scripted queries; manual focus/label checks.
Applicable StandardWCAG 2.1 Level AA
ScopeThe Player component only (container semantics, play/pause, mute, seek, volume, fullscreen, time display). Page-level findings on /player (marketing copy, surrounding demo controls, duplicate link text) are out of scope.

Conformance Level Key

TermDefinition
SupportsFully meets the criterion
Partially SupportsSome content meets, some gaps remain
Does Not SupportSignificant failures
Not ApplicableFeature or content type does not exist in the product

Findings (by WCAG criterion)

1.1.1 Non-text Content (Level A)

Conformance Level: Partially Supports

Remarks:

  • Play/Pause, Mute, Fullscreen SVG-icon buttons have proper aria-label + title.
  • Play/Pause accessible name toggles ("Play video" ↔ "Pause video") to reflect state.
  • Mute label does not toggle to "Unmute sound" and has no aria-pressed — state cannot be determined by screen readers (see 4.1.2).

1.2.1 Audio-only and Video-only (Prerecorded) (Level A)

Conformance Level: Does Not Support

Remarks:

  • <Player> provides no text-alternative surface for audio-only or video-only compositions.

1.2.2 Captions (Prerecorded) (Level A)

Conformance Level: Does Not Support

Remarks:

  • The component does not render a <video>/<track> hierarchy and exposes no captions/subtitles API. Compositions with spoken dialogue cannot have captions without consumer code.

1.2.3 Audio Description or Media Alternative (Prerecorded) (Level A)

Conformance Level: Does Not Support

Remarks:

  • No built-in audio description track or synchronized text-alternative mechanism.

1.2.5 Audio Description (Prerecorded) (Level AA)

Conformance Level: Does Not Support

Remarks:

  • See 1.2.3.

1.3.1 Info and Relationships (Level A)

Conformance Level: Does Not Support

Remarks:

  • .__remotion-player wrapper has no role, aria-label, or aria-roledescription. There is no region/landmark identifying this as a video player.
  • The seek bar is a stack of plain <div> elements with no role="slider", no aria-valuemin/max/now, no label.
  • The volume slider is a plain <div> with no slider role, name, or value attributes.

2.1.1 Keyboard (Level A)

Conformance Level: Does Not Support

Remarks:

  • Seek bar cannot be reached or operated from the keyboard (not in tab order; no key handlers).
  • Volume slider cannot be reached or operated from the keyboard.
  • No media keyboard shortcuts on the player root: Space/K (play-pause), ←/→ (seek), ↑/↓ (volume), M (mute), F (fullscreen) all do nothing.

2.1.2 No Keyboard Trap (Level A)

Conformance Level: Supports

Remarks:

  • No keyboard trap observed.

2.2.2 Pause, Stop, Hide (Level A)

Conformance Level: Partially Supports

Remarks:

  • A Pause button exists on the default controls.
  • A <Player autoPlay loop> instance has no built-in respect for prefers-reduced-motion — autoplay/loop run regardless. Component should default to no-autoplay under reduced motion and document the override.

2.4.7 Focus Visible (Level AA)

Conformance Level: Supports

Remarks:

  • Keyboard-focused Play/Pause, Mute, Fullscreen buttons show a visible outline (confirmed via screenshot — blue ring on the Pause button). The author CSS sets outline-style: none only on :focus; Chrome's default :focus-visible UA style restores the ring for keyboard focus.
  • Recommendation (not a failure): define an explicit :focus-visible rule on the controls so the indicator is stable across browsers/themes and does not depend on UA defaults.

4.1.2 Name, Role, Value (Level A)

Conformance Level: Does Not Support

Remarks:

  • Play/Pause and Mute/Fullscreen buttons have accessible names — Supports at the button level.
  • Seek bar: no role="slider", no aria-valuemin/max/now/text, no aria-labelfails.
  • Volume slider: same — fails.
  • Mute button: no aria-pressed; label doesn't toggle; muted state not programmatically exposed — fails.
  • Player wrapper has no container role / accessible name (see 1.3.1).

4.1.3 Status Messages (Level AA)

Conformance Level: Does Not Support

Remarks:

  • Time display updates silently — no role="timer", no aria-live.
  • Mute state changes are not announced.

Summary of Issues

WCAGIssue
1.2.2 / 1.2.3 / 1.2.5No captions, no audio description, no transcript mechanism in the component API
1.3.1 / 4.1.2Seek bar is a plain <div> stack — no slider role, name, or value
1.3.1 / 4.1.2Volume slider is a plain <div> — no slider role, name, or value
1.3.1.__remotion-player wrapper has no container role or accessible name
2.1.1Seek bar and volume slider not keyboard-operable; no media keyboard shortcuts
2.2.2<Player autoPlay loop> does not respect prefers-reduced-motion
4.1.2Mute button has no aria-pressed and label does not toggle to expose state
4.1.3Time display not a live region; mute state changes not announced

What conforms

  • Play/Pause, Mute, Fullscreen: native <button> with aria-label + title
  • Play/Pause accessible name toggles with state
  • Composition text renders to real DOM — readable by screen readers
  • Decorative preload <audio> elements are display: none — not in the tab order

Overall

The @remotion/player video-player component Partially Supports WCAG 2.1 Level AA. Control buttons are labelled and keyboard-focusable, but the seek bar, volume slider, focus indicator, mute-state semantics, captions/transcript surface, and container landmarking all need work before the component can be considered an accessible media player. Reference implementations for comparison: Able Player, OzPlayer, Video.js.