@jwplayer/jwplayer-react-native 1.1.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +114 -21
  2. package/RNJWPlayer.podspec +1 -1
  3. package/android/build.gradle +14 -1
  4. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerModule.java +27 -0
  5. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +373 -204
  6. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +16 -0
  7. package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +13 -1
  8. package/badges/version.svg +1 -1
  9. package/docs/CONFIG-REFERENCE.md +747 -0
  10. package/docs/MIGRATION-GUIDE.md +617 -0
  11. package/docs/PLATFORM-DIFFERENCES.md +693 -0
  12. package/docs/props.md +15 -3
  13. package/index.d.ts +225 -216
  14. package/index.js +34 -0
  15. package/ios/RNJWPlayer/RNJWPlayerView.swift +365 -10
  16. package/ios/RNJWPlayer/RNJWPlayerViewController.swift +45 -16
  17. package/ios/RNJWPlayer/RNJWPlayerViewManager.m +2 -0
  18. package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +13 -0
  19. package/package.json +2 -2
  20. package/types/advertising.d.ts +514 -0
  21. package/types/index.d.ts +21 -0
  22. package/types/legacy.d.ts +82 -0
  23. package/types/platform-specific.d.ts +641 -0
  24. package/types/playlist.d.ts +410 -0
  25. package/types/unified-config.d.ts +591 -0
  26. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  27. package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
  28. package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
  29. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  30. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  31. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  32. package/android/.gradle/8.9/gc.properties +0 -0
  33. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  34. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  35. package/android/.gradle/vcs-1/gc.properties +0 -0
  36. package/docs/types.md +0 -254
