@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,747 @@
1
+ # JWPlayer React Native Configuration Reference
2
+
3
+ Complete reference for the unified configuration system supporting both iOS and Android platforms.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Quick Start](#quick-start)
9
+ - [Core Configuration](#core-configuration)
10
+ - [Media Content](#media-content)
11
+ - [Playback Settings](#playback-settings)
12
+ - [Advertising](#advertising)
13
+ - [Related Content](#related-content)
14
+ - [Platform-Specific Features](#platform-specific-features)
15
+ - [iOS Only](#ios-only-features)
16
+ - [Android Only](#android-only-features)
17
+ - [Advertising Configuration](#advertising-configuration-detailed)
18
+ - [Playlist Items](#playlist-items)
19
+ - [Complete Examples](#complete-examples)
20
+
21
+ ---
22
+
23
+ ## Overview
24
+
25
+ The JWPlayer React Native wrapper uses a unified configuration system that works across both iOS (`JWJSONParser`) and Android (`JsonHelper`) platforms. The configuration is passed as a JavaScript object and automatically parsed by the native SDK.
26
+
27
+ ### Key Features
28
+
29
+ - ✅ **Single Configuration Object**: One config works on both platforms
30
+ - ✅ **Type Safety**: Full TypeScript support with autocomplete
31
+ - ✅ **Platform Annotations**: Clear documentation of platform-specific features
32
+ - ✅ **Backward Compatible**: Existing configs continue to work
33
+ - ✅ **Flexible Naming**: Supports multiple naming conventions where needed
34
+
35
+ ### Import Types
36
+
37
+ ```typescript
38
+ import { JWPlayerConfig } from '@jwplayer/jwplayer-react-native';
39
+ // Or import from types directory
40
+ import type { JWPlayerConfig } from '@jwplayer/jwplayer-react-native/types';
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Quick Start
46
+
47
+ ### Minimal Configuration
48
+
49
+ ```typescript
50
+ import JWPlayer from '@jwplayer/jwplayer-react-native';
51
+
52
+ const config: JWPlayerConfig = {
53
+ license: 'YOUR_LICENSE_KEY', // Required
54
+ file: 'https://example.com/video.m3u8'
55
+ };
56
+
57
+ <JWPlayer config={config} />
58
+ ```
59
+
60
+ ### With Autostart and Poster
61
+
62
+ ```typescript
63
+ const config: JWPlayerConfig = {
64
+ license: 'YOUR_LICENSE_KEY',
65
+ file: 'https://example.com/video.m3u8',
66
+ image: 'https://example.com/poster.jpg',
67
+ autostart: true,
68
+ mute: false
69
+ };
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Core Configuration
75
+
76
+ ### Media Content
77
+
78
+ #### Single File
79
+
80
+ Use `file` for a single video:
81
+
82
+ ```typescript
83
+ const config: JWPlayerConfig = {
84
+ license: 'YOUR_LICENSE_KEY',
85
+ file: 'https://example.com/video.m3u8',
86
+ title: 'My Video',
87
+ description: 'Video description',
88
+ image: 'https://example.com/poster.jpg'
89
+ };
90
+ ```
91
+
92
+ **Supported Fields:**
93
+ - `file` (string): URL of the media file
94
+ - `title` (string): Video title
95
+ - `description` (string): Video description
96
+ - `image` (string): Poster image URL
97
+ - `tracks` (JWTrack[]): Caption/thumbnail tracks
98
+
99
+ #### Multiple Quality Sources
100
+
101
+ Use `sources` for multiple quality levels:
102
+
103
+ ```typescript
104
+ const config: JWPlayerConfig = {
105
+ license: 'YOUR_LICENSE_KEY',
106
+ sources: [
107
+ {
108
+ file: 'https://example.com/video-1080p.mp4',
109
+ label: '1080p',
110
+ default: true
111
+ },
112
+ {
113
+ file: 'https://example.com/video-720p.mp4',
114
+ label: '720p'
115
+ },
116
+ {
117
+ file: 'https://example.com/video-480p.mp4',
118
+ label: '480p'
119
+ }
120
+ ]
121
+ };
122
+ ```
123
+
124
+ **JWSource Fields:**
125
+ - `file` (string): Source URL - **Required**
126
+ - `label` (string): Quality label (e.g., "1080p")
127
+ - `default` (boolean): Whether this is the default quality
128
+ - `type` (string): Media type (e.g., "mp4", "hls")
129
+ - `drm` (JWDrm): DRM configuration
130
+
131
+ #### Playlist
132
+
133
+ Use `playlist` for multiple videos:
134
+
135
+ ```typescript
136
+ const config: JWPlayerConfig = {
137
+ license: 'YOUR_LICENSE_KEY',
138
+ playlist: [
139
+ {
140
+ file: 'https://example.com/video1.m3u8',
141
+ title: 'Video 1',
142
+ image: 'https://example.com/poster1.jpg'
143
+ },
144
+ {
145
+ file: 'https://example.com/video2.m3u8',
146
+ title: 'Video 2',
147
+ image: 'https://example.com/poster2.jpg'
148
+ }
149
+ ],
150
+ autostart: true
151
+ };
152
+ ```
153
+
154
+ **Or load from a remote playlist:**
155
+
156
+ ```typescript
157
+ const config: JWPlayerConfig = {
158
+ license: 'YOUR_LICENSE_KEY',
159
+ playlist: 'https://cdn.jwplayer.com/v2/media/MEDIAID?format=json',
160
+ autostart: true
161
+ };
162
+ ```
163
+
164
+ **Platform Support:** iOS, Android
165
+ **Mutually Exclusive:** Can only use ONE of: `file`, `sources`, or `playlist`
166
+
167
+ ---
168
+
169
+ ### Playback Settings
170
+
171
+ #### Basic Playback
172
+
173
+ ```typescript
174
+ const config: JWPlayerConfig = {
175
+ license: 'YOUR_LICENSE_KEY',
176
+ file: 'https://example.com/video.m3u8',
177
+
178
+ autostart: true, // Auto-play on load
179
+ mute: false, // Initial mute state
180
+ repeat: false, // Loop content
181
+ preload: 'auto', // Preload behavior: 'auto' | 'none'
182
+ stretching: 'uniform', // Video scaling: 'uniform' | 'fill' | 'exactfit' | 'none'
183
+ playlistIndex: 0, // Start playlist at index (0-based)
184
+
185
+ // Playback speed controls
186
+ playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2],
187
+ playbackRateControls: true,
188
+
189
+ // Bandwidth limit (bits per second)
190
+ bitrateUpperBound: 2000000
191
+ };
192
+ ```
193
+
194
+ **Field Reference:**
195
+
196
+ | Field | Type | Default | Description | Platforms |
197
+ |-------|------|---------|-------------|-----------|
198
+ | `autostart` | boolean | false | Auto-play on load | iOS, Android |
199
+ | `mute` | boolean | false | Mute audio initially | iOS, Android |
200
+ | `repeat` | boolean | false | Loop content | iOS, Android |
201
+ | `preload` | 'auto' \| 'none' | 'auto' | Preload behavior | iOS, Android |
202
+ | `stretching` | Stretching | 'uniform' | Video scaling mode | iOS, Android |
203
+ | `playlistIndex` | number | 0 | Starting playlist index | iOS, Android |
204
+ | `playbackRates` | number[] | - | Available speed rates (0.25-4.0) | iOS, Android |
205
+ | `playbackRateControls` | boolean | false | Show speed controls | iOS, Android |
206
+ | `bitrateUpperBound` | number | - | Max bitrate (bps) | iOS, Android |
207
+ | `pid` / `playerId` | string | - | Player ID for analytics (8 chars) | iOS, Android |
208
+
209
+ ---
210
+
211
+ ### Advertising
212
+
213
+ See [Advertising Configuration (Detailed)](#advertising-configuration-detailed) section below for complete advertising documentation.
214
+
215
+ **Quick Example - IMA DAI VOD:**
216
+
217
+ ```typescript
218
+ const config: JWPlayerConfig = {
219
+ license: 'YOUR_LICENSE_KEY',
220
+ file: 'https://example.com/video.m3u8',
221
+ advertising: {
222
+ client: 'dai',
223
+ imaDaiSettings: {
224
+ videoId: 'tears-of-steel',
225
+ cmsId: '2528370',
226
+ streamType: 'hls'
227
+ }
228
+ }
229
+ };
230
+ ```
231
+
232
+ ---
233
+
234
+ ### Related Content
235
+
236
+ Configure the related content overlay that appears after playback:
237
+
238
+ ```typescript
239
+ const config: JWPlayerConfig = {
240
+ license: 'YOUR_LICENSE_KEY',
241
+ file: 'https://example.com/video.m3u8',
242
+ related: {
243
+ file: 'https://example.com/related.json', // Related feed URL
244
+ onclick: 'play', // 'play' | 'link'
245
+ oncomplete: 'show', // 'show' | 'hide' | 'autoplay'
246
+ autoplaytimer: 10 // Countdown seconds
247
+ }
248
+ };
249
+ ```
250
+
251
+ **Platform Notes:**
252
+ - iOS: Full support with additional options (`heading`, `autoplayMessage`)
253
+ - Android: Basic support with `file`, `onclick`, `oncomplete`, `autoplaytimer`
254
+
255
+ ---
256
+
257
+ ## Platform-Specific Features
258
+
259
+ ### iOS Only Features
260
+
261
+ #### Styling
262
+
263
+ Customize colors, fonts, and UI appearance (iOS only):
264
+
265
+ ```typescript
266
+ const config: JWPlayerConfig = {
267
+ license: 'YOUR_LICENSE_KEY',
268
+ file: 'https://example.com/video.m3u8',
269
+ styling: {
270
+ colors: {
271
+ buttons: '#FF0000',
272
+ backgroundColor: '#000000',
273
+ fontColor: '#FFFFFF',
274
+ timeslider: {
275
+ thumb: '#FF0000',
276
+ rail: '#808080',
277
+ slider: '#FF0000'
278
+ }
279
+ },
280
+ font: {
281
+ name: 'Helvetica',
282
+ size: 14
283
+ },
284
+ showTitle: true,
285
+ showDesc: true,
286
+ captionsStyle: {
287
+ fontColor: '#FFFF00',
288
+ fontSize: 16,
289
+ backgroundColor: '#000000',
290
+ backgroundOpacity: 75,
291
+ edgeStyle: 'dropshadow'
292
+ }
293
+ }
294
+ };
295
+ ```
296
+
297
+ **⚠️ Android:** Use XML styling instead. See [Android Styling Guide](https://docs.jwplayer.com/players/docs/android-styling-guide)
298
+
299
+ #### Background Audio
300
+
301
+ ```typescript
302
+ const config: JWPlayerConfig = {
303
+ license: 'YOUR_LICENSE_KEY',
304
+ file: 'https://example.com/video.m3u8',
305
+ backgroundAudioEnabled: true,
306
+ category: 'Playback',
307
+ categoryOptions: ['MixWithOthers', 'DuckOthers'],
308
+ mode: 'MoviePlayback'
309
+ };
310
+ ```
311
+
312
+ #### Interface Control
313
+
314
+ ```typescript
315
+ const config: JWPlayerConfig = {
316
+ license: 'YOUR_LICENSE_KEY',
317
+ file: 'https://example.com/video.m3u8',
318
+ interfaceBehavior: 'normal', // 'normal' | 'hidden' | 'onscreen'
319
+ interfaceFadeDelay: 3, // Seconds before UI fades
320
+ hideUIGroups: ['settings_menu', 'casting_menu']
321
+ };
322
+ ```
323
+
324
+ #### FairPlay DRM
325
+
326
+ ```typescript
327
+ const config: JWPlayerConfig = {
328
+ license: 'YOUR_LICENSE_KEY',
329
+ sources: [{
330
+ file: 'https://example.com/video.m3u8',
331
+ drm: {
332
+ fairplay: {
333
+ processSpcUrl: 'https://your-drm-server.com/process-spc',
334
+ certificateUrl: 'https://your-drm-server.com/certificate'
335
+ }
336
+ }
337
+ }]
338
+ };
339
+ ```
340
+
341
+ ---
342
+
343
+ ### Android Only Features
344
+
345
+ #### UI Configuration
346
+
347
+ Control which UI elements are visible (Android only):
348
+
349
+ ```typescript
350
+ const config: JWPlayerConfig = {
351
+ license: 'YOUR_LICENSE_KEY',
352
+ file: 'https://example.com/video.m3u8',
353
+ uiConfig: {
354
+ hasOverlay: true,
355
+ hasControlbar: true,
356
+ hasCenterControls: true,
357
+ hasNextUp: true,
358
+ hasQualitySubMenu: true,
359
+ hasCaptionsSubMenu: true,
360
+ hasPlaybackRatesSubMenu: true,
361
+ hasMenu: true,
362
+ hasAds: true
363
+ }
364
+ };
365
+ ```
366
+
367
+ **⚠️ Note:** When using `uiConfig`, all unspecified elements default to `false`. Specify all elements you want visible.
368
+
369
+ #### Android-Specific Settings
370
+
371
+ ```typescript
372
+ const config: JWPlayerConfig = {
373
+ license: 'YOUR_LICENSE_KEY',
374
+ file: 'https://example.com/video.m3u8',
375
+ useTextureView: true, // Use TextureView instead of SurfaceView
376
+ allowCrossProtocolRedirectsSupport: true, // Allow HTTP->HTTPS redirects
377
+ displaytitle: true,
378
+ displaydescription: true,
379
+ thumbnailPreview: 102 // Thumbnail preview quality (101-103)
380
+ };
381
+ ```
382
+
383
+ #### Widevine DRM
384
+
385
+ ```typescript
386
+ const config: JWPlayerConfig = {
387
+ license: 'YOUR_LICENSE_KEY',
388
+ sources: [{
389
+ file: 'https://example.com/video.mpd',
390
+ drm: {
391
+ widevine: {
392
+ url: 'https://your-drm-server.com/license',
393
+ keySetId: 'optional-key-set-id'
394
+ }
395
+ }
396
+ }]
397
+ };
398
+ ```
399
+
400
+ ---
401
+
402
+ ## Advertising Configuration (Detailed)
403
+
404
+ The wrapper supports multiple advertising systems across both platforms.
405
+
406
+ ### Supported Ad Types
407
+
408
+ | Ad Type | iOS | Android | Client Value |
409
+ |---------|-----|---------|--------------|
410
+ | VAST with Schedule | ✅ | ✅ | `'vast'` |
411
+ | VMAP | ✅ | ✅ | `'vast'` |
412
+ | Google IMA | ✅ | ✅ | `'googima'` or `'IMA'` |
413
+ | Google IMA DAI | ✅ | ✅ | `'dai'` or `'IMA_DAI'` or `'GoogleIMADAI'` |
414
+
415
+ ### IMA DAI Configuration
416
+
417
+ #### VOD Stream (Video on Demand)
418
+
419
+ Requires `videoId` + `cmsId`:
420
+
421
+ ```typescript
422
+ const config: JWPlayerConfig = {
423
+ license: 'YOUR_LICENSE_KEY',
424
+ file: 'https://example.com/video.m3u8',
425
+ advertising: {
426
+ client: 'dai',
427
+ imaDaiSettings: {
428
+ videoId: 'tears-of-steel',
429
+ cmsId: '2528370',
430
+ streamType: 'hls', // 'hls' or 'dash'
431
+ apiKey: 'your-api-key', // Optional
432
+ adTagParameters: {
433
+ 'custom_param': 'value'
434
+ }
435
+ },
436
+ imaSdkSettings: {
437
+ language: 'en',
438
+ autoPlayAdBreaks: true
439
+ },
440
+ skipoffset: 5 // Skip button after 5 seconds
441
+ }
442
+ };
443
+ ```
444
+
445
+ #### Live Stream
446
+
447
+ Requires `assetKey`:
448
+
449
+ ```typescript
450
+ const config: JWPlayerConfig = {
451
+ license: 'YOUR_LICENSE_KEY',
452
+ file: 'https://example.com/live.m3u8',
453
+ advertising: {
454
+ client: 'dai',
455
+ imaDaiSettings: {
456
+ assetKey: 'sN_IYUG8STe1ZzhIIE_ksA',
457
+ streamType: 'hls'
458
+ }
459
+ }
460
+ };
461
+ ```
462
+
463
+ **Platform Note:** Both iOS and Android support `imaDaiSettings`. iOS also accepts `googimadai` as an alias.
464
+
465
+ ### VAST Advertising
466
+
467
+ #### With Schedule
468
+
469
+ ```typescript
470
+ const config: JWPlayerConfig = {
471
+ license: 'YOUR_LICENSE_KEY',
472
+ file: 'https://example.com/video.m3u8',
473
+ advertising: {
474
+ client: 'vast',
475
+ schedule: [
476
+ {
477
+ offset: 'pre',
478
+ tag: 'https://example.com/preroll.xml'
479
+ },
480
+ {
481
+ offset: '50%', // Midroll at 50%
482
+ tag: 'https://example.com/midroll.xml',
483
+ skipoffset: 5
484
+ },
485
+ {
486
+ offset: 'post',
487
+ tag: 'https://example.com/postroll.xml'
488
+ }
489
+ ],
490
+ skipoffset: 5,
491
+ admessage: 'Ad - {remaining}',
492
+ skipmessage: 'Skip in {remaining}',
493
+ skiptext: 'Skip Ad'
494
+ }
495
+ };
496
+ ```
497
+
498
+ #### With VMAP
499
+
500
+ ```typescript
501
+ const config: JWPlayerConfig = {
502
+ license: 'YOUR_LICENSE_KEY',
503
+ file: 'https://example.com/video.m3u8',
504
+ advertising: {
505
+ client: 'vast',
506
+ tag: 'https://example.com/vmap.xml', // VMAP URL
507
+ skipoffset: 5
508
+ }
509
+ };
510
+ ```
511
+
512
+ ### Google IMA
513
+
514
+ ```typescript
515
+ const config: JWPlayerConfig = {
516
+ license: 'YOUR_LICENSE_KEY',
517
+ file: 'https://example.com/video.m3u8',
518
+ advertising: {
519
+ client: 'googima',
520
+ schedule: [
521
+ {
522
+ offset: 'pre',
523
+ tag: 'https://pubads.g.doubleclick.net/gampad/ads?...'
524
+ }
525
+ ],
526
+ imaSdkSettings: {
527
+ language: 'en',
528
+ autoPlayAdBreaks: true,
529
+ maxRedirects: 5,
530
+ isDebugMode: false
531
+ }
532
+ }
533
+ };
534
+ ```
535
+
536
+ ### Ad Rules (Android Primary)
537
+
538
+ Control ad playback across a playlist:
539
+
540
+ ```typescript
541
+ const config: JWPlayerConfig = {
542
+ license: 'YOUR_LICENSE_KEY',
543
+ playlist: [...],
544
+ advertising: {
545
+ client: 'vast',
546
+ schedule: [...],
547
+ rules: {
548
+ startOn: 2, // Start ads on 2nd playlist item
549
+ frequency: 2, // Show ads every 2 items
550
+ timeBetweenAds: 300, // Min 5 minutes between midrolls
551
+ startOnSeek: 'pre' // Show preroll after seeking
552
+ }
553
+ }
554
+ };
555
+ ```
556
+
557
+ **Platform Note:** Android has full support. iOS has limited support for `startOn` and `frequency`.
558
+
559
+ ---
560
+
561
+ ## Playlist Items
562
+
563
+ Complete configuration for playlist items:
564
+
565
+ ```typescript
566
+ const playlistItem: JWPlaylistItem = {
567
+ // Media source (Required: file OR sources)
568
+ file: 'https://example.com/video.m3u8',
569
+ // OR
570
+ sources: [
571
+ { file: 'https://example.com/1080p.mp4', label: '1080p' },
572
+ { file: 'https://example.com/720p.mp4', label: '720p' }
573
+ ],
574
+
575
+ // Metadata
576
+ title: 'Video Title',
577
+ description: 'Video description',
578
+ image: 'https://example.com/poster.jpg',
579
+ mediaId: 'unique-id',
580
+
581
+ // Playback
582
+ starttime: 0, // Start position in seconds
583
+ duration: 600, // Duration in seconds
584
+
585
+ // Tracks
586
+ tracks: [
587
+ {
588
+ file: 'https://example.com/captions-en.vtt',
589
+ kind: 'captions',
590
+ label: 'English',
591
+ locale: 'en',
592
+ default: true
593
+ }
594
+ ],
595
+
596
+ // Item-level advertising
597
+ imaDaiSettings: {
598
+ videoId: 'video-id',
599
+ cmsId: 'cms-id'
600
+ },
601
+
602
+ // Related content
603
+ recommendations: 'https://example.com/related.json',
604
+
605
+ // Chromecast
606
+ userInfo: {
607
+ customData: 'value'
608
+ },
609
+
610
+ // DRM (platform-specific)
611
+ drm: {
612
+ fairplay: { // iOS
613
+ processSpcUrl: '...',
614
+ certificateUrl: '...'
615
+ },
616
+ widevine: { // Android
617
+ url: '...',
618
+ keySetId: '...'
619
+ }
620
+ }
621
+ };
622
+ ```
623
+
624
+ ---
625
+
626
+ ## Complete Examples
627
+
628
+ ### Basic Video with Captions
629
+
630
+ ```typescript
631
+ import JWPlayer, { JWPlayerConfig } from '@jwplayer/jwplayer-react-native';
632
+
633
+ const config: JWPlayerConfig = {
634
+ license: 'YOUR_LICENSE_KEY',
635
+ file: 'https://example.com/video.m3u8',
636
+ title: 'Sample Video',
637
+ image: 'https://example.com/poster.jpg',
638
+ tracks: [
639
+ {
640
+ file: 'https://example.com/captions-en.vtt',
641
+ kind: 'captions',
642
+ label: 'English',
643
+ locale: 'en',
644
+ default: true
645
+ },
646
+ {
647
+ file: 'https://example.com/captions-es.vtt',
648
+ kind: 'captions',
649
+ label: 'Español',
650
+ locale: 'es'
651
+ }
652
+ ],
653
+ autostart: true
654
+ };
655
+
656
+ export default () => (
657
+ <JWPlayer config={config} style={{ flex: 1 }} />
658
+ );
659
+ ```
660
+
661
+ ### IMA DAI with Playlist
662
+
663
+ ```typescript
664
+ const config: JWPlayerConfig = {
665
+ license: 'YOUR_LICENSE_KEY',
666
+ autostart: true,
667
+ playlist: [
668
+ {
669
+ title: 'VOD with Ads',
670
+ file: 'https://example.com/vod.m3u8',
671
+ imaDaiSettings: {
672
+ videoId: 'tears-of-steel',
673
+ cmsId: '2528370'
674
+ }
675
+ },
676
+ {
677
+ title: 'Live Stream with Ads',
678
+ file: 'https://example.com/live.m3u8',
679
+ imaDaiSettings: {
680
+ assetKey: 'sN_IYUG8STe1ZzhIIE_ksA'
681
+ }
682
+ },
683
+ {
684
+ title: 'Video without Ads',
685
+ file: 'https://example.com/no-ads.m3u8'
686
+ }
687
+ ],
688
+ advertising: {
689
+ client: 'dai'
690
+ }
691
+ };
692
+ ```
693
+
694
+ ### Multi-Quality with DRM
695
+
696
+ ```typescript
697
+ import { Platform } from 'react-native';
698
+
699
+ const config: JWPlayerConfig = {
700
+ license: Platform.OS === 'ios' ? 'IOS_LICENSE' : 'ANDROID_LICENSE',
701
+ sources: [
702
+ {
703
+ file: Platform.OS === 'ios'
704
+ ? 'https://example.com/fairplay.m3u8'
705
+ : 'https://example.com/widevine.mpd',
706
+ label: '1080p',
707
+ default: true,
708
+ drm: Platform.OS === 'ios' ? {
709
+ fairplay: {
710
+ processSpcUrl: 'https://drm.example.com/spc',
711
+ certificateUrl: 'https://drm.example.com/cert'
712
+ }
713
+ } : {
714
+ widevine: {
715
+ url: 'https://drm.example.com/license'
716
+ }
717
+ }
718
+ }
719
+ ],
720
+ autostart: true
721
+ };
722
+ ```
723
+
724
+ ---
725
+
726
+ ## See Also
727
+
728
+ - [Platform Differences Guide](./PLATFORM-DIFFERENCES.md) - Detailed platform-specific information
729
+ - [Migration Guide](./MIGRATION-GUIDE.md) - Upgrading from legacy configs
730
+ - [Props Documentation](./props.md) - Component props reference
731
+ - [iOS JSON Parser Docs](../ios-json-parser/README.md) - iOS parser details
732
+ - [Android JSON Parser Docs](../android-json-parser/README.md) - Android parser details
733
+
734
+ ---
735
+
736
+ ## Need Help?
737
+
738
+ - **Configuration Issues**: Check [PLATFORM-DIFFERENCES.md](./PLATFORM-DIFFERENCES.md)
739
+ - **Migration Questions**: See [MIGRATION-GUIDE.md](./MIGRATION-GUIDE.md)
740
+ - **TypeScript Errors**: Import types from `'@jwplayer/jwplayer-react-native/types'`
741
+ - **Platform-Specific**: Review [iOS](../ios-json-parser/) or [Android](../android-json-parser/) parser docs
742
+
743
+ ---
744
+
745
+ *Last Updated: October 2025*
746
+ *SDK Version: JWPlayer React Native*
747
+