or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

event-handling.mdexpo-configuration.mdindex.mdplatform-features.mdvideo-component.mdvideo-ref-methods.mdvideo-sources.md

event-handling.mddocs/

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

```