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
```