@@ -0,0 +1,693 @@
1
+ # Platform Differences Guide
2
+
3
+ This guide documents the differences between iOS and Android platforms when using JWPlayer React Native.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Configuration Naming Differences](#configuration-naming-differences)
9
+ - [iOS-Specific Features](#ios-specific-features)
10
+ - [Android-Specific Features](#android-specific-features)
11
+ - [Cross-Platform Best Practices](#cross-platform-best-practices)
12
+ - [Common Gotchas](#common-gotchas)
13
+
14
+ ---
15
+
16
+ ## Overview
17
+
18
+ The JWPlayer React Native wrapper provides a **unified configuration interface** that works across both platforms. However, some features are platform-specific due to native SDK differences.
19
+
20
+ ### Platform Detection
21
+
22
+ ```typescript
23
+ import { Platform } from 'react-native';
24
+
25
+ const config: JWPlayerConfig = {
26
+ license: Platform.OS === 'ios' ? 'IOS_LICENSE' : 'ANDROID_LICENSE',
27
+ file: 'https://example.com/video.m3u8',
28
+
29
+ // Platform-specific feature
30
+ ...(Platform.OS === 'ios' && {
31
+ styling: {
32
+ colors: { buttons: '#FF0000' }
33
+ }
34
+ }),
35
+
36
+ ...(Platform.OS === 'android' && {
37
+ uiConfig: {
38
+ hasControlbar: true,
39
+ hasOverlay: true
40
+ }
41
+ })
42
+ };
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Configuration Naming Differences
48
+
49
+ ### IMA DAI Settings
50
+
51
+ **Field Name Differences:**
52
+
53
+ | Feature | iOS Parser | Android Parser | **Recommended** |
54
+ |---------|-----------|----------------|-----------------|
55
+ | DAI Settings Object | `googimadai` | `imaDaiSettings` | `imaDaiSettings` ✅ |
56
+ | DAI Settings (alternate) | `googleimadaisettings` | `imaDaiSettings` | `imaDaiSettings` ✅ |
57
+ | IMA Settings Object | `imaSettings` | `imaSdkSettings` | `imaSdkSettings` ✅ |
58
+ | Video ID | `videoID` | `videoId` | `videoId` ✅ |
59
+ | CMS ID | `cmsID` | `cmsId` | `cmsId` ✅ |
60
+
61
+ **✅ Recommended Cross-Platform Config:**
62
+
63
+ ```typescript
64
+ const config: JWPlayerConfig = {
65
+ license: 'YOUR_LICENSE_KEY',
66
+ file: 'https://example.com/video.m3u8',
67
+ advertising: {
68
+ client: 'dai', // Works on both platforms
69
+ imaDaiSettings: { // Preferred naming
70
+ videoId: 'tears-of-steel', // camelCase
71
+ cmsId: '2528370', // camelCase
72
+ streamType: 'hls'
73
+ },
74
+ imaSdkSettings: { // Preferred naming
75
+ language: 'en'
76
+ }
77
+ }
78
+ };
79
+ ```
80
+
81
+ **iOS-Specific Naming (also supported):**
82
+
83
+ ```typescript
84
+ // iOS can also use these alternate names
85
+ const iosConfig = {
86
+ advertising: {
87
+ client: 'GoogleIMADAI', // iOS naming
88
+ googimadai: { // iOS naming
89
+ videoID: '...', // Uppercase ID
90
+ cmsID: '...' // Uppercase ID
91
+ },
92
+ imaSettings: { // iOS uses "imaSettings"
93
+ locale: 'en'
94
+ }
95
+ }
96
+ };
97
+ ```
98
+
99
+ ### Ad Client Values
100
+
101
+ | Ad Type | iOS Values | Android Values | **Recommended** |
102
+ |---------|-----------|----------------|-----------------|
103
+ | VAST | `'vast'`, `'VAST'` | `'vast'`, `'VAST'` | `'vast'` ✅ |
104
+ | Google IMA | `'googima'` | `'googima'`, `'IMA'`, `'GOOGIMA'` | `'googima'` ✅ |
105
+ | Google DAI | `'dai'`, `'GoogleIMADAI'` | `'IMA_DAI'` | `'dai'` ✅ |
106
+
107
+ **Example:**
108
+
109
+ ```typescript
110
+ // ✅ Cross-platform
111
+ advertising: { client: 'dai' }
112
+
113
+ // ❌ Platform-specific
114
+ advertising: { client: 'GoogleIMADAI' } // iOS only
115
+ advertising: { client: 'IMA_DAI' } // Android only
116
+ ```
117
+
118
+ ### Playlist Item Fields
119
+
120
+ | Field | iOS | Android | **Recommended** |
121
+ |-------|-----|---------|-----------------|
122
+ | Media ID | `mediaid` | `mediaid` | `mediaId` ✅ |
123
+ | Ad Schedule | `adschedule` | `adschedule` | `adSchedule` ✅ |
124
+ | Feed ID | `feedid` | `feedid` | `feedId` ✅ |
125
+ | DAI Settings | `daiSetting` | `imaDaiSettings` | `imaDaiSettings` ✅ |
126
+ | Start Time | `starttime` | `starttime` | `startTime` ✅ |
127
+
128
+ ---
129
+
130
+ ## iOS-Specific Features
131
+
132
+ ### 1. Styling Configuration
133
+
134
+ **iOS Only** - Android uses XML styling
135
+
136
+ ```typescript
137
+ const config: JWPlayerConfig = {
138
+ license: 'YOUR_LICENSE_KEY',
139
+ file: 'https://example.com/video.m3u8',
140
+ styling: { // ⚠️ iOS ONLY
141
+ colors: {
142
+ buttons: '#FF0000',
143
+ backgroundColor: '#000000',
144
+ fontColor: '#FFFFFF',
145
+ timeslider: {
146
+ thumb: '#FF0000',
147
+ rail: '#808080',
148
+ slider: '#FF0000'
149
+ }
150
+ },
151
+ font: {
152
+ name: 'Helvetica',
153
+ size: 14
154
+ },
155
+ showTitle: true,
156
+ showDesc: true
157
+ }
158
+ };
159
+ ```
160
+
161
+ **Android Alternative:**
162
+
163
+ Use XML styling instead. See [Android Styling Guide](https://docs.jwplayer.com/players/docs/android-styling-guide).
164
+
165
+ ### 2. Audio Session Configuration
166
+
167
+ **iOS Only** - Controls background audio behavior
168
+
169
+ ```typescript
170
+ const config: JWPlayerConfig = {
171
+ license: 'YOUR_LICENSE_KEY',
172
+ file: 'https://example.com/video.m3u8',
173
+ backgroundAudioEnabled: true, // ⚠️ iOS ONLY
174
+ category: 'Playback', // ⚠️ iOS ONLY
175
+ categoryOptions: [ // ⚠️ iOS ONLY
176
+ 'MixWithOthers',
177
+ 'DuckOthers'
178
+ ],
179
+ mode: 'MoviePlayback' // ⚠️ iOS ONLY
180
+ };
181
+ ```
182
+
183
+ **Audio Session Categories:**
184
+ - `Ambient`: Mix with other audio, silence when locked
185
+ - `SoloAmbient`: Default, silences other audio
186
+ - `Playback`: For media playback
187
+ - `Record`: For recording
188
+ - `PlayAndRecord`: For VoIP
189
+ - `MultiRoute`: Multiple audio routes
190
+
191
+ **Category Options:**
192
+ - `MixWithOthers`: Mix with other audio
193
+ - `DuckOthers`: Lower volume of other audio
194
+ - `AllowBluetooth`: Allow Bluetooth A2DP
195
+ - `DefaultToSpeaker`: Route to speaker by default
196
+ - `InterruptSpokenAudioAndMix`: Interrupt spoken audio
197
+ - `AllowAirPlay`: Allow AirPlay
198
+
199
+ ### 3. Caption Styling
200
+
201
+ **iOS Only** - Customize caption appearance
202
+
203
+ ```typescript
204
+ const config: JWPlayerConfig = {
205
+ license: 'YOUR_LICENSE_KEY',
206
+ file: 'https://example.com/video.m3u8',
207
+ styling: { // ⚠️ iOS ONLY
208
+ captionsStyle: {
209
+ fontColor: '#FFFF00',
210
+ fontSize: 16,
211
+ backgroundColor: '#000000',
212
+ backgroundOpacity: 75,
213
+ windowColor: '#000000',
214
+ windowOpacity: 0,
215
+ edgeStyle: 'dropshadow', // 'none' | 'dropshadow' | 'raised' | 'depressed' | 'uniform'
216
+ fontFamily: 'Helvetica'
217
+ }
218
+ }
219
+ };
220
+ ```
221
+
222
+ **Android:** Uses system accessibility settings for captions.
223
+
224
+ ### 4. Interface Control
225
+
226
+ **iOS Only** - Control UI behavior
227
+
228
+ ```typescript
229
+ const config: JWPlayerConfig = {
230
+ license: 'YOUR_LICENSE_KEY',
231
+ file: 'https://example.com/video.m3u8',
232
+ interfaceBehavior: 'normal', // ⚠️ iOS ONLY: 'normal' | 'hidden' | 'onscreen'
233
+ interfaceFadeDelay: 3, // ⚠️ iOS ONLY: Seconds before UI fades
234
+ hideUIGroups: [ // ⚠️ iOS ONLY
235
+ 'settings_menu',
236
+ 'casting_menu',
237
+ 'quality_submenu'
238
+ ]
239
+ };
240
+ ```
241
+
242
+ ### 5. FairPlay DRM
243
+
244
+ **iOS Only** - FairPlay DRM
245
+
246
+ ```typescript
247
+ const config: JWPlayerConfig = {
248
+ license: 'YOUR_LICENSE_KEY',
249
+ sources: [{
250
+ file: 'https://example.com/video.m3u8',
251
+ drm: {
252
+ fairplay: { // ⚠️ iOS ONLY
253
+ processSpcUrl: 'https://drm-server.com/spc',
254
+ certificateUrl: 'https://drm-server.com/cert'
255
+ }
256
+ }
257
+ }],
258
+ // Global FairPlay settings (iOS only)
259
+ processSpcUrl: 'https://drm-server.com/spc',
260
+ fairplayCertUrl: 'https://drm-server.com/cert',
261
+ contentUUID: 'unique-content-id'
262
+ };
263
+ ```
264
+
265
+ ### 6. External Playback (AirPlay)
266
+
267
+ **iOS Only**
268
+
269
+ ```typescript
270
+ const config: JWPlayerConfig = {
271
+ license: 'YOUR_LICENSE_KEY',
272
+ file: 'https://example.com/video.m3u8',
273
+ externalPlaybackSettings: { // ⚠️ iOS ONLY
274
+ playbackEnabled: true,
275
+ usesExternalPlaybackWhileExternalScreenIsActive: true,
276
+ videoGravity: 'resizeAspect'
277
+ }
278
+ };
279
+ ```
280
+
281
+ ---
282
+
283
+ ## Android-Specific Features
284
+
285
+ ### 1. UI Configuration
286
+
287
+ **Android Only** - Granular UI control
288
+
289
+ ```typescript
290
+ const config: JWPlayerConfig = {
291
+ license: 'YOUR_LICENSE_KEY',
292
+ file: 'https://example.com/video.m3u8',
293
+ uiConfig: { // ⚠️ ANDROID ONLY
294
+ hasOverlay: true,
295
+ hasControlbar: true,
296
+ hasCenterControls: true,
297
+ hasNextUp: true,
298
+ hasQualitySubMenu: true,
299
+ hasCaptionsSubMenu: true,
300
+ hasPlaybackRatesSubMenu: true,
301
+ hasMenu: true,
302
+ hasAds: true
303
+ }
304
+ };
305
+ ```
306
+
307
+ **⚠️ Important:** When using `uiConfig`, ALL unspecified elements default to `false`. You must explicitly enable each element you want visible.
308
+
309
+ **iOS Alternative:** Use `hideUIGroups` or `interfaceBehavior`.
310
+
311
+ ### 2. TextureView
312
+
313
+ **Android Only**
314
+
315
+ ```typescript
316
+ const config: JWPlayerConfig = {
317
+ license: 'YOUR_LICENSE_KEY',
318
+ file: 'https://example.com/video.m3u8',
319
+ useTextureView: true // ⚠️ ANDROID ONLY
320
+ };
321
+ ```
322
+
323
+ **Use Case:** Required for applying transformations (rotation, scaling) to the video view.
324
+
325
+ ### 3. Ad Rules
326
+
327
+ **Android Primary** (iOS has limited support)
328
+
329
+ ```typescript
330
+ const config: JWPlayerConfig = {
331
+ license: 'YOUR_LICENSE_KEY',
332
+ playlist: [...],
333
+ advertising: {
334
+ client: 'vast',
335
+ schedule: [...],
336
+ rules: {
337
+ startOn: 2, // ✅ Both platforms
338
+ frequency: 2, // ✅ Both platforms
339
+ timeBetweenAds: 300, // ⚠️ ANDROID ONLY
340
+ startOnSeek: 'pre' // ⚠️ ANDROID ONLY
341
+ }
342
+ }
343
+ };
344
+ ```
345
+
346
+ **Platform Support:**
347
+ - `startOn`: ✅ iOS, ✅ Android
348
+ - `frequency`: ✅ iOS, ✅ Android
349
+ - `timeBetweenAds`: ❌ iOS, ✅ Android
350
+ - `startOnSeek`: ❌ iOS, ✅ Android
351
+
352
+ ### 4. Widevine DRM
353
+
354
+ **Android Only** - Widevine DRM
355
+
356
+ ```typescript
357
+ const config: JWPlayerConfig = {
358
+ license: 'YOUR_LICENSE_KEY',
359
+ sources: [{
360
+ file: 'https://example.com/video.mpd',
361
+ drm: {
362
+ widevine: { // ⚠️ ANDROID ONLY
363
+ url: 'https://license-server.com/license',
364
+ keySetId: 'optional-key-id'
365
+ }
366
+ }
367
+ }]
368
+ };
369
+ ```
370
+
371
+ ### 5. HTTP Headers
372
+
373
+ **Android Only**
374
+
375
+ ```typescript
376
+ const playlistItem: JWPlaylistItem = {
377
+ file: 'https://example.com/video.m3u8',
378
+ httpheaders: { // ⚠️ ANDROID ONLY
379
+ 'Authorization': 'Bearer token',
380
+ 'Custom-Header': 'value'
381
+ }
382
+ };
383
+ ```
384
+
385
+ ### 6. Cross-Protocol Redirects
386
+
387
+ **Android Only**
388
+
389
+ ```typescript
390
+ const config: JWPlayerConfig = {
391
+ license: 'YOUR_LICENSE_KEY',
392
+ file: 'https://example.com/video.m3u8',
393
+ allowCrossProtocolRedirectsSupport: true // ⚠️ ANDROID ONLY
394
+ };
395
+ ```
396
+
397
+ ### 7. Display Title/Description
398
+
399
+ **Android Only** (iOS always shows based on `showTitle`/`showDesc` in styling)
400
+
401
+ ```typescript
402
+ const config: JWPlayerConfig = {
403
+ license: 'YOUR_LICENSE_KEY',
404
+ file: 'https://example.com/video.m3u8',
405
+ displaytitle: true, // ⚠️ ANDROID ONLY
406
+ displaydescription: true // ⚠️ ANDROID ONLY
407
+ };
408
+ ```
409
+
410
+ ---
411
+
412
+ ## Cross-Platform Best Practices
413
+
414
+ ### 1. Use Conditional Configuration
415
+
416
+ ```typescript
417
+ import { Platform } from 'react-native';
418
+
419
+ const config: JWPlayerConfig = {
420
+ license: Platform.OS === 'ios' ? IOS_LICENSE : ANDROID_LICENSE,
421
+ file: 'https://example.com/video.m3u8',
422
+ autostart: true,
423
+
424
+ // iOS-specific features
425
+ ...(Platform.OS === 'ios' && {
426
+ styling: {
427
+ colors: { buttons: '#FF0000' }
428
+ },
429
+ backgroundAudioEnabled: true
430
+ }),
431
+
432
+ // Android-specific features
433
+ ...(Platform.OS === 'android' && {
434
+ uiConfig: {
435
+ hasControlbar: true,
436
+ hasOverlay: true
437
+ },
438
+ useTextureView: true
439
+ })
440
+ };
441
+ ```
442
+
443
+ ### 2. Unified Naming Convention
444
+
445
+ Always use the **recommended** cross-platform naming:
446
+
447
+ ```typescript
448
+ // ✅ GOOD - Cross-platform
449
+ const config: JWPlayerConfig = {
450
+ advertising: {
451
+ client: 'dai',
452
+ imaDaiSettings: {
453
+ videoId: 'tears-of-steel',
454
+ cmsId: '2528370'
455
+ },
456
+ imaSdkSettings: {
457
+ language: 'en'
458
+ }
459
+ }
460
+ };
461
+
462
+ // ❌ AVOID - Platform-specific naming
463
+ const config: JWPlayerConfig = {
464
+ advertising: {
465
+ client: 'GoogleIMADAI', // iOS-specific
466
+ googimadai: { // iOS-specific
467
+ videoID: '...', // Uppercase (iOS)
468
+ cmsID: '...' // Uppercase (iOS)
469
+ }
470
+ }
471
+ };
472
+ ```
473
+
474
+ ### 3. Handle DRM Properly
475
+
476
+ ```typescript
477
+ import { Platform } from 'react-native';
478
+
479
+ const getDrmConfig = () => {
480
+ if (Platform.OS === 'ios') {
481
+ return {
482
+ fairplay: {
483
+ processSpcUrl: 'https://drm.example.com/fps',
484
+ certificateUrl: 'https://drm.example.com/cert'
485
+ }
486
+ };
487
+ } else {
488
+ return {
489
+ widevine: {
490
+ url: 'https://drm.example.com/widevine'
491
+ }
492
+ };
493
+ }
494
+ };
495
+
496
+ const config: JWPlayerConfig = {
497
+ license: Platform.OS === 'ios' ? IOS_LICENSE : ANDROID_LICENSE,
498
+ sources: [{
499
+ file: Platform.OS === 'ios'
500
+ ? 'https://example.com/fairplay.m3u8'
501
+ : 'https://example.com/widevine.mpd',
502
+ label: '1080p',
503
+ drm: getDrmConfig()
504
+ }]
505
+ };
506
+ ```
507
+
508
+ ### 4. Test on Both Platforms
509
+
510
+ Always test configurations on both iOS and Android devices:
511
+
512
+ ```typescript
513
+ // Helper function for testing
514
+ export const validateConfig = (config: JWPlayerConfig): string[] => {
515
+ const warnings: string[] = [];
516
+
517
+ if (Platform.OS === 'android' && config.styling) {
518
+ warnings.push('`styling` is iOS-only. Use XML styling on Android.');
519
+ }
520
+
521
+ if (Platform.OS === 'ios' && config.uiConfig) {
522
+ warnings.push('`uiConfig` is Android-only. iOS uses native UI.');
523
+ }
524
+
525
+ if (Platform.OS === 'ios' && config.useTextureView) {
526
+ warnings.push('`useTextureView` is Android-only.');
527
+ }
528
+
529
+ return warnings;
530
+ };
531
+ ```
532
+
533
+ ---
534
+
535
+ ## Common Gotchas
536
+
537
+ ### 1. IMA DAI Naming Confusion
538
+
539
+ ❌ **Wrong:**
540
+ ```typescript
541
+ // Mixing iOS and Android naming
542
+ advertising: {
543
+ client: 'GoogleIMADAI', // iOS naming
544
+ imaDaiSettings: { // Android naming
545
+ videoID: '...', // iOS casing
546
+ cmsId: '...' // Android casing
547
+ }
548
+ }
549
+ ```
550
+
551
+ ✅ **Correct:**
552
+ ```typescript
553
+ advertising: {
554
+ client: 'dai', // Cross-platform
555
+ imaDaiSettings: { // Preferred
556
+ videoId: '...', // camelCase
557
+ cmsId: '...' // camelCase
558
+ }
559
+ }
560
+ ```
561
+
562
+ ### 2. UI Configuration Defaults
563
+
564
+ ❌ **Wrong (Android):**
565
+ ```typescript
566
+ // Only specifying some UI elements
567
+ uiConfig: {
568
+ hasControlbar: true
569
+ // Oops! All other elements are now hidden
570
+ }
571
+ ```
572
+
573
+ ✅ **Correct (Android):**
574
+ ```typescript
575
+ // Specify ALL elements you want visible
576
+ uiConfig: {
577
+ hasOverlay: true,
578
+ hasControlbar: true,
579
+ hasCenterControls: true,
580
+ hasNextUp: true,
581
+ hasQualitySubMenu: true,
582
+ hasCaptionsSubMenu: true,
583
+ hasMenu: true,
584
+ hasAds: true
585
+ }
586
+ ```
587
+
588
+ ### 3. License Keys
589
+
590
+ ❌ **Wrong:**
591
+ ```typescript
592
+ // Using same license for both platforms
593
+ const config = {
594
+ license: 'SINGLE_LICENSE_KEY' // Won't work!
595
+ };
596
+ ```
597
+
598
+ ✅ **Correct:**
599
+ ```typescript
600
+ import { Platform } from 'react-native';
601
+
602
+ const config = {
603
+ license: Platform.OS === 'ios'
604
+ ? process.env.IOS_LICENSE_KEY
605
+ : process.env.ANDROID_LICENSE_KEY
606
+ };
607
+ ```
608
+
609
+ ### 4. Styling vs UI Config
610
+
611
+ ❌ **Wrong:**
612
+ ```typescript
613
+ // Trying to use both
614
+ const config = {
615
+ styling: { ... }, // iOS
616
+ uiConfig: { ... } // Android
617
+ // Will be ignored on wrong platform
618
+ };
619
+ ```
620
+
621
+ ✅ **Correct:**
622
+ ```typescript
623
+ const config = {
624
+ ...(Platform.OS === 'ios' && {
625
+ styling: { ... }
626
+ }),
627
+ ...(Platform.OS === 'android' && {
628
+ uiConfig: { ... }
629
+ })
630
+ };
631
+ ```
632
+
633
+ ### 5. Ad Rules Assumptions
634
+
635
+ ❌ **Wrong:**
636
+ ```typescript
637
+ // Assuming full ad rules support on iOS
638
+ advertising: {
639
+ client: 'vast',
640
+ rules: {
641
+ startOn: 2,
642
+ timeBetweenAds: 300 // iOS doesn't support this!
643
+ }
644
+ }
645
+ ```
646
+
647
+ ✅ **Correct:**
648
+ ```typescript
649
+ advertising: {
650
+ client: 'vast',
651
+ rules: {
652
+ startOn: 2,
653
+ frequency: 2,
654
+ ...(Platform.OS === 'android' && {
655
+ timeBetweenAds: 300,
656
+ startOnSeek: 'pre'
657
+ })
658
+ }
659
+ }
660
+ ```
661
+
662
+ ---
663
+
664
+ ## Summary Table
665
+
666
+ | Feature | iOS | Android | Recommendation |
667
+ |---------|-----|---------|----------------|
668
+ | **Styling** | ✅ Full | ❌ Use XML | Platform-specific |
669
+ | **UI Config** | ❌ Use hideUIGroups | ✅ Full | Platform-specific |
670
+ | **Background Audio** | ✅ Full | ❌ | iOS only |
671
+ | **Caption Styling** | ✅ Full | ❌ System settings | iOS only |
672
+ | **FairPlay DRM** | ✅ | ❌ | iOS only |
673
+ | **Widevine DRM** | ❌ | ✅ | Android only |
674
+ | **Ad Rules (full)** | ⚠️ Limited | ✅ Full | Platform-aware |
675
+ | **HTTP Headers** | ❌ | ✅ | Android only |
676
+ | **TextureView** | ❌ | ✅ | Android only |
677
+ | **AirPlay** | ✅ | ❌ | iOS only |
678
+ | **IMA DAI** | ✅ | ✅ | Use `imaDaiSettings` |
679
+ | **VAST/IMA** | ✅ | ✅ | Fully cross-platform |
680
+
681
+ ---
682
+
683
+ ## See Also
684
+
685
+ - [Configuration Reference](./CONFIG-REFERENCE.md) - Complete config documentation
686
+ - [Migration Guide](./MIGRATION-GUIDE.md) - Upgrading from legacy configs
687
+ - [TypeScript Example](../Example/app/jsx/screens/TypeScriptExample.tsx) - Example with platform-specific configurations
688
+
689
+ ---
690
+
691
+ *Last Updated: October 2025*
692
+ *SDK Version: JWPlayer React Native*
693
+
package/docs/props.md CHANGED
@@ -2,17 +2,29 @@
2
2
 
3
3
  This wrapper implements the native methods exposed by the [Android](https://sdk.jwplayer.com/android/v4/reference/com/jwplayer/pub/api/JsonHelper.html) and [iOS](https://sdk.jwplayer.com/ios/v4/reference/Classes/JWJSONParser.html) SDK for parsing JSON objects into player configs.
4
4
 
5
+ ## Component Props
6
+
5
7
  | Prop | Type | Platform | Description | Default |
6
8
  | --- | --- | --- | --- | --- |
7
- | `config` | object | A, I | **(REQUIRED)** `JWConfig` object<br />See: [Config](#config) | `undefined` |
9
+ | `config` | object | A, I | **(REQUIRED)** `JWPlayerConfig` or `Config` object<br />See: [Configuration Reference](./CONFIG-REFERENCE.md) | `undefined` |
8
10
  | `controls` | boolean | A, I | Determines if player controls are displayed | `true` |
9
11
 
10
12
  <br /><br />
11
13
 
14
+ ## Configuration Documentation
15
+
16
+ 📚 **Complete documentation is now available in separate guides:**
17
+
18
+ - **[Configuration Reference](./CONFIG-REFERENCE.md)** - Complete field reference with examples
19
+ - **[Platform Differences](./PLATFORM-DIFFERENCES.md)** - iOS vs Android feature comparison
20
+ - **[Migration Guide](./MIGRATION-GUIDE.md)** - Upgrading to unified types
21
+
22
+ <br />
23
+
12
24
  ## Config
13
- With the exception of `license` and `playlist`, all other fields are optional.
25
+ With the exception of `license` and one of (`file`, `sources`, or `playlist`), all other fields are optional.
14
26
 
15
- See [`types`](./types.md) for a definition of config types defined below
27
+ See the [Configuration Reference](./CONFIG-REFERENCE.md) for complete documentation of all configuration options.
16
28
 
17
29
  | Field | Type | Platform | Additional Notes |
18
30
  | --- | --- | --- | --- |