@codearcade/video-player
v1.0.0
Published
A production-ready, feature-rich React video player component built on top of **Shaka Player**. This component provides a comprehensive video streaming solution with adaptive bitrate streaming (HLS/DASH), custom UI controls, watermarking, chapter navigati
Readme
@codearcade/video-player
A production-ready, feature-rich React video player component built on top of Shaka Player. This component provides a comprehensive video streaming solution with adaptive bitrate streaming (HLS/DASH), custom UI controls, watermarking, chapter navigation, retention analytics tracking, and extensive accessibility features.
🌟 Features
Core Capabilities
- ✅ HLS, DASH, and CMAF Streaming - Support for all major adaptive streaming protocols
- ✅ Adaptive Bitrate Streaming (ABR) - Automatic quality adjustment based on network conditions
- ✅ Custom UI Theme - Fully customizable player controls with dark/light themes
- ✅ Cross-Browser Compatible - Works on Chrome, Firefox, Safari, and Edge
- ✅ Zero-config CSS - Styles are automatically injected, no need to manually import CSS files!
Advanced Features
- 🎬 Custom Controls - Play/pause, volume, progress bar, fullscreen, quality selector, playback speed
- 🏷️ Watermarking System - Dynamic text/image overlays with animations and positioning
- 📑 Video Chapters - Navigation with thumbnails, progress bar markers, and chapter display
- 📊 Retention Analytics - Built-in tracking for user retention, auto-batched and throttled
- 🔒 Auth & DRM - Passthrough headers, cookies, and Widevine/PlayReady/FairPlay configurations
- ⌨️ Keyboard Shortcuts - Scoped keyboard controls that don't interfere with the rest of your page
- ♿ Accessibility - ARIA labels, keyboard navigation, and screen reader support
- ⚡ Resilient - Deterministic error recovery and retry logic
🚀 Quick Start
Installation
npm install @codearcade/video-player
# or
yarn add @codearcade/video-player
# or
pnpm add @codearcade/video-player
# or
bun add @codearcade/video-playerUsage
import VideoPlayer from "@codearcade/video-player";
export default function App() {
return (
<VideoPlayer
src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
poster="/poster.jpg"
theme="dark"
onReady={() => console.log("Player ready")}
onError={(error) => console.error("Player error:", error)}
/>
);
}📚 API Reference
VideoPlayer Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| src | string | Required | Video source URL |
| userId | string | - | User identifier for retention tracking |
| type | 'hls' \| 'dash' \| 'cmaf' \| 'auto' | 'auto' | Stream type |
| poster | string | - | Poster image URL |
| autoplay | boolean | false | Auto-start playback |
| muted | boolean | false | Start muted |
| loop | boolean | false | Loop playback |
| watermark | WatermarkConfig | - | Watermark configuration |
| chapters | Chapter[] | [] | Video chapters array |
| controls | ControlsConfig | - | Controls configuration |
| theme | 'dark' \| 'light' | 'dark' | UI theme |
| shakaConfig | ShakaConfig | - | Shaka Player config overrides |
| networkConfig | NetworkConfig | - | Custom headers, cookies, and retry logic |
| retentionData| RetentionData[] | - | Initial retention graph data to display |
| className | string | - | Custom CSS class |
| style | CSSProperties | - | Inline styles |
Event Callbacks
| Callback | Type | Description |
| --- | --- | --- |
| onReady | () => void | Called when player is initialized |
| onError | (error: VideoPlayerError) => void | Called on critical error |
| onRetry | (attempt: number, error: VideoPlayerError) => void| Called when the player attempts a retry |
| onPlay | () => void | Called when playback starts |
| onPause | () => void | Called when playback pauses |
| onEnded | () => void | Called when playback ends |
| onTimeUpdate | (currentTime: number) => void | Called on time update |
| onSeeking | () => void | Called when seeking |
| onSeeked | () => void | Called when seek completes |
| onQualityChange | (quality: QualityLevel \| null) => void | Called on quality change |
| onChapterChange | (chapter: Chapter \| null) => void | Called on chapter change |
| onRetentionFlush| (batch: RetentionData[]) => void | Called periodically with batched playback tracking data |
🎨 Watermarking
import type { WatermarkConfig } from "@codearcade/video-player";
const myWatermark: WatermarkConfig = {
type: "text", // or "image"
content: "My Brand", // or URL for image
position: "top-right",
opacity: 0.7,
size: "18px",
style: { fontFamily: "Arial, sans-serif", fontWeight: "bold" },
};
<VideoPlayer src="video.m3u8" watermark={myWatermark} />📑 Chapters
import type { Chapter } from "@codearcade/video-player";
const myChapters: Chapter[] = [
{ id: "1", title: "Intro", startTime: 0, endTime: 30, description: "Welcome" },
{ id: "2", title: "Core", startTime: 30, endTime: 90, description: "Main concepts" },
];
<VideoPlayer src="video.m3u8" chapters={myChapters} />🌐 Network & Authentication
The networkConfig prop allows you to easily pass custom headers or credentials to the Shaka Player engine for authenticated streams:
<VideoPlayer
src="protected-video.m3u8"
networkConfig={{
withCredentials: true, // Send cookies cross-origin
headers: {
"Authorization": "Bearer token123"
},
timeout: 15000,
maxRetries: 4
}}
/>⌨️ Scoped Keyboard Shortcuts
The player handles shortcuts globally only when the player is focused or hovered, preventing interference with forms on the rest of your page.
| Key | Action |
| --- | --- |
| Space or K | Play/Pause |
| F | Toggle fullscreen |
| M | Mute/Unmute |
| C | Toggle chapters panel |
| ← / → | Seek backward/forward 5s |
| J / L | Seek backward/forward 10s |
| ↑ / ↓ | Increase/decrease volume |
| < / > | Decrease/increase playback speed |
| 0-9 | Seek to 0%-90% |
📄 License
MIT License
