0
# Advanced Features & MSE
1
2
Media Source Extensions (MSE), Encrypted Media Extensions (EME) support, utility functions, and advanced audio features for streaming and encrypted content.
3
4
## Capabilities
5
6
### Media Source Extensions (MSE) Support
7
8
Support for Media Source Extensions allowing for advanced streaming capabilities and custom media handling.
9
10
```typescript { .api }
11
interface MSEPropsObject {
12
/** Custom seek handler for MSE streams */
13
onSeek: OnSeek;
14
/** Handler for encrypted media events */
15
onEcrypted?: (e: unknown) => void;
16
/** Total duration of the source in seconds (required for MSE) */
17
srcDuration: number;
18
}
19
20
type OnSeek = (audio: HTMLAudioElement, time: number) => Promise<void>;
21
```
22
23
When MSE configuration is provided:
24
- The `onSeek` function handles all seeking operations instead of standard `currentTime` setting
25
- `srcDuration` is used to display total duration instead of `audio.duration`
26
- `onEcrypted` handles Encrypted Media Extensions (EME) events
27
- Progress bar and duration display adapt to work with MSE streams
28
29
### Component Instance Access
30
31
Access to the underlying HTML audio element and component methods for advanced control.
32
33
### Component Instance Methods
34
35
Methods available on the H5AudioPlayer component instance for programmatic control.
36
37
```typescript { .api }
38
class H5AudioPlayer extends Component<PlayerProps> {
39
/** Toggle between play and pause states */
40
togglePlay(e: React.SyntheticEvent): void;
41
42
/** Safely play audio with promise-based error handling */
43
playAudioPromise(): void;
44
45
/** Check if audio is currently playing */
46
isPlaying(): boolean;
47
48
/** Reference to the underlying HTML audio element */
49
audio: React.RefObject<HTMLAudioElement>;
50
51
/** Reference to the progress bar container */
52
progressBar: React.RefObject<HTMLDivElement>;
53
54
/** Reference to the main player container */
55
container: React.RefObject<HTMLDivElement>;
56
}
57
```
58
59
### Error Handling
60
61
Advanced error handling for playback and seeking operations.
62
63
```typescript { .api }
64
interface ErrorHandlers {
65
/** Called when audio.play() promise is rejected */
66
onPlayError?: (err: Error) => void;
67
68
/** Called when currentTime change operations fail */
69
onChangeCurrentTimeError?: (err: Error) => void;
70
}
71
```
72
73
Common error scenarios:
74
- Browser autoplay policy violations
75
- Network connectivity issues during streaming
76
- Codec compatibility problems
77
- MSE/EME setup failures
78
79
### Performance Configuration
80
81
Fine-tune performance and responsiveness through various timing configurations.
82
83
```typescript { .api }
84
interface PerformanceConfig {
85
/** Frequency of progress bar updates in milliseconds */
86
progressUpdateInterval?: number;
87
88
/** Frequency of onListen event firing in milliseconds */
89
listenInterval?: number;
90
91
/** Jump distance for keyboard/button controls in milliseconds */
92
progressJumpStep?: number;
93
94
/** Separate jump distances for backward/forward */
95
progressJumpSteps?: {
96
backward?: number;
97
forward?: number;
98
};
99
100
/** Volume increment for volume controls */
101
volumeJumpStep?: number;
102
}
103
```
104
105
**Performance Recommendations:**
106
- Lower `progressUpdateInterval` (10-50ms) for smoother progress bars
107
- Higher `listenInterval` (500-2000ms) for less frequent position tracking
108
- Adjust jump steps based on content type (music vs podcasts vs audiobooks)
109
110
## Usage Examples
111
112
**MSE Configuration for Streaming:**
113
114
```typescript
115
import AudioPlayer from 'react-h5-audio-player';
116
117
const streamingPlayer = () => {
118
const handleMSESeek = async (audio: HTMLAudioElement, time: number) => {
119
// Custom seek implementation for MSE
120
try {
121
await myStreamingService.seekTo(time);
122
// Update UI to reflect new position
123
console.log(`Seeking to ${time} seconds`);
124
} catch (error) {
125
console.error('Seek failed:', error);
126
}
127
};
128
129
const handleEncrypted = (e: unknown) => {
130
// Handle EME for encrypted content
131
console.log('Encrypted media detected', e);
132
// Setup MediaKeys, licenses, etc.
133
};
134
135
return (
136
<AudioPlayer
137
src="blob:https://example.com/stream"
138
mse={{
139
onSeek: handleMSESeek,
140
onEcrypted: handleEncrypted,
141
srcDuration: 3600 // 1 hour in seconds
142
}}
143
onError={(e) => console.error('Streaming error:', e)}
144
/>
145
);
146
};
147
```
148
149
**Custom Error Handling:**
150
151
```typescript
152
<AudioPlayer
153
src="audio.mp3"
154
onPlayError={(err) => {
155
console.error('Playback failed:', err);
156
// Show user-friendly error message
157
if (err.message.includes('NotAllowedError')) {
158
alert('Please click play to start audio (browser autoplay policy)');
159
}
160
}}
161
onChangeCurrentTimeError={(err) => {
162
console.error('Seek failed:', err);
163
// Handle seek failures gracefully
164
}}
165
onError={(e) => {
166
const audio = e.target as HTMLAudioElement;
167
if (audio.error) {
168
switch (audio.error.code) {
169
case MediaError.MEDIA_ERR_NETWORK:
170
console.error('Network error loading audio');
171
break;
172
case MediaError.MEDIA_ERR_DECODE:
173
console.error('Audio decoding error');
174
break;
175
case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
176
console.error('Audio format not supported');
177
break;
178
default:
179
console.error('Unknown audio error');
180
}
181
}
182
}}
183
/>
184
```
185
186
**Performance Tuning:**
187
188
```typescript
189
<AudioPlayer
190
src="audio.mp3"
191
progressUpdateInterval={20} // Smooth 50fps progress updates
192
listenInterval={250} // Position tracking 4x per second
193
progressJumpStep={10000} // 10 second jumps
194
progressJumpSteps={{
195
backward: 15000, // 15 second rewind
196
forward: 30000 // 30 second skip forward
197
}}
198
volumeJumpStep={0.1} // 10% volume increments
199
/>
200
```
201
202
**Programmatic Control:**
203
204
```typescript
205
import React, { useRef, useEffect } from 'react';
206
import AudioPlayer from 'react-h5-audio-player';
207
208
const ControlledPlayer = () => {
209
const playerRef = useRef<AudioPlayer>(null);
210
211
useEffect(() => {
212
// Example: Auto-play after 3 seconds
213
const timer = setTimeout(() => {
214
if (playerRef.current) {
215
playerRef.current.playAudioPromise();
216
}
217
}, 3000);
218
219
return () => clearTimeout(timer);
220
}, []);
221
222
const handleExternalPlay = () => {
223
if (playerRef.current) {
224
playerRef.current.togglePlay({} as React.SyntheticEvent);
225
}
226
};
227
228
const checkPlayingStatus = () => {
229
if (playerRef.current) {
230
const isPlaying = playerRef.current.isPlaying();
231
console.log('Currently playing:', isPlaying);
232
}
233
};
234
235
return (
236
<div>
237
<AudioPlayer
238
ref={playerRef}
239
src="audio.mp3"
240
/>
241
<button onClick={handleExternalPlay}>
242
External Play/Pause
243
</button>
244
<button onClick={checkPlayingStatus}>
245
Check Status
246
</button>
247
</div>
248
);
249
};
250
```
251
252
**Custom Time Display:**
253
254
```typescript
255
// The utility functions are internal to the component and not exported
256
// Time formatting is handled automatically by the component based on timeFormat prop
257
258
<AudioPlayer
259
src="audio.mp3"
260
timeFormat="mm:ss" // or "hh:mm:ss" or "auto"
261
onListen={(e) => {
262
const audio = e.target as HTMLAudioElement;
263
console.log('Position update:', audio.currentTime);
264
// Custom logic for position tracking
265
}}
266
/>
267
```
268
269
**Advanced Accessibility:**
270
271
```typescript
272
<AudioPlayer
273
src="podcast.mp3"
274
i18nAriaLabels={{
275
player: 'Podcast Player',
276
progressControl: 'Playback progress, use arrow keys to seek',
277
volumeControl: 'Volume control, use arrow keys to adjust',
278
play: 'Play podcast',
279
pause: 'Pause podcast',
280
rewind: 'Rewind 15 seconds',
281
forward: 'Skip forward 30 seconds'
282
}}
283
progressJumpSteps={{
284
backward: 15000, // 15s rewind for podcasts
285
forward: 30000 // 30s skip for podcasts
286
}}
287
/>
288
```