DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
← From Beginner to Expert in Fundamentals of Frontend
  • Project 1: The Performance-First Dashboard
  • Project 2: Accessible Video Player
  • Project 3: Markdown Blog Engine
  • Project 4: Browser-Based Code Editor
  • Project 5: Multi-Tab Whiteboard
  • Project 6: Infinite Scroll Image Gallery
  • Project 7: Recipe Optimizer & Converter
  • Project 8: Budget Tracker with Charts
  • Project 9: Typing Speed Test
  • Project 10: Weather App with Time-Travel
  • Project 11: CSS Grid Layout Builder
  • Project 12: Password Vault (Frontend Only)
  • Project 13: Kanban Board (Trello Clone)
  • Project 14: Quiz App with Leaderboard
  • Project 15: Habit Tracker (GitHub Style)
  • Project 16: E-commerce Product Page
  • Project 17: Unit Converter (Expert Mode)
  • Project 18: Music Visualizer
  • Project 19: Flashcard Learning App
  • Project 20: Custom Form Validator
  • Project 21: Virtual Terminal
  • Project 22: Pomodoro Timer (Focus Pro)
  • Project 23: SVG Path Editor
  • Project 24: Movie Database Matchmaker
  • Project 25: Interactive Resume / Portfolio
  • Project 26: Recipe Scraper UI
  • Project 27: Crypto Tracker (Real-Time)
  • Project 28: Find My Pet (PWA)
  • Project 29: Markdown-to-Slide Tool
  • Project 30: Browser Health Dashboard
← From Beginner to Expert in Fundamentals of Frontend

Project 2: Accessible Video Player

50 min read
HTML5 Media APIWAI-ARIAKeyboard NavigationPicture-in-PictureScreen ReadersUniversal Design

📋 Project Brief

Build a fully custom video player that replaces native browser controls with a keyboard-navigable, screen-reader-friendly interface. This project is a deep dive into the HTML5 Media API, WAI-ARIA standards, and Universal Design principles. Every user — regardless of motor or visual ability — must be able to control playback with the same level of precision.

🎯 Learning Objectives

  • Master the HTML5 <video> element's JavaScript API (play, pause, currentTime, volume, playbackRate)
  • Implement comprehensive keyboard navigation following WAI-ARIA media player guidelines
  • Build custom UI controls that communicate state to assistive technologies via ARIA attributes
  • Handle complex edge cases: fullscreen transitions, Picture-in-Picture, and buffering states
  • Create a progress bar with precise scrubbing that works with both mouse and keyboard

📐 Architecture Overview

LayerResponsibilityKey Challenge
Media EngineWraps the native <video> element and exposes a clean APISynchronizing UI state with asynchronous media events
Control BarCustom play/pause, volume, progress, and settings controlsMaking every control accessible via keyboard and screen reader
Caption SystemRenders and announces subtitle tracksStyling WebVTT cues and announcing changes to screen readers
Keyboard ManagerMaps keyboard shortcuts to media actionsPreventing conflicts with browser-native shortcuts

✅ Feature Requirements

Feature 1: Keyboard Shortcuts

What it does: Maps specific keys to media actions, mimicking YouTube's keyboard UX.

Acceptance Criteria:

  • Space or K → Toggle play/pause
  • J → Seek backward 10 seconds
  • L → Seek forward 10 seconds
  • M → Toggle mute
  • F → Toggle fullscreen
  • ↑ / ↓ → Increase / decrease volume by 5%
  • ← / → → Seek backward / forward 5 seconds
  • All shortcuts must ONLY work when the player has focus (not globally on the page)
  • A "Keyboard Shortcuts" help overlay must be toggleable with ?

Feature 2: ARIA-Live Captions

What it does: A dedicated region that visually displays captions and announces track changes to screen readers.

Acceptance Criteria:

  • Support loading .vtt caption files
  • Display captions in a styled overlay at the bottom of the video
  • When a new caption track is selected, announce "Captions changed to [Language]" via an aria-live="polite" region
  • Provide a "Captions Off" option
  • Caption font size must be adjustable (Small, Medium, Large)

Feature 3: Picture-in-Picture (PiP)

What it does: Allows the video to float in a small window while the user browses other content.

Acceptance Criteria:

  • A button in the control bar triggers the browser's native PiP API
  • The button icon must change to reflect the current PiP state (enter/exit)
  • Gracefully handle browsers that don't support PiP (hide the button entirely)
  • When PiP is active, the main player area should show a "Playing in Picture-in-Picture" message

Feature 4: Playback Speed Controller

What it does: A slider or menu to adjust playback rate from 0.25x to 3x.

Acceptance Criteria:

  • Offer preset speeds: 0.25x, 0.5x, 0.75x, 1x, 1.25x, 1.5x, 2x, 3x
  • Include a "Preserve Pitch" toggle (uses preservesPitch property)
  • The current speed must be visually indicated and announced to screen readers
  • Changing speed must not interrupt or restart playback

Feature 5: Buffer Progress Visualizer

What it does: Shows how much of the video has been downloaded/cached by the browser.

Acceptance Criteria:

  • A secondary bar (behind the playback progress bar) shows buffered ranges
  • Must handle multiple buffered ranges (the buffered property returns a TimeRanges object)
  • The buffer bar must be visually distinct from the playback bar (e.g., lighter color)
  • Hovering over the progress bar shows a time tooltip at the cursor position

♿ Accessibility Requirements (Non-Negotiable)

RequirementStandardHow to Verify
All controls have visible focus indicatorsWCAG 2.4.7Tab through every control — each must show a clear outline
All controls have accessible namesWCAG 4.1.2Use axe-core or screen reader to verify labels
Progress bar is an accessible sliderARIA slider patternMust have role="slider", aria-valuenow, aria-valuemin, aria-valuemax
State changes are announcedWCAG 4.1.3"Paused", "Playing", "Muted" announced via aria-live
No keyboard trapsWCAG 2.1.2User must be able to Tab out of the player at any time

🏗️ Suggested File Structure

File / FolderPurpose
src/components/VideoPlayer/Main player wrapper
src/components/ControlBar/Play, volume, progress, settings controls
src/components/CaptionOverlay/Caption rendering and track selection
src/hooks/useMediaPlayer.jsCustom hook wrapping the video element API
src/hooks/useKeyboardShortcuts.jsKeyboard event handler with scope management
src/utils/timeFormat.jsConverts seconds to MM:SS or HH:MM:SS

🧪 Testing Checklist

  • Unit test time formatting utility (0 → "0:00", 3661 → "1:01:01")
  • Unit test keyboard mapping logic
  • Integration test: pressing Space toggles between play and pause states
  • A11y audit: zero violations using axe-core
  • Cross-browser test: verify PiP graceful degradation in Firefox vs Chrome

🚀 Stretch Goals

  • Add a "Chapters" system that shows named segments on the progress bar
  • Implement "Theater Mode" that expands the player to full-width
  • Add gesture support for mobile (swipe left/right to seek, swipe up/down for volume)
  • Create a "Mini Player" mode that sticks to the bottom-right on scroll

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.