@mottosports/motto-video-player 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +233 -0
- package/dist/index.d.mts +499 -0
- package/dist/index.d.ts +499 -0
- package/dist/index.js +2631 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2590 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Motto Video Player
|
|
2
|
+
|
|
3
|
+
React video player component for the Motto platform, powered by Shaka Player with TanStack Query integration.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎬 **Dual Components**: Bare `VideoPlayer` for direct URL playback and `Video` wrapper for data fetching
|
|
8
|
+
- 🔄 **TanStack Query Integration**: Advanced caching, background refetching, and error handling
|
|
9
|
+
- 📱 **Responsive Design**: Automatic aspect ratio handling and mobile-friendly controls
|
|
10
|
+
- 🎮 **Skip Controls**: Built-in skip back/forward buttons with customizable durations
|
|
11
|
+
- 🎯 **Quality Control**: Automatic quality selection and manual quality switching
|
|
12
|
+
- 📊 **Analytics**: Built-in Mux analytics support
|
|
13
|
+
- 🖥️ **Chromecast Support**: Cast videos to compatible devices
|
|
14
|
+
- 🔒 **DRM Support**: Content protection with various DRM systems
|
|
15
|
+
- 📦 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @motto-ui-components/motto-video-player @tanstack/react-query
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Setup QueryClient (Required for Video wrapper)
|
|
26
|
+
|
|
27
|
+
```jsx
|
|
28
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
29
|
+
|
|
30
|
+
const queryClient = new QueryClient();
|
|
31
|
+
|
|
32
|
+
function App() {
|
|
33
|
+
return (
|
|
34
|
+
<QueryClientProvider client={queryClient}>
|
|
35
|
+
<YourComponents />
|
|
36
|
+
</QueryClientProvider>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Basic Usage
|
|
42
|
+
|
|
43
|
+
#### VideoPlayer (Bare Component)
|
|
44
|
+
For direct stream URL playback:
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
import { VideoPlayer } from '@motto-ui-components/motto-video-player';
|
|
48
|
+
|
|
49
|
+
function MyPlayer() {
|
|
50
|
+
return (
|
|
51
|
+
<VideoPlayer
|
|
52
|
+
src="https://example.com/video.m3u8"
|
|
53
|
+
controls
|
|
54
|
+
aspectRatio={16/9}
|
|
55
|
+
onPlay={() => console.log('Playing')}
|
|
56
|
+
onError={(error) => console.error(error)}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Video (Wrapper Component)
|
|
63
|
+
For data fetching with TanStack Query:
|
|
64
|
+
|
|
65
|
+
```jsx
|
|
66
|
+
import { Video } from '@motto-ui-components/motto-video-player';
|
|
67
|
+
|
|
68
|
+
function MyPlayer() {
|
|
69
|
+
return (
|
|
70
|
+
<Video
|
|
71
|
+
videoId="your-video-id"
|
|
72
|
+
publicKey="your-public-key"
|
|
73
|
+
controls
|
|
74
|
+
refetchInterval={30000}
|
|
75
|
+
events={{
|
|
76
|
+
onVideoData: (video) => console.log('Video loaded:', video),
|
|
77
|
+
onError: (error) => console.error('Error:', error),
|
|
78
|
+
onPlay: () => console.log('Playing')
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Component Comparison
|
|
86
|
+
|
|
87
|
+
| Feature | VideoPlayer | Video |
|
|
88
|
+
|---------|-------------|-------|
|
|
89
|
+
| **Use Case** | Direct stream URL | Data fetching with videoId |
|
|
90
|
+
| **Data Fetching** | ❌ Manual | ✅ Automatic with TanStack Query |
|
|
91
|
+
| **Caching** | ❌ None | ✅ Smart caching & background updates |
|
|
92
|
+
| **Loading States** | ❌ Manual | ✅ Built-in loading indicators |
|
|
93
|
+
| **Error Handling** | ❌ Manual | ✅ Automatic retry with exponential backoff |
|
|
94
|
+
| **Performance** | ✅ Minimal overhead | ✅ Optimized with query deduplication |
|
|
95
|
+
|
|
96
|
+
## Advanced Configuration
|
|
97
|
+
|
|
98
|
+
### TanStack Query Options
|
|
99
|
+
|
|
100
|
+
```jsx
|
|
101
|
+
<Video
|
|
102
|
+
videoId="123"
|
|
103
|
+
publicKey="key"
|
|
104
|
+
refetchInterval={30000}
|
|
105
|
+
queryOptions={{
|
|
106
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
107
|
+
retry: 3,
|
|
108
|
+
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000)
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Skip Controls
|
|
114
|
+
|
|
115
|
+
```jsx
|
|
116
|
+
<VideoPlayer
|
|
117
|
+
src="..."
|
|
118
|
+
skipConfig={{
|
|
119
|
+
showSkipBack: true,
|
|
120
|
+
showSkipForward: true,
|
|
121
|
+
skipDuration: 15,
|
|
122
|
+
position: 'controls' // or 'overlay'
|
|
123
|
+
}}
|
|
124
|
+
onSkipBack={(newTime) => console.log('Skipped to:', newTime)}
|
|
125
|
+
onSkipForward={(newTime) => console.log('Skipped to:', newTime)}
|
|
126
|
+
/>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Responsive Sizing
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
// Default responsive 16:9
|
|
133
|
+
<VideoPlayer src="..." />
|
|
134
|
+
|
|
135
|
+
// Custom aspect ratio
|
|
136
|
+
<VideoPlayer src="..." aspectRatio={4/3} />
|
|
137
|
+
|
|
138
|
+
// Fixed dimensions
|
|
139
|
+
<VideoPlayer src="..." width={800} height={450} />
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Analytics Integration
|
|
143
|
+
|
|
144
|
+
```jsx
|
|
145
|
+
<VideoPlayer
|
|
146
|
+
src="..."
|
|
147
|
+
muxConfig={{
|
|
148
|
+
debug: false,
|
|
149
|
+
data: {
|
|
150
|
+
env_key: 'your-mux-env-key',
|
|
151
|
+
video_title: 'Video Title',
|
|
152
|
+
video_id: 'video-123',
|
|
153
|
+
player_name: 'Web Player',
|
|
154
|
+
viewer_user_id: 'user-456'
|
|
155
|
+
}
|
|
156
|
+
}}
|
|
157
|
+
onMuxReady={(monitor) => console.log('Mux ready')}
|
|
158
|
+
/>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## API Reference
|
|
162
|
+
|
|
163
|
+
### VideoPlayer Props
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
interface VideoPlayerProps {
|
|
167
|
+
src: string; // Video source URL
|
|
168
|
+
autoPlay?: boolean; // Auto-play video
|
|
169
|
+
controls?: boolean; // Show player controls
|
|
170
|
+
aspectRatio?: number; // Video aspect ratio (default: 16/9)
|
|
171
|
+
width?: number; // Fixed width
|
|
172
|
+
height?: number; // Fixed height
|
|
173
|
+
skipConfig?: SkipConfig; // Skip controls configuration
|
|
174
|
+
muxConfig?: MuxConfig; // Mux analytics configuration
|
|
175
|
+
onPlay?: () => void; // Play event callback
|
|
176
|
+
onPause?: () => void; // Pause event callback
|
|
177
|
+
onError?: (error: any) => void; // Error event callback
|
|
178
|
+
// ... more props
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Video Props
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface VideoProps extends Omit<VideoPlayerProps, 'src'> {
|
|
186
|
+
videoId?: string; // Video ID for data fetching
|
|
187
|
+
publicKey?: string; // Public key for API authentication
|
|
188
|
+
videoData?: VideoData; // Pre-loaded video data
|
|
189
|
+
refetchInterval?: number; // Background refetch interval (ms)
|
|
190
|
+
queryOptions?: QueryOptions; // TanStack Query configuration
|
|
191
|
+
events?: {
|
|
192
|
+
onVideoData?: (video: VideoData) => void;
|
|
193
|
+
onEmptyPlaylists?: () => void;
|
|
194
|
+
onError?: (error: Error) => void;
|
|
195
|
+
// ... player events
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## TanStack Query Benefits
|
|
201
|
+
|
|
202
|
+
### Caching & Performance
|
|
203
|
+
- **Automatic Caching**: Videos are cached with configurable stale time
|
|
204
|
+
- **Background Refetching**: Data stays fresh with background updates
|
|
205
|
+
- **Request Deduplication**: Identical requests are automatically deduplicated
|
|
206
|
+
- **Garbage Collection**: Memory-efficient cleanup of unused cache entries
|
|
207
|
+
|
|
208
|
+
### Resilience & UX
|
|
209
|
+
- **Smart Retries**: Exponential backoff retry logic for failed requests
|
|
210
|
+
- **Loading States**: Built-in loading indicators for better UX
|
|
211
|
+
- **Error Recovery**: Automatic error handling and recovery mechanisms
|
|
212
|
+
- **Optimistic Updates**: Support for optimistic UI updates
|
|
213
|
+
|
|
214
|
+
## Examples
|
|
215
|
+
|
|
216
|
+
Check out the [example app](../../apps/example) for comprehensive usage examples including:
|
|
217
|
+
|
|
218
|
+
- Basic VideoPlayer usage
|
|
219
|
+
- Video wrapper with TanStack Query
|
|
220
|
+
- Pre-loaded data scenarios
|
|
221
|
+
- Skip controls integration
|
|
222
|
+
- Responsive design patterns
|
|
223
|
+
|
|
224
|
+
## Contributing
|
|
225
|
+
|
|
226
|
+
1. Clone the repository
|
|
227
|
+
2. Install dependencies: `pnpm install`
|
|
228
|
+
3. Start development: `pnpm dev`
|
|
229
|
+
4. Build: `pnpm build`
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
ISC
|