Video Playerv0.2.18Documentation Under Review
A Brightcove video player component with customizable controls and comprehensive styling options. Built on Brightcove React Player Loader with full support for captions, chapters, audio tracks, and picture-in-picture.
Installation
Install the Video Player component from the Catalyst component library:
npm install @pmi/catalyst-video-playerOverview
The Video Player component provides a feature-rich video playback experience built on Brightcove's video platform. It features:
- Brightcove Integration - Seamless integration with Brightcove video hosting
- Custom Icons - Replace default player icons with Catalyst icon components
- State Management - Real-time player state tracking (play/pause, volume, fullscreen)
- Responsive Sizing - Four size variants (xs, sm, md, lg) with adaptive controls
- Advanced Features - Captions, chapters, audio tracks, and picture-in-picture support
- Customizable UI - Extensive Tailwind-based styling for all player controls
- Accessible - WCAG 2.1 AA compliant video player with keyboard navigation
Examples
Basic Video Player
A basic video player with custom icons for all controls:
Video with Captions
A video player configured to display captions:
Video with Chapters
A video player with chapter markers for navigation:
Video with Audio Tracks
A video player with multiple audio track options:
Size Variants
The video player supports four size variants for the big play button:
import { VideoPlayerRoot, VideoPlayerIconSlot } from '@pmi/catalyst-video-player'
import { PlayIcon } from '@pmi/catalyst-icons'
// Extra Small
<VideoPlayerRoot size="xs" videoId="..." playerId="..." accountId="...">
<VideoPlayerIconSlot name="bigPlayButton">
<PlayIcon size="full" />
</VideoPlayerIconSlot>
</VideoPlayerRoot>
// Small
<VideoPlayerRoot size="sm" videoId="..." playerId="..." accountId="...">
<VideoPlayerIconSlot name="bigPlayButton">
<PlayIcon size="full" />
</VideoPlayerIconSlot>
</VideoPlayerRoot>
// Medium (default)
<VideoPlayerRoot size="md" videoId="..." playerId="..." accountId="...">
<VideoPlayerIconSlot name="bigPlayButton">
<PlayIcon size="full" />
</VideoPlayerIconSlot>
</VideoPlayerRoot>
// Large
<VideoPlayerRoot size="lg" videoId="..." playerId="..." accountId="...">
<VideoPlayerIconSlot name="bigPlayButton">
<PlayIcon size="full" />
</VideoPlayerIconSlot>
</VideoPlayerRoot>Component Structure
The Video Player component is composed of two main parts:
- VideoPlayerRoot - The main video player container with Brightcove integration
- VideoPlayerIconSlot - Slots for custom icon content in various player controls
API Reference
VideoPlayerRoot
Prop
Type
VideoPlayerIconSlot
Prop
Type
PlayerState Interface
Prop
Type
Styling with Tailwind
The Video Player component uses extensive Tailwind CSS classes for comprehensive player control styling:
Control Bar Styling
The control bar is fully styled with Tailwind tokens:
// Control bar is styled with:
// - Height: [&_.video-js_.vjs-control-bar]:h-[var(--scale-32)]
// - Padding: [&_.video-js_.vjs-control-bar]:px-[var(--scale-8)]
// - Background: [&_.video-js_.vjs-control-bar]:bg-[var(--components-video-player-action-fill-bar)]
// - Font: [&_.video-js_.vjs-control-bar]:font-displayBig Play Button
Customize the big play button appearance by size:
// Size-based button styling:
// xs: p-[var(--scale-8)], icon size-[var(--scale-32)]
// sm: p-[var(--scale-12)], icon size-[var(--scale-32)]
// md: p-[var(--scale-16)], icon size-[var(--scale-40)]
// lg: p-[var(--scale-28)], icon size-[var(--scale-40)]
<VideoPlayerRoot size="lg" className="aspect-video max-w-screen-xl">
{/* Big play button automatically sized */}
</VideoPlayerRoot>Progress Bar
The progress bar uses custom fill colors:
// Progress bar styling:
// - Background: [&_.video-js_.vjs-progress-holder]:bg-[var(--components-video-player-played-fill-background)]
// - Foreground: [&_.video-js_.vjs-play-progress]:bg-[var(--components-video-player-played-fill-forground)]Design Tokens
Common design tokens used in Video Player:
- Control Bar:
--components-video-player-action-fill-bar - Progress Background:
--components-video-player-played-fill-background - Progress Foreground:
--components-video-player-played-fill-forground - Resolution Menu:
--components-video-player-resolution-fill-container - Title Area:
--components-video-player-title-area-gradient-from,--components-video-player-title-area-gradient-to - Caption Overlay:
--components-video-player-caption-overlay-fill-container - Spacing:
--scale-8,--scale-12,--scale-16,--scale-28,--scale-32,--scale-40 - Icons:
--icon-white,--fill-off-black-dark
Patterns and Best Practices
State Management
Track player state for conditional icon rendering:
const [playerState, setPlayerState] = useState({})
const handleStateChange = useCallback((state) => {
setPlayerState(state)
}, [])
<VideoPlayerRoot onPlayerStateChange={handleStateChange}>
<VideoPlayerIconSlot name="playToggle">
{playerState.paused ? <PlayIcon /> : <PauseIcon />}
</VideoPlayerIconSlot>
</VideoPlayerRoot>Volume Level Icons
Display appropriate volume icons based on current level:
<VideoPlayerIconSlot name="muteToggle">
{playerState.volumeLevel === 'mute' && <MuteIcon size="full" />}
{playerState.volumeLevel === 'low' && <VolumeLowIcon size="full" />}
{playerState.volumeLevel === 'mid' && <VolumeMediumIcon size="full" />}
{playerState.volumeLevel === 'high' && <VolumeIcon size="full" />}
</VideoPlayerIconSlot>Fullscreen Toggle
Toggle between expand and exit fullscreen icons:
<VideoPlayerIconSlot name="fullscreenToggle">
{playerState.fullscreen ? <ExitFullScreenIcon size="full" /> : <ExpandIcon size="full" />}
</VideoPlayerIconSlot>Picture-in-Picture
Handle picture-in-picture mode transitions:
<VideoPlayerIconSlot name="pictureInPictureToggle">
{playerState.pictureInPicture ? (
<PictureInPictureExitIcon size="full" />
) : (
<PictureInPictureIcon size="full" />
)}
</VideoPlayerIconSlot>Aspect Ratio Container
Use Tailwind aspect ratio utilities for responsive video:
<VideoPlayerRoot className="aspect-video max-w-screen-xl" videoId="..." playerId="..." accountId="...">
{/* Player content */}
</VideoPlayerRoot>Custom Icon Slots
Replace any player control icon with custom components:
// All available icon slots:
<VideoPlayerIconSlot name="bigPlayButton">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="playToggle">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="muteToggle">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="chaptersButton">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="subsCapsButton">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="audioTrackButton">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="fullscreenToggle">{/* Custom icon */}</VideoPlayerIconSlot>
<VideoPlayerIconSlot name="pictureInPictureToggle">{/* Custom icon */}</VideoPlayerIconSlot>Accessibility
The Video Player component is built with accessibility in mind, using the Brightcove player which implements WCAG 2.1 AA standards:
WCAG 2.1 AA Compliance
- Keyboard Navigation: Full keyboard control for all player functions
- Screen Reader Support: Proper ARIA labels and roles for all controls
- Captions Support: Built-in closed caption and subtitle support
- Keyboard Shortcuts: Standard video player keyboard shortcuts
- Focus Management: Visible focus indicators on all interactive elements
- Color Contrast: Sufficient contrast for control bar and text elements
Keyboard Interactions
| Key | Description |
|---|---|
Space / K | Toggle play/pause |
M | Toggle mute |
F | Toggle fullscreen |
Arrow Up/Down | Adjust volume |
Arrow Left/Right | Seek backward/forward |
0-9 | Jump to specific percentage of video |
C | Toggle captions |
Home | Jump to beginning |
End | Jump to end |
Caption Support
The component fully supports:
- Closed captions (CC)
- Subtitles
- Multiple caption tracks
- Caption customization via settings
Audio Description
For videos with audio descriptions:
- Multiple audio track support
- Audio track selection menu
- Synchronized audio switching
Best Practices
- Always provide captions - Include closed captions for all video content
- Test keyboard navigation - Verify all controls work via keyboard
- Provide transcripts - Offer text transcripts for video content
- Use descriptive titles - Set meaningful video titles in Brightcove
- Audio descriptions - Include audio descriptions for visual content
- Contrast compliance - Ensure control bar has sufficient contrast
- Focus indicators - Maintain visible focus states on all controls
- Screen reader testing - Test with NVDA, JAWS, or VoiceOver
- Multiple players - When using multiple VideoPlayer instances on the same page, ensure each has a unique
playerIdto avoid conflicts
Using Multiple Video Players
The VideoPlayer component fully supports multiple instances on the same page. Each player manages its own state independently and is properly disposed when unmounted:
<div className="grid grid-cols-2 gap-4">
<VideoPlayerRoot
videoId="6361280101112"
playerId="HyAj7DGSW" // Must be unique
accountId="5392214295001"
onPlayerStateChange={(state) => console.log('Player 1:', state)}
>
{/* Player 1 icon slots */}
</VideoPlayerRoot>
<VideoPlayerRoot
videoId="6361280101113"
playerId="BJAZNkRV" // Different playerId for second instance
accountId="5392214295001"
onPlayerStateChange={(state) => console.log('Player 2:', state)}
>
{/* Player 2 icon slots */}
</VideoPlayerRoot>
</div>Important considerations:
- Each player instance maintains its own event listeners and state
- Players are automatically cleaned up and disposed when unmounted
- Must use unique
playerIdvalues for each instance to ensure proper initialization and avoid conflicts - State changes in one player do not affect other players on the page
- Each player gets a unique React key to prevent instance reuse
Brightcove Integration
Required Configuration
To use the Video Player, you need:
- Brightcove Account - A valid Brightcove account
- Account ID - Your Brightcove account identifier
- Player ID - The player configuration to use
- Video ID - The specific video to play
Example Configuration
<VideoPlayerRoot
videoId="6361280101112" // Your video ID
playerId="HyAj7DGSW" // Your player ID
accountId="5392214295001" // Your account ID
>
{/* Icon slots */}
</VideoPlayerRoot>Advanced Features
The Brightcove player supports:
- Chapters - Navigate video via chapter markers
- Captions - Multiple caption/subtitle tracks
- Audio Tracks - Multiple audio language options
- Quality Selection - Adaptive bitrate streaming
- Analytics - Built-in viewing analytics
- DRM - Content protection support
Content Security Policy (CSP) Configuration
Important: The Video Player component requires specific Content Security Policy (CSP) directives to function properly. If the video player is not loading or displaying correctly in your application, you need to review and update your CSP configuration.
Required CSP Directives
Add the following domains to your application's CSP headers:
// Example CSP configuration
{
'connect-src': [
'https://*.brightcove.com',
'http://*.brightcove.com',
'https://*.boltdns.net',
'https://*.brightcovecdn.com'
],
'script-src': [
'https://*.brightcove.net',
'https://vjs.zencdn.net',
"'unsafe-inline'", // Required for Brightcove player inline scripts
"'unsafe-eval'" // Required for Brightcove player dynamic evaluation
],
'style-src': [
"'unsafe-inline'" // Required for Brightcove player inline styles
],
'font-src': [
'https://*.brightcove.com',
'https://cdn.fontshare.com',
'data:'
],
'style-src-elem': [
'https://*.brightcove.com',
'http://*.s3.amazonaws.com',
'https://api.fontshare.com',
"'unsafe-inline'"
],
'img-src': [
'https://*.brightcove.com',
'https://*.boltdns.net'
]
}Next.js Configuration Example
If you're using Next.js, add these directives to your next.config.js:
/** @type {import('next').NextConfig} */
const config = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Content-Security-Policy',
value: [
"connect-src 'self' https://*.brightcove.com http://*.brightcove.com https://*.boltdns.net https://*.brightcovecdn.com",
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.brightcove.net https://vjs.zencdn.net",
"style-src 'self' 'unsafe-inline'",
"font-src 'self' https://*.brightcove.com data:",
"style-src-elem 'self' https://*.brightcove.com http://*.s3.amazonaws.com 'unsafe-inline'",
"img-src 'self' https://*.brightcove.com https://*.boltdns.net",
].join('; '),
},
],
},
];
},
};
export default config;Troubleshooting CSP Issues
If the video player is not working:
- Check Browser Console - Look for CSP violation errors
- Review Your CSP Configuration - Ensure all Brightcove domains are whitelisted
- Test in Development - Temporarily use a more permissive CSP to identify missing directives
- Verify Player Loading - Confirm the Brightcove player script loads successfully
Note: The unsafe-inline and unsafe-eval directives are required by the Brightcove player. If your security policy doesn't allow these, consider using nonce-based CSP or consulting with your security team for alternative solutions.
Related Components
- Icons - Icon components used in player controls
- Aspect Ratio - Container for responsive video sizing
See Also
- Brightcove Player SDK - Official Brightcove documentation
- React Player Loader - Brightcove React integration
- WCAG Media Guidelines - W3C accessibility standards for media
- Video.js - The underlying video player library
- Content Security Policy (MDN) - CSP documentation and best practices