0
# Event Handling
1
2
Comprehensive event system covering playback events, state changes, track information, buffering, error handling, and platform-specific events for complete video playback monitoring and control.
3
4
## Capabilities
5
6
### ReactVideoEvents Interface
7
8
Main interface defining all available event handlers for the Video component.
9
10
```typescript { .api }
11
/**
12
* Complete event handling interface for video playback monitoring
13
* All events are optional and provide detailed information about video state
14
*/
15
interface ReactVideoEvents {
16
// Core Playback Events
17
onLoad?: (e: OnLoadData) => void;
18
onLoadStart?: (e: OnLoadStartData) => void;
19
onProgress?: (e: OnProgressData) => void;
20
onEnd?: () => void;
21
onError?: (e: OnVideoErrorData) => void;
22
onSeek?: (e: OnSeekData) => void;
23
24
// State Change Events
25
onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void;
26
onPlaybackRateChange?: (e: OnPlaybackRateChangeData) => void;
27
onVolumeChange?: (e: OnVolumeChangeData) => void;
28
onBuffer?: (e: OnBufferData) => void;
29
onReadyForDisplay?: () => void;
30
31
// Track Events
32
onAudioTracks?: (e: OnAudioTracksData) => void;
33
onTextTracks?: (e: OnTextTracksData) => void;
34
onVideoTracks?: (e: OnVideoTracksData) => void;
35
onTextTrackDataChanged?: (e: OnTextTrackDataChangedData) => void;
36
onAspectRatio?: (e: OnVideoAspectRatioData) => void;
37
38
// UI & Interaction Events
39
onFullscreenPlayerWillPresent?: () => void;
40
onFullscreenPlayerDidPresent?: () => void;
41
onFullscreenPlayerWillDismiss?: () => void;
42
onFullscreenPlayerDidDismiss?: () => void;
43
onControlsVisibilityChange?: (e: OnControlsVisibilityChange) => void;
44
45
// Picture-in-Picture Events
46
onPictureInPictureStatusChanged?: (e: OnPictureInPictureStatusChangedData) => void;
47
onRestoreUserInterfaceForPictureInPictureStop?: () => void;
48
49
// Platform-Specific Events
50
onAudioBecomingNoisy?: () => void;
51
onAudioFocusChanged?: (e: OnAudioFocusChangedData) => void;
52
onIdle?: () => void;
53
onExternalPlaybackChange?: (e: OnExternalPlaybackChangeData) => void;
54
onBandwidthUpdate?: (e: OnBandwidthUpdateData) => void;
55
onTimedMetadata?: (e: OnTimedMetadataData) => void;
56
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void;
57
}
58
```
59
60
**Usage Examples:**
61
62
```typescript
63
<Video
64
source={{ uri: "https://example.com/video.mp4" }}
65
onLoad={(data) => {
66
console.log("Video loaded:", {
67
duration: data.duration,
68
naturalSize: data.naturalSize,
69
audioTracks: data.audioTracks.length,
70
textTracks: data.textTracks.length
71
});
72
}}
73
onProgress={(data) => {
74
console.log(`Progress: ${data.currentTime}/${data.seekableDuration}`);
75
}}
76
onError={(error) => {
77
console.error("Video error:", error.error.errorString);
78
}}
79
onEnd={() => {
80
console.log("Video playback completed");
81
}}
82
/>
83
```
84
85
### Core Playback Events
86
87
Events related to video loading, progress, and basic playback state.
88
89
```typescript { .api }
90
/**
91
* Fired when video metadata and tracks are loaded
92
*/
93
interface OnLoadData {
94
currentTime: number;
95
duration: number;
96
naturalSize: {
97
width: number;
98
height: number;
99
orientation: "landscape" | "portrait";
100
};
101
audioTracks: AudioTrack[];
102
textTracks: TextTrack[];
103
videoTracks: VideoTrack[];
104
}
105
106
/**
107
* Fired when video loading begins
108
*/
109
interface OnLoadStartData {
110
isNetwork: boolean;
111
type: string;
112
uri: string;
113
}
114
115
/**
116
* Fired periodically during playback with current progress
117
*/
118
interface OnProgressData {
119
currentTime: number;
120
playableDuration: number;
121
seekableDuration: number;
122
}
123
124
/**
125
* Fired when seek operation completes
126
*/
127
interface OnSeekData {
128
currentTime: number;
129
seekTime: number;
130
}
131
132
/**
133
* Fired when video playback error occurs
134
*/
135
interface OnVideoErrorData {
136
error: {
137
errorString: string;
138
errorException: string;
139
errorStackTrace: string;
140
errorCode: string;
141
domain?: string;
142
};
143
}
144
```
145
146
**Usage Examples:**
147
148
```typescript
149
<Video
150
source={{ uri: "https://example.com/video.mp4" }}
151
onLoadStart={(data) => {
152
console.log("Loading started:", data.uri, "Network:", data.isNetwork);
153
}}
154
onLoad={(data) => {
155
console.log("Video loaded:", {
156
duration: Math.round(data.duration),
157
resolution: `${data.naturalSize.width}x${data.naturalSize.height}`,
158
orientation: data.naturalSize.orientation,
159
tracks: {
160
audio: data.audioTracks.length,
161
text: data.textTracks.length,
162
video: data.videoTracks.length
163
}
164
});
165
}}
166
onProgress={(data) => {
167
const progress = (data.currentTime / data.seekableDuration) * 100;
168
console.log(`Progress: ${progress.toFixed(1)}%`);
169
}}
170
onSeek={(data) => {
171
console.log(`Seek completed: ${data.currentTime}s (target: ${data.seekTime}s)`);
172
}}
173
onError={(error) => {
174
console.error("Playback error:", {
175
code: error.error.errorCode,
176
message: error.error.errorString,
177
domain: error.error.domain
178
});
179
}}
180
/>
181
```
182
183
### State Change Events
184
185
Events for monitoring playback state, rate, and volume changes.
186
187
```typescript { .api }
188
/**
189
* Fired when playback state changes (play/pause/buffering/idle)
190
*/
191
interface OnPlaybackStateChangedData {
192
isPlaying: boolean;
193
}
194
195
/**
196
* Fired when playback rate changes
197
*/
198
interface OnPlaybackRateChangeData {
199
playbackRate: number;
200
}
201
202
/**
203
* Fired when volume changes
204
*/
205
interface OnVolumeChangeData {
206
volume: number;
207
}
208
209
/**
210
* Fired during buffering events
211
*/
212
interface OnBufferData {
213
isBuffering: boolean;
214
}
215
```
216
217
**Usage Examples:**
218
219
```typescript
220
<Video
221
source={{ uri: "https://example.com/video.mp4" }}
222
onPlaybackStateChanged={(data) => {
223
console.log("Playback state:", data.isPlaying ? "Playing" : "Paused");
224
}}
225
onPlaybackRateChange={(data) => {
226
console.log("Playback rate changed to:", data.playbackRate);
227
}}
228
onVolumeChange={(data) => {
229
console.log("Volume changed to:", Math.round(data.volume * 100) + "%");
230
}}
231
onBuffer={(data) => {
232
console.log("Buffering:", data.isBuffering ? "Started" : "Finished");
233
}}
234
onReadyForDisplay={() => {
235
console.log("Video is ready for display");
236
}}
237
/>
238
```
239
240
### Track Information Events
241
242
Events providing information about available and selected tracks.
243
244
```typescript { .api }
245
/**
246
* Audio track information
247
*/
248
interface AudioTrack {
249
index: number;
250
title?: string;
251
language?: string;
252
bitrate?: number;
253
type?: string;
254
selected?: boolean;
255
}
256
257
/**
258
* Text track information
259
*/
260
interface TextTrack {
261
index: number;
262
title?: string;
263
language?: string;
264
type?: "srt" | "ttml" | "vtt";
265
selected?: boolean;
266
}
267
268
/**
269
* Video track information
270
*/
271
interface VideoTrack {
272
index: number;
273
tracksID?: string;
274
codecs?: string;
275
width?: number;
276
height?: number;
277
bitrate?: number;
278
selected?: boolean;
279
}
280
281
/**
282
* Fired when audio tracks are available
283
*/
284
interface OnAudioTracksData {
285
audioTracks: AudioTrack[];
286
}
287
288
/**
289
* Fired when text tracks are available
290
*/
291
interface OnTextTracksData {
292
textTracks: TextTrack[];
293
}
294
295
/**
296
* Fired when video tracks are available
297
*/
298
interface OnVideoTracksData {
299
videoTracks: VideoTrack[];
300
}
301
302
/**
303
* Fired when text track data changes (iOS)
304
*/
305
interface OnTextTrackDataChangedData {
306
subtitleTracks: TextTrack[];
307
}
308
309
/**
310
* Fired when video aspect ratio changes
311
*/
312
interface OnVideoAspectRatioData {
313
aspectRatio: number;
314
}
315
```
316
317
**Usage Examples:**
318
319
```typescript
320
<Video
321
source={{ uri: "https://example.com/video.mp4" }}
322
onAudioTracks={(data) => {
323
console.log("Audio tracks available:");
324
data.audioTracks.forEach(track => {
325
console.log(`- ${track.title || 'Track ' + track.index}: ${track.language} (${track.bitrate}bps)`);
326
});
327
}}
328
onTextTracks={(data) => {
329
console.log("Text tracks available:");
330
data.textTracks.forEach(track => {
331
console.log(`- ${track.title || 'Track ' + track.index}: ${track.language} (${track.type})`);
332
});
333
}}
334
onVideoTracks={(data) => {
335
console.log("Video tracks available:");
336
data.videoTracks.forEach(track => {
337
console.log(`- Track ${track.index}: ${track.width}x${track.height} (${track.bitrate}bps)`);
338
});
339
}}
340
onAspectRatio={(data) => {
341
console.log("Aspect ratio changed to:", data.aspectRatio);
342
}}
343
/>
344
```
345
346
### UI & Fullscreen Events
347
348
Events related to user interface changes and fullscreen transitions.
349
350
```typescript { .api }
351
/**
352
* Fired when controls visibility changes
353
*/
354
interface OnControlsVisibilityChange {
355
isVisible: boolean;
356
}
357
```
358
359
**Usage Examples:**
360
361
```typescript
362
<Video
363
source={{ uri: "https://example.com/video.mp4" }}
364
controls={true}
365
onFullscreenPlayerWillPresent={() => {
366
console.log("Fullscreen presentation will start");
367
}}
368
onFullscreenPlayerDidPresent={() => {
369
console.log("Fullscreen presentation completed");
370
}}
371
onFullscreenPlayerWillDismiss={() => {
372
console.log("Fullscreen dismissal will start");
373
}}
374
onFullscreenPlayerDidDismiss={() => {
375
console.log("Fullscreen dismissal completed");
376
}}
377
onControlsVisibilityChange={(data) => {
378
console.log("Controls are now:", data.isVisible ? "visible" : "hidden");
379
}}
380
/>
381
```
382
383
### Picture-in-Picture Events
384
385
Events for Picture-in-Picture mode changes and state restoration.
386
387
```typescript { .api }
388
/**
389
* Fired when Picture-in-Picture status changes
390
*/
391
interface OnPictureInPictureStatusChangedData {
392
isActive: boolean;
393
}
394
```
395
396
**Usage Examples:**
397
398
```typescript
399
<Video
400
source={{ uri: "https://example.com/video.mp4" }}
401
onPictureInPictureStatusChanged={(data) => {
402
console.log("Picture-in-Picture:", data.isActive ? "Active" : "Inactive");
403
}}
404
onRestoreUserInterfaceForPictureInPictureStop={() => {
405
console.log("Restore UI for PiP stop requested");
406
// Restore your app's UI here
407
}}
408
/>
409
```
410
411
### Platform-Specific Events
412
413
Events that are specific to certain platforms or provide platform-specific information.
414
415
```typescript { .api }
416
/**
417
* Audio focus change event (Android)
418
*/
419
interface OnAudioFocusChangedData {
420
hasAudioFocus: boolean;
421
}
422
423
/**
424
* External playback change event (iOS)
425
*/
426
interface OnExternalPlaybackChangeData {
427
isExternalPlaybackActive: boolean;
428
}
429
430
/**
431
* Bandwidth update event (Android)
432
*/
433
interface OnBandwidthUpdateData {
434
bitrate: number;
435
}
436
437
/**
438
* Timed metadata event (Android, iOS)
439
*/
440
interface OnTimedMetadataData {
441
metadata: {
442
identifier: string;
443
value: string;
444
}[];
445
}
446
```
447
448
**Usage Examples:**
449
450
```typescript
451
<Video
452
source={{ uri: "https://example.com/video.mp4" }}
453
// Android events
454
onAudioFocusChanged={(data) => {
455
console.log("Audio focus:", data.hasAudioFocus ? "gained" : "lost");
456
}}
457
onBandwidthUpdate={(data) => {
458
console.log("Current bitrate:", Math.round(data.bitrate / 1000) + " kbps");
459
}}
460
onIdle={() => {
461
console.log("Player entered idle state");
462
}}
463
464
// iOS events
465
onExternalPlaybackChange={(data) => {
466
console.log("AirPlay:", data.isExternalPlaybackActive ? "active" : "inactive");
467
}}
468
469
// Cross-platform events
470
onAudioBecomingNoisy={() => {
471
console.log("Audio becoming noisy (headphones unplugged?)");
472
// Pause playback
473
}}
474
onTimedMetadata={(data) => {
475
console.log("Timed metadata received:");
476
data.metadata.forEach(item => {
477
console.log(`- ${item.identifier}: ${item.value}`);
478
});
479
}}
480
/>
481
```
482
483
### Advertisement Events
484
485
Events related to advertisement playback and interaction.
486
487
```typescript { .api }
488
/**
489
* Advertisement event data
490
*/
491
interface OnReceiveAdEventData {
492
event: AdEvent;
493
data?: object;
494
}
495
```
496
497
**Usage Examples:**
498
499
```typescript
500
<Video
501
source={{
502
uri: "https://example.com/video.mp4",
503
ad: {
504
adTagUrl: "https://pubads.g.doubleclick.net/gampad/ads?...",
505
adLanguage: "en"
506
}
507
}}
508
onReceiveAdEvent={(data) => {
509
console.log("Ad event:", data.event);
510
511
switch (data.event) {
512
case "LOADED":
513
console.log("Ad loaded and ready to play");
514
break;
515
case "STARTED":
516
console.log("Ad playback started");
517
break;
518
case "COMPLETED":
519
console.log("Ad playback completed");
520
break;
521
case "ERROR":
522
console.error("Ad error:", data.data);
523
break;
524
case "CLICK":
525
console.log("Ad was clicked");
526
break;
527
}
528
}}
529
/>
530
```
531
532
## Event Usage Patterns
533
534
### Progress Tracking with State Management
535
536
```typescript
537
import React, { useState } from "react";
538
import Video from "react-native-video";
539
540
function VideoPlayerWithProgress() {
541
const [progress, setProgress] = useState({ currentTime: 0, duration: 0 });
542
const [isBuffering, setIsBuffering] = useState(false);
543
544
return (
545
<Video
546
source={{ uri: "https://example.com/video.mp4" }}
547
onLoad={(data) => {
548
setProgress(prev => ({ ...prev, duration: data.duration }));
549
}}
550
onProgress={(data) => {
551
setProgress(prev => ({ ...prev, currentTime: data.currentTime }));
552
}}
553
onBuffer={(data) => {
554
setIsBuffering(data.isBuffering);
555
}}
556
/>
557
);
558
}
559
```
560
561
### Error Handling and Recovery
562
563
```typescript
564
function VideoPlayerWithErrorHandling() {
565
const [error, setError] = useState<string | null>(null);
566
const [retryCount, setRetryCount] = useState(0);
567
568
const handleError = (errorData: OnVideoErrorData) => {
569
console.error("Video error:", errorData.error);
570
setError(errorData.error.errorString);
571
572
// Implement retry logic
573
if (retryCount < 3) {
574
setTimeout(() => {
575
setRetryCount(prev => prev + 1);
576
setError(null);
577
}, 2000);
578
}
579
};
580
581
return (
582
<Video
583
source={{ uri: "https://example.com/video.mp4" }}
584
onError={handleError}
585
onLoad={() => {
586
setError(null);
587
setRetryCount(0);
588
}}
589
/>
590
);
591
}
592
```