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

platform-features.mddocs/

0

# Platform-Specific Features

1

2

Platform-specific functionality including Android decoder utilities, iOS-specific features, Windows support, and Web platform capabilities with comprehensive codec support detection and platform optimization features.

3

4

## Capabilities

5

6

### VideoDecoderProperties (Android)

7

8

Utility object providing codec support detection and decoder information specifically for Android platform.

9

10

```typescript { .api }

11

/**

12

* Android-specific decoder utilities for codec support detection

13

* Platform: Android only - throws error on other platforms

14

*/

15

declare const VideoDecoderProperties: {

16

getWidevineLevel(): Promise<number>;

17

isCodecSupported(mimeType: string, width?: number, height?: number): Promise<'unsupported' | 'hardware' | 'software'>;

18

isHEVCSupported(): Promise<'unsupported' | 'hardware' | 'software'>;

19

};

20

```

21

22

**Usage Examples:**

23

24

```typescript

25

import { VideoDecoderProperties } from "react-native-video";

26

import { Platform } from "react-native";

27

28

// Check platform before using Android-specific features

29

if (Platform.OS === 'android') {

30

try {

31

// Check Widevine security level

32

const widevineLevel = await VideoDecoderProperties.getWidevineLevel();

33

console.log("Widevine security level:", widevineLevel);

34

35

// Check HEVC support

36

const hevcSupported = await VideoDecoderProperties.isHEVCSupported();

37

console.log("HEVC support:", hevcSupported); // 'unsupported' | 'hardware' | 'software'

38

39

// Check specific codec support

40

const h264Support = await VideoDecoderProperties.isCodecSupported('video/avc');

41

const vp9Support = await VideoDecoderProperties.isCodecSupported('video/x-vnd.on2.vp9');

42

43

console.log("Codec support:", { h264: h264Support, vp9: vp9Support });

44

} catch (error) {

45

console.error("Error checking decoder properties:", error);

46

}

47

}

48

```

49

50

### Widevine Security Level Detection

51

52

Get the Widevine DRM security level on Android devices.

53

54

```typescript { .api }

55

/**

56

* Get Widevine DRM security level

57

* @returns Promise resolving to security level (1 = L1, 3 = L3)

58

* @throws Error on non-Android platforms

59

* Platform: Android only

60

*/

61

getWidevineLevel(): Promise<number>;

62

```

63

64

**Usage Examples:**

65

66

```typescript

67

// Determine DRM capability based on Widevine level

68

const checkDRMCapability = async () => {

69

if (Platform.OS === 'android') {

70

try {

71

const level = await VideoDecoderProperties.getWidevineLevel();

72

73

switch (level) {

74

case 1:

75

console.log("Widevine L1: Hardware-backed security, supports HD content");

76

return "premium";

77

case 3:

78

console.log("Widevine L3: Software-based security, SD content only");

79

return "standard";

80

default:

81

console.log("Unknown Widevine level:", level);

82

return "unknown";

83

}

84

} catch (error) {

85

console.error("Failed to get Widevine level:", error);

86

return "unavailable";

87

}

88

}

89

return "not-android";

90

};

91

```

92

93

### Codec Support Detection

94

95

Check support for specific video codecs with optional resolution constraints.

96

97

```typescript { .api }

98

/**

99

* Check if a specific codec is supported

100

* @param mimeType - MIME type of the codec (e.g., 'video/avc', 'video/hevc')

101

* @param width - Optional video width constraint

102

* @param height - Optional video height constraint

103

* @returns Promise resolving to support level: 'unsupported', 'hardware', or 'software'

104

* @throws Error on non-Android platforms

105

* Platform: Android only

106

*/

107

isCodecSupported(mimeType: string, width?: number, height?: number): Promise<'unsupported' | 'hardware' | 'software'>;

108

```

109

110

**Usage Examples:**

111

112

```typescript

113

// Check codec support for different resolutions

114

const checkCodecSupport = async () => {

115

if (Platform.OS === 'android') {

116

try {

117

const codecs = [

118

{ name: 'H.264', mime: 'video/avc' },

119

{ name: 'H.265/HEVC', mime: 'video/hevc' },

120

{ name: 'VP8', mime: 'video/x-vnd.on2.vp8' },

121

{ name: 'VP9', mime: 'video/x-vnd.on2.vp9' },

122

{ name: 'AV1', mime: 'video/av01' }

123

];

124

125

const support = {};

126

127

for (const codec of codecs) {

128

// Check general support

129

const generalSupport = await VideoDecoderProperties.isCodecSupported(codec.mime);

130

131

// Check 4K support

132

const uhd4KSupport = await VideoDecoderProperties.isCodecSupported(

133

codec.mime, 3840, 2160

134

);

135

136

// Check 8K support

137

const uhd8KSupport = await VideoDecoderProperties.isCodecSupported(

138

codec.mime, 7680, 4320

139

);

140

141

support[codec.name] = {

142

general: generalSupport, // 'unsupported' | 'hardware' | 'software'

143

uhd4K: uhd4KSupport, // 'unsupported' | 'hardware' | 'software'

144

uhd8K: uhd8KSupport // 'unsupported' | 'hardware' | 'software'

145

};

146

}

147

148

console.log("Codec support matrix:", support);

149

return support;

150

} catch (error) {

151

console.error("Error checking codec support:", error);

152

return {};

153

}

154

}

155

};

156

```

157

158

### HEVC Support Detection

159

160

Convenient method to specifically check HEVC/H.265 codec support.

161

162

```typescript { .api }

163

/**

164

* Check if HEVC/H.265 codec is supported

165

* @returns Promise resolving to support level: 'unsupported', 'hardware', or 'software'

166

* @throws Error on non-Android platforms

167

* Platform: Android only

168

*/

169

isHEVCSupported(): Promise<'unsupported' | 'hardware' | 'software'>;

170

```

171

172

**Usage Examples:**

173

174

```typescript

175

// Adaptive streaming based on HEVC support

176

const selectVideoSource = async () => {

177

if (Platform.OS === 'android') {

178

try {

179

const hevcSupported = await VideoDecoderProperties.isHEVCSupported();

180

181

if (hevcSupported === 'hardware' || hevcSupported === 'software') {

182

return {

183

uri: "https://example.com/video-hevc.mp4", // Higher quality HEVC stream

184

type: "video/mp4"

185

};

186

} else {

187

return {

188

uri: "https://example.com/video-h264.mp4", // Fallback H.264 stream

189

type: "video/mp4"

190

};

191

}

192

} catch (error) {

193

console.error("Error checking HEVC support:", error);

194

// Fallback to H.264

195

return {

196

uri: "https://example.com/video-h264.mp4",

197

type: "video/mp4"

198

};

199

}

200

}

201

202

// Default for other platforms

203

return {

204

uri: "https://example.com/video.mp4",

205

type: "video/mp4"

206

};

207

};

208

```

209

210

## Platform-Specific Component Features

211

212

### Android-Specific Props and Features

213

214

Android platform provides additional configuration options and features.

215

216

```typescript { .api }

217

/**

218

* Android-specific Video component props

219

*/

220

interface AndroidVideoProps {

221

// View configuration

222

viewType?: 0 | 1 | 2; // TEXTURE | SURFACE | SURFACE_SECURE

223

useTextureView?: boolean; // Deprecated: use viewType

224

useSecureView?: boolean; // Deprecated: use viewType

225

226

// UI and interaction

227

focusable?: boolean;

228

disableFocus?: boolean;

229

hideShutterView?: boolean;

230

shutterColor?: string;

231

232

// Playback control

233

currentPlaybackTime?: number;

234

reportBandwidth?: boolean;

235

disableDisconnectError?: boolean;

236

237

// Controls customization

238

controlsStyles?: ControlsStyles;

239

240

// Subtitle styling

241

subtitleStyle?: SubtitleStyle;

242

243

// Buffer configuration

244

bufferConfig?: BufferConfig;

245

minLoadRetryCount?: number;

246

}

247

248

/**

249

* View types for Android video rendering

250

*/

251

enum ViewType {

252

TEXTURE = 0, // TextureView - supports animation and transformation

253

SURFACE = 1, // SurfaceView - better performance, limited functionality

254

SURFACE_SECURE = 2 // Secure SurfaceView - required for DRM content

255

}

256

```

257

258

**Usage Examples:**

259

260

```typescript

261

// Android-specific configuration

262

<Video

263

source={{ uri: "https://example.com/video.mp4" }}

264

viewType={1} // Use SurfaceView for better performance

265

reportBandwidth={true}

266

shutterColor="#000000"

267

controlsStyles={{

268

hideSeekBar: false,

269

seekIncrementMS: 15000,

270

liveLabel: "LIVE"

271

}}

272

subtitleStyle={{

273

fontSize: 16,

274

paddingTop: 2,

275

paddingBottom: 2,

276

opacity: 0.8

277

}}

278

/>

279

280

// DRM content with secure view

281

<Video

282

source={{

283

uri: "https://example.com/drm-content.mpd",

284

drm: {

285

type: "widevine",

286

licenseServer: "https://license-server.com"

287

}

288

}}

289

viewType={2} // SURFACE_SECURE required for DRM

290

useSecureView={true}

291

/>

292

```

293

294

### iOS-Specific Props and Features

295

296

iOS platform provides additional features for media control and presentation.

297

298

```typescript { .api }

299

/**

300

* iOS-specific Video component props

301

*/

302

interface iOSVideoProps {

303

// Fullscreen configuration

304

fullscreen?: boolean;

305

fullscreenAutorotate?: boolean;

306

fullscreenOrientation?: "all" | "landscape" | "portrait";

307

308

// Audio configuration

309

ignoreSilentSwitch?: "inherit" | "ignore" | "obey";

310

mixWithOthers?: "inherit" | "mix" | "duck";

311

playWhenInactive?: boolean;

312

automaticallyWaitsToMinimizeStalling?: boolean;

313

disableAudioSessionManagement?: boolean;

314

315

// External playback

316

allowsExternalPlayback?: boolean;

317

318

// Video processing

319

filter?: string;

320

filterEnabled?: boolean;

321

preferredForwardBufferDuration?: number;

322

323

// Chapter support

324

chapters?: Chapters[];

325

}

326

327

/**

328

* Chapter information for iOS

329

*/

330

interface Chapters {

331

title: string;

332

startTime: number;

333

endTime: number;

334

uri?: string;

335

}

336

```

337

338

**Usage Examples:**

339

340

```typescript

341

// iOS-specific configuration

342

<Video

343

source={{ uri: "https://example.com/video.mp4" }}

344

fullscreenOrientation="landscape"

345

ignoreSilentSwitch="ignore" // Continue playing even when silent switch is on

346

mixWithOthers="duck" // Duck other audio when playing

347

allowsExternalPlayback={true} // Enable AirPlay

348

chapters={[

349

{ title: "Introduction", startTime: 0, endTime: 30 },

350

{ title: "Main Content", startTime: 30, endTime: 300 },

351

{ title: "Conclusion", startTime: 300, endTime: 330 }

352

]}

353

filter="CIColorMonochrome"

354

filterEnabled={true}

355

/>

356

```

357

358

### Windows-Specific Features

359

360

Windows platform support through MediaPlayerElement.

361

362

```typescript { .api }

363

/**

364

* Windows-specific features (limited compared to mobile platforms)

365

*/

366

interface WindowsVideoProps {

367

// Basic playback control supported

368

// Limited event support compared to mobile platforms

369

}

370

```

371

372

### Web Platform Features

373

374

Web platform implementation using HTML5 video element with React Native Web.

375

376

```typescript { .api }

377

/**

378

* Web-specific Video component props and features

379

*/

380

interface WebVideoProps {

381

// Loader customization

382

renderLoader?: ReactNode | ((props: ReactVideoRenderLoaderProps) => ReactNode);

383

384

// Direct HTML video element access

385

nativeHtmlVideoRef?: RefObject<HTMLVideoElement | null>; // Via VideoRef

386

}

387

388

/**

389

* Render loader props for web platform

390

*/

391

interface ReactVideoRenderLoaderProps {

392

source?: ReactVideoSource;

393

style?: StyleProp<ImageStyle>;

394

resizeMode?: "none" | "contain" | "cover" | "stretch";

395

}

396

```

397

398

**Usage Examples:**

399

400

```typescript

401

// Web-specific loader

402

<Video

403

source={{ uri: "https://example.com/video.mp4" }}

404

renderLoader={({ style }) => (

405

<View style={style}>

406

<Text>Loading video...</Text>

407

</View>

408

)}

409

/>

410

411

// Access HTML video element

412

const videoRef = useRef<VideoRef>(null);

413

414

useEffect(() => {

415

if (Platform.OS === 'web' && videoRef.current?.nativeHtmlVideoRef?.current) {

416

const htmlVideo = videoRef.current.nativeHtmlVideoRef.current;

417

418

// Add custom HTML video event listeners

419

htmlVideo.addEventListener('canplaythrough', () => {

420

console.log("HTML video can play through");

421

});

422

423

// Access HTML video properties

424

console.log("Video element ready state:", htmlVideo.readyState);

425

}

426

}, []);

427

```

428

429

## Platform Detection and Adaptive Features

430

431

### Comprehensive Platform Capability Detection

432

433

```typescript

434

import { Platform } from "react-native";

435

import { VideoDecoderProperties } from "react-native-video";

436

437

const detectPlatformCapabilities = async () => {

438

const capabilities = {

439

platform: Platform.OS,

440

drm: {},

441

codecs: {},

442

features: {}

443

};

444

445

// Platform-specific capability detection

446

switch (Platform.OS) {

447

case 'android':

448

try {

449

capabilities.drm.widevineLevel = await VideoDecoderProperties.getWidevineLevel();

450

capabilities.codecs.hevc = await VideoDecoderProperties.isHEVCSupported();

451

capabilities.codecs.h264 = await VideoDecoderProperties.isCodecSupported('video/avc');

452

capabilities.codecs.vp9 = await VideoDecoderProperties.isCodecSupported('video/x-vnd.on2.vp9');

453

454

capabilities.features = {

455

pictureInPicture: true,

456

backgroundAudio: true,

457

externalPlayback: false,

458

customControls: true,

459

subtitleStyling: true

460

};

461

} catch (error) {

462

console.error("Android capability detection failed:", error);

463

}

464

break;

465

466

case 'ios':

467

capabilities.drm = { fairplay: true };

468

capabilities.features = {

469

pictureInPicture: true,

470

backgroundAudio: true,

471

externalPlayback: true, // AirPlay

472

customControls: false,

473

chapters: true,

474

filters: true

475

};

476

break;

477

478

case 'web':

479

capabilities.features = {

480

pictureInPicture: false,

481

backgroundAudio: false,

482

externalPlayback: false,

483

customLoader: true,

484

htmlVideoAccess: true

485

};

486

break;

487

488

case 'windows':

489

capabilities.features = {

490

basicPlayback: true,

491

limitedEvents: true

492

};

493

break;

494

}

495

496

return capabilities;

497

};

498

```

499

500

### Adaptive Video Source Selection

501

502

```typescript

503

const selectOptimalVideoSource = async (baseUrl: string) => {

504

const capabilities = await detectPlatformCapabilities();

505

506

// Select best video source based on platform capabilities

507

if (Platform.OS === 'android' && capabilities.codecs.hevc) {

508

return {

509

uri: `${baseUrl}/video-hevc.mp4`,

510

type: "video/mp4"

511

};

512

}

513

514

if (Platform.OS === 'ios') {

515

return {

516

uri: `${baseUrl}/video-hls.m3u8`,

517

type: "application/x-mpegURL"

518

};

519

}

520

521

// Fallback for other platforms

522

return {

523

uri: `${baseUrl}/video-h264.mp4`,

524

type: "video/mp4"

525

};

526

};

527

```