@mottosports/motto-video-player
Version:
React video player component for the Motto platform, powered by Shaka Player
244 lines (195 loc) • 6.8 kB
Markdown
React video player component for the Motto platform, powered by Shaka Player with TanStack Query integration.
- 🎬 **Dual Components**: Bare `VideoPlayer` for direct URL playback and `Video` wrapper for data fetching
- 🔄 **TanStack Query Integration**: Advanced caching, background refetching, and error handling
- 📱 **Responsive Design**: Automatic aspect ratio handling and mobile-friendly controls
- 🎮 **Skip Controls**: Built-in skip back/forward buttons with customizable durations
- ⌨️ **Keyboard Controls**: Desktop keyboard shortcuts (arrows for skip, spacebar for play/pause)
- 🎯 **Quality Control**: Automatic quality selection and manual quality switching
- 📊 **Analytics**: Built-in Mux analytics support
- 🖥️ **Chromecast Support**: Cast videos to compatible devices
- 🔒 **DRM Support**: Content protection with various DRM systems
- 📦 **TypeScript**: Full TypeScript support with comprehensive type definitions
## Installation
```bash
npm install @motto-ui-components/motto-video-player @tanstack/react-query
```
## Quick Start
### Setup QueryClient (Required for Video wrapper)
```jsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourComponents />
</QueryClientProvider>
);
}
```
For direct stream URL playback:
```jsx
import { VideoPlayer } from '@motto-ui-components/motto-video-player';
function MyPlayer() {
return (
<VideoPlayer
src="https://example.com/video.m3u8"
controls
aspectRatio={16/9}
onPlay={() => console.log('Playing')}
onError={(error) => console.error(error)}
/>
);
}
```
For data fetching with TanStack Query:
```jsx
import { Video } from '@motto-ui-components/motto-video-player';
function MyPlayer() {
return (
<Video
videoId="your-video-id"
publicKey="your-public-key"
controls
refetchInterval={30000}
events={{
onVideoData: (video) => console.log('Video loaded:', video),
onError: (error) => console.error('Error:', error),
onPlay: () => console.log('Playing')
}}
/>
);
}
```
| Feature | VideoPlayer | Video |
|---------|-------------|-------|
| **Use Case** | Direct stream URL | Data fetching with videoId |
| **Data Fetching** | ❌ Manual | ✅ Automatic with TanStack Query |
| **Caching** | ❌ None | ✅ Smart caching & background updates |
| **Loading States** | ❌ Manual | ✅ Built-in loading indicators |
| **Error Handling** | ❌ Manual | ✅ Automatic retry with exponential backoff |
| **Performance** | ✅ Minimal overhead | ✅ Optimized with query deduplication |
```jsx
<Video
videoId="123"
publicKey="key"
refetchInterval={30000}
queryOptions={{
staleTime: 5 * 60 * 1000, // 5 minutes
retry: 3,
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000)
}}
/>
```
```jsx
<VideoPlayer
src="..."
skipConfig={{
showSkipBack: true,
showSkipForward: true,
skipDuration: 15,
position: 'controls' // or 'overlay'
}}
onSkipBack={(newTime) => console.log('Skipped to:', newTime)}
onSkipForward={(newTime) => console.log('Skipped to:', newTime)}
/>
```
Desktop users can control the player using keyboard shortcuts:
- **←** Left Arrow: Skip back 15 seconds
- **→** Right Arrow: Skip forward 15 seconds
- **Space**: Play/Pause toggle
Keyboard controls are automatically enabled on desktop devices (disabled on mobile) and work when the player is focused or when no input fields are active.
### Responsive Sizing
```jsx
// Default responsive 16:9
<VideoPlayer src="..." />
// Custom aspect ratio
<VideoPlayer src="..." aspectRatio={4/3} />
// Fixed dimensions
<VideoPlayer src="..." width={800} height={450} />
```
```jsx
<VideoPlayer
src="..."
muxConfig={{
debug: false,
data: {
env_key: 'your-mux-env-key',
video_title: 'Video Title',
video_id: 'video-123',
player_name: 'Web Player',
viewer_user_id: 'user-456'
}
}}
onMuxReady={(monitor) => console.log('Mux ready')}
/>
```
```typescript
interface VideoPlayerProps {
src: string; // Video source URL
autoPlay?: boolean; // Auto-play video
controls?: boolean; // Show player controls
aspectRatio?: number; // Video aspect ratio (default: 16/9)
width?: number; // Fixed width
height?: number; // Fixed height
skipConfig?: SkipConfig; // Skip controls configuration
muxConfig?: MuxConfig; // Mux analytics configuration
onPlay?: () => void; // Play event callback
onPause?: () => void; // Pause event callback
onError?: (error: any) => void; // Error event callback
// ... more props
}
```
```typescript
interface VideoProps extends Omit<VideoPlayerProps, 'src'> {
videoId?: string; // Video ID for data fetching
publicKey?: string; // Public key for API authentication
videoData?: VideoData; // Pre-loaded video data
refetchInterval?: number; // Background refetch interval (ms)
queryOptions?: QueryOptions; // TanStack Query configuration
events?: {
onVideoData?: (video: VideoData) => void;
onEmptyPlaylists?: () => void;
onError?: (error: Error) => void;
// ... player events
};
}
```
- **Automatic Caching**: Videos are cached with configurable stale time
- **Background Refetching**: Data stays fresh with background updates
- **Request Deduplication**: Identical requests are automatically deduplicated
- **Garbage Collection**: Memory-efficient cleanup of unused cache entries
- **Smart Retries**: Exponential backoff retry logic for failed requests
- **Loading States**: Built-in loading indicators for better UX
- **Error Recovery**: Automatic error handling and recovery mechanisms
- **Optimistic Updates**: Support for optimistic UI updates
Check out the [example app](../../apps/example) for comprehensive usage examples including:
- Basic VideoPlayer usage
- Video wrapper with TanStack Query
- Pre-loaded data scenarios
- Skip controls integration
- Responsive design patterns
1. Clone the repository
2. Install dependencies: `pnpm install`
3. Start development: `pnpm dev`
4. Build: `pnpm build`
ISC