@jwplayer/jwplayer-react-native 1.0.1 → 1.0.3
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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +10 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +10 -0
- package/.github/ISSUE_TEMPLATE/implement.md +9 -0
- package/.github/ISSUE_TEMPLATE/question.md +10 -0
- package/README.md +2 -0
- package/RNJWPlayer.podspec +2 -2
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -2
- package/android/build.gradle +1 -1
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerModule.java +510 -458
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +384 -32
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +12 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +26 -7
- package/badges/version.svg +1 -1
- package/index.d.ts +41 -7
- package/index.js +22 -2
- package/ios/RNJWPlayer/RNJWPlayerView.swift +47 -34
- package/ios/RNJWPlayer/RNJWPlayerViewController.swift +15 -9
- package/ios/RNJWPlayer/RNJWPlayerViewManager.m +9 -1
- package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +49 -15
- package/jwplayer-jwplayer-react-native-1.0.3.tgz +0 -0
- package/package.json +3 -3
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/android/.gradle/8.1.1/checksums/checksums.lock +0 -0
- package/android/.gradle/8.1.1/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.1.1/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.1.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.4/checksums/checksums.lock +0 -0
- package/android/.gradle/8.4/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.4/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.4/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.4/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.4/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.4/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.4/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.4/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.4/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.4/gc.properties +0 -0
- package/android/.gradle/config.properties +0 -2
- package/android/.gradle/file-system.probe +0 -0
- package/android/.idea/compiler.xml +0 -6
- package/android/.idea/gradle.xml +0 -18
- package/android/.idea/migrations.xml +0 -10
- package/android/.idea/misc.xml +0 -10
- package/android/.idea/vcs.xml +0 -6
- package/android/local.properties +0 -8
- package/ios/RNJWPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/RNJWPlayer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/ios/RNJWPlayer.xcodeproj/project.xcworkspace/xcuserdata/jmilham.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/RNJWPlayer.xcodeproj/xcuserdata/jmilham.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- /package/android/.gradle/{8.1.1 → 8.9}/dependencies-accessors/gc.properties +0 -0
- /package/android/.gradle/{8.1.1 → 8.9}/fileChanges/last-build.bin +0 -0
- /package/android/.gradle/{8.1.1 → 8.9}/gc.properties +0 -0
|
@@ -155,10 +155,22 @@ public class RNJWPlayerViewManager extends SimpleViewManager<RNJWPlayerView> {
|
|
|
155
155
|
MapBuilder.of(
|
|
156
156
|
"phasedRegistrationNames",
|
|
157
157
|
MapBuilder.of("bubbled", "onAudioTracks")))
|
|
158
|
+
.put("topCaptionsChanged",
|
|
159
|
+
MapBuilder.of(
|
|
160
|
+
"phasedRegistrationNames",
|
|
161
|
+
MapBuilder.of("bubbled", "onCaptionsChanged")))
|
|
162
|
+
.put("topCaptionsList",
|
|
163
|
+
MapBuilder.of(
|
|
164
|
+
"phasedRegistrationNames",
|
|
165
|
+
MapBuilder.of("bubbled", "onCaptionsList")))
|
|
158
166
|
.put("topCasting",
|
|
159
167
|
MapBuilder.of(
|
|
160
168
|
"phasedRegistrationNames",
|
|
161
169
|
MapBuilder.of("bubbled", "onCasting")))
|
|
170
|
+
.put("topFirstFrame",
|
|
171
|
+
MapBuilder.of(
|
|
172
|
+
"phasedRegistrationNames",
|
|
173
|
+
MapBuilder.of("bubbled", "onLoaded")))
|
|
162
174
|
.build();
|
|
163
175
|
}
|
|
164
176
|
|
|
@@ -2,17 +2,21 @@ package com.jwplayer.rnjwplayer;
|
|
|
2
2
|
|
|
3
3
|
import static androidx.media3.common.util.Util.toByteArray;
|
|
4
4
|
|
|
5
|
+
import android.util.Log;
|
|
5
6
|
import android.util.Patterns;
|
|
6
7
|
import android.webkit.URLUtil;
|
|
7
8
|
|
|
8
9
|
import com.facebook.react.bridge.ReadableArray;
|
|
9
10
|
import com.facebook.react.bridge.ReadableMap;
|
|
11
|
+
import com.jwplayer.pub.api.JsonHelper;
|
|
10
12
|
import com.jwplayer.pub.api.media.ads.AdBreak;
|
|
11
13
|
import com.jwplayer.pub.api.media.captions.Caption;
|
|
12
14
|
import com.jwplayer.pub.api.media.captions.CaptionType;
|
|
13
15
|
import com.jwplayer.pub.api.media.playlists.MediaSource;
|
|
14
16
|
import com.jwplayer.pub.api.media.playlists.PlaylistItem;
|
|
15
17
|
|
|
18
|
+
import org.json.JSONObject;
|
|
19
|
+
|
|
16
20
|
import java.io.IOException;
|
|
17
21
|
import java.io.InputStream;
|
|
18
22
|
import java.io.OutputStream;
|
|
@@ -20,8 +24,8 @@ import java.net.HttpURLConnection;
|
|
|
20
24
|
import java.net.URL;
|
|
21
25
|
import java.util.ArrayList;
|
|
22
26
|
import java.util.List;
|
|
23
|
-
import java.util.Map;
|
|
24
27
|
import java.util.Locale;
|
|
28
|
+
import java.util.Map;
|
|
25
29
|
|
|
26
30
|
public class Util {
|
|
27
31
|
|
|
@@ -62,7 +66,7 @@ public class Util {
|
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
public static boolean isValidURL(String url){
|
|
69
|
+
public static boolean isValidURL(String url) {
|
|
66
70
|
return URLUtil.isValidUrl(url) && Patterns.WEB_URL.matcher(url).matches();
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -75,14 +79,28 @@ public class Util {
|
|
|
75
79
|
while (playlistItems.size() > j) {
|
|
76
80
|
ReadableMap playlistItem = playlistItems.getMap(j);
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
JSONObject obj;
|
|
83
|
+
PlaylistItem item = null;
|
|
84
|
+
// Try since legacy config may or may not conform to this standard
|
|
85
|
+
try {
|
|
86
|
+
obj = MapUtil.toJSONObject(playlistItem);
|
|
87
|
+
item = JsonHelper.parsePlaylistItemJson(obj);
|
|
88
|
+
} catch (Exception ex) {
|
|
89
|
+
Log.e("createPlaylist", ex.toString());
|
|
90
|
+
}
|
|
91
|
+
if (item != null) {
|
|
92
|
+
playlist.add(item);
|
|
93
|
+
} else {
|
|
94
|
+
// Try to use the legacy format
|
|
95
|
+
PlaylistItem newPlayListItem = getPlaylistItem((playlistItem));
|
|
96
|
+
playlist.add(newPlayListItem);
|
|
97
|
+
}
|
|
80
98
|
j++;
|
|
81
99
|
}
|
|
82
100
|
return playlist;
|
|
83
101
|
}
|
|
84
102
|
|
|
85
|
-
public static PlaylistItem getPlaylistItem
|
|
103
|
+
public static PlaylistItem getPlaylistItem(ReadableMap playlistItem) {
|
|
86
104
|
PlaylistItem.Builder itemBuilder = new PlaylistItem.Builder();
|
|
87
105
|
|
|
88
106
|
if (playlistItem.hasKey("file")) {
|
|
@@ -194,11 +212,12 @@ public class Util {
|
|
|
194
212
|
|
|
195
213
|
/**
|
|
196
214
|
* Internal helper for parsing a caption type from a known string
|
|
215
|
+
*
|
|
197
216
|
* @param type one of "CAPTIONS", "CHAPTERS", "THUMBNAILS"
|
|
198
217
|
* @return the correct Enum CaptionType
|
|
199
218
|
*/
|
|
200
|
-
public static CaptionType getCaptionType(String type){
|
|
201
|
-
for (CaptionType captionType: CaptionType.values()) {
|
|
219
|
+
public static CaptionType getCaptionType(String type) {
|
|
220
|
+
for (CaptionType captionType : CaptionType.values()) {
|
|
202
221
|
if (captionType.name().equals(type)) {
|
|
203
222
|
return CaptionType.valueOf(type);
|
|
204
223
|
}
|
package/badges/version.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="90" height="20" role="img" aria-label="version: 1.0.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="90" height="20" role="img" aria-label="version: 1.0.3"><title>version: 1.0.3</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="90" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="51" height="20" fill="#555"/><rect x="51" width="39" height="20" fill="#007ec6"/><rect width="90" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="265" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="410">version</text><text x="265" y="140" transform="scale(.1)" fill="#fff" textLength="410">version</text><text aria-hidden="true" x="695" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="290">1.0.3</text><text x="695" y="140" transform="scale(.1)" fill="#fff" textLength="290">1.0.3</text></g></svg>
|
package/index.d.ts
CHANGED
|
@@ -26,7 +26,13 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
26
26
|
advertising?: JwAdvertisingConfig;
|
|
27
27
|
playbackRates?: number[];
|
|
28
28
|
playbackRateControls?: boolean;
|
|
29
|
+
// Non-Json Parsing props
|
|
29
30
|
license: string;
|
|
31
|
+
playerInModal?: boolean;
|
|
32
|
+
fullScreenOnLandscape?: boolean;
|
|
33
|
+
landscapeOnFullScreen?: boolean;
|
|
34
|
+
portraitOnExitFullScreen?: boolean;
|
|
35
|
+
exitFullScreenOnPortrait?: boolean;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
type JwThumbnailPreview = 101 | 102 | 103;
|
|
@@ -448,6 +454,7 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
448
454
|
landscapeOnFullScreen?: boolean;
|
|
449
455
|
portraitOnExitFullScreen?: boolean;
|
|
450
456
|
exitFullScreenOnPortrait?: boolean;
|
|
457
|
+
playerInModal?: boolean;
|
|
451
458
|
playlist?: PlaylistItem[];
|
|
452
459
|
stretching?: string;
|
|
453
460
|
related?: Related;
|
|
@@ -476,6 +483,15 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
476
483
|
rate: number;
|
|
477
484
|
at: number;
|
|
478
485
|
}
|
|
486
|
+
interface PlayerSetupErrorProps {
|
|
487
|
+
errorMessage?: string;
|
|
488
|
+
errorCode?: number;
|
|
489
|
+
}
|
|
490
|
+
interface PlayerErrorProps {
|
|
491
|
+
error?: string;
|
|
492
|
+
errorCode?: number;
|
|
493
|
+
description?: string; // Android Only
|
|
494
|
+
}
|
|
479
495
|
interface TimeEventProps {
|
|
480
496
|
position: number;
|
|
481
497
|
duration: number;
|
|
@@ -486,6 +502,9 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
486
502
|
interface PlaylistEventProps {
|
|
487
503
|
playlist: PlaylistItem[]
|
|
488
504
|
}
|
|
505
|
+
interface LoadEventProps {
|
|
506
|
+
loadTime: number;
|
|
507
|
+
}
|
|
489
508
|
interface PlaylistItemEventProps {
|
|
490
509
|
playlistItem: PlaylistItem
|
|
491
510
|
}
|
|
@@ -494,15 +513,26 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
494
513
|
error: string;
|
|
495
514
|
}
|
|
496
515
|
interface PlayerWarningEventProps {
|
|
497
|
-
code
|
|
498
|
-
warning
|
|
516
|
+
code?: number;
|
|
517
|
+
warning?: string;
|
|
518
|
+
adErrorCode?: number; // Android only
|
|
499
519
|
}
|
|
500
520
|
interface AdEventProps {
|
|
501
521
|
client?: string;
|
|
502
522
|
reason?: string;
|
|
503
523
|
type: number;
|
|
504
524
|
}
|
|
505
|
-
type
|
|
525
|
+
// Overloaded type to be used in multiple error events
|
|
526
|
+
interface CaptionsChangedEventProps {
|
|
527
|
+
index?: number;
|
|
528
|
+
}
|
|
529
|
+
interface CaptionsListEventProps {
|
|
530
|
+
index: number;
|
|
531
|
+
file?: string;
|
|
532
|
+
label: string;
|
|
533
|
+
default: string;
|
|
534
|
+
}
|
|
535
|
+
type NativeError = (event: BaseEvent<PlayerErrorEventProps> | BaseEvent<PlayerSetupErrorProps> | BaseEvent<PlayerErrorProps>) => void;
|
|
506
536
|
type NativeWarning = (event: BaseEvent<PlayerWarningEventProps>) => void;
|
|
507
537
|
interface PropsType {
|
|
508
538
|
config: Config | JwConfig;
|
|
@@ -511,6 +541,7 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
511
541
|
forceLegacyConfig?: boolean;
|
|
512
542
|
onPlayerReady?: () => void;
|
|
513
543
|
onPlaylist?: (event: BaseEvent<PlaylistEventProps>) => void;
|
|
544
|
+
onLoaded? : (event: BaseEvent<LoadEventProps>) => void;
|
|
514
545
|
onBeforePlay?: () => void;
|
|
515
546
|
onBeforeComplete?: () => void;
|
|
516
547
|
onComplete?: () => void;
|
|
@@ -521,9 +552,9 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
521
552
|
onRateChanged?: (event?: BaseEvent<RateChangedEventProps>) => void;
|
|
522
553
|
onSetupPlayerError?: NativeError;
|
|
523
554
|
onPlayerError?: NativeError;
|
|
524
|
-
onPlayerWarning?: NativeWarning;
|
|
525
|
-
onPlayerAdError?: NativeError;
|
|
526
|
-
onPlayerAdWarning?: NativeWarning;
|
|
555
|
+
onPlayerWarning?: NativeWarning;
|
|
556
|
+
onPlayerAdError?: NativeError;
|
|
557
|
+
onPlayerAdWarning?: NativeWarning;
|
|
527
558
|
onAdEvent?: (event: BaseEvent<AdEventProps>) => void;
|
|
528
559
|
onAdTime?: (event: BaseEvent<TimeEventProps>) => void;
|
|
529
560
|
onBuffer?: () => void;
|
|
@@ -535,6 +566,8 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
535
566
|
onControlBarVisible?: (event: BaseEvent<ControlBarVisibleEventProps>) => void;
|
|
536
567
|
onPlaylistComplete?: () => void;
|
|
537
568
|
onPlaylistItem?: (event: BaseEvent<PlaylistItemEventProps>) => void;
|
|
569
|
+
onCaptionsChanged?: (event: BaseEvent<CaptionsChangedEventProps>) => void;
|
|
570
|
+
onCaptionsList?: (event: BaseEvent<CaptionsListEventProps>) => void;
|
|
538
571
|
onAudioTracks?: () => void;
|
|
539
572
|
shouldComponentUpdate?: (nextProps: any, nextState: any) => boolean;
|
|
540
573
|
}
|
|
@@ -553,7 +586,7 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
553
586
|
setControls(show: boolean): void;
|
|
554
587
|
setLockScreenControls(show: boolean): void;
|
|
555
588
|
seekTo(time: number): void;
|
|
556
|
-
loadPlaylist(playlistItems: PlaylistItem[]): void;
|
|
589
|
+
loadPlaylist(playlistItems: PlaylistItem[] | JwPlaylistItem[] | string): void;
|
|
557
590
|
setFullscreen(fullScreen: boolean): void;
|
|
558
591
|
position(): Promise<number>;
|
|
559
592
|
setUpCastController(): void;
|
|
@@ -566,6 +599,7 @@ declare module "@jwplayer/jwplayer-react-native" {
|
|
|
566
599
|
getCurrentAudioTrack(): Promise<number | null>;
|
|
567
600
|
setCurrentAudioTrack(index: number): void;
|
|
568
601
|
setCurrentCaptions(index: number): void;
|
|
602
|
+
getCurrentCaptions(): Promise<number | null>;
|
|
569
603
|
setVisibility(visibility: boolean, controls: JWControlType[]): void;
|
|
570
604
|
}
|
|
571
605
|
}
|
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
findNodeHandle,
|
|
7
7
|
} from 'react-native';
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
|
-
import
|
|
9
|
+
import isEqualWith from 'lodash.isequalwith';
|
|
10
10
|
|
|
11
11
|
const RNJWPlayerManager =
|
|
12
12
|
Platform.OS === 'ios'
|
|
@@ -306,6 +306,7 @@ export default class JWPlayer extends Component {
|
|
|
306
306
|
offlineImage: PropTypes.string,
|
|
307
307
|
forceFullScreenOnLandscape: PropTypes.bool,
|
|
308
308
|
forceLandscapeOnFullScreen: PropTypes.bool,
|
|
309
|
+
playerInModal: PropTypes.bool,
|
|
309
310
|
enableLockScreenControls: PropTypes.bool,
|
|
310
311
|
stretching: PropTypes.oneOf([
|
|
311
312
|
'uniform',
|
|
@@ -319,6 +320,7 @@ export default class JWPlayer extends Component {
|
|
|
319
320
|
}),
|
|
320
321
|
onPlayerReady: PropTypes.func,
|
|
321
322
|
onPlaylist: PropTypes.func,
|
|
323
|
+
onLoaded: PropTypes.func,
|
|
322
324
|
changePlaylist: PropTypes.func,
|
|
323
325
|
play: PropTypes.func,
|
|
324
326
|
pause: PropTypes.func,
|
|
@@ -368,6 +370,9 @@ export default class JWPlayer extends Component {
|
|
|
368
370
|
getCurrentAudioTrack: PropTypes.func,
|
|
369
371
|
setCurrentAudioTrack: PropTypes.func,
|
|
370
372
|
setCurrentCaptions: PropTypes.func,
|
|
373
|
+
getCurrentCaptions: PropTypes.func,
|
|
374
|
+
onCaptionsChanged: PropTypes.func,
|
|
375
|
+
onCaptionsList: PropTypes.func,
|
|
371
376
|
onAudioTracks: PropTypes.func,
|
|
372
377
|
};
|
|
373
378
|
|
|
@@ -389,7 +394,7 @@ export default class JWPlayer extends Component {
|
|
|
389
394
|
var { config, controls } = nextProps;
|
|
390
395
|
var thisConfig = this.props.config || {};
|
|
391
396
|
|
|
392
|
-
var result = !
|
|
397
|
+
var result = !isEqualWith(
|
|
393
398
|
config,
|
|
394
399
|
thisConfig,
|
|
395
400
|
(value1, value2, key) => {
|
|
@@ -686,6 +691,21 @@ export default class JWPlayer extends Component {
|
|
|
686
691
|
);
|
|
687
692
|
}
|
|
688
693
|
}
|
|
694
|
+
|
|
695
|
+
async getCurrentCaptions() {
|
|
696
|
+
if (RNJWPlayerManager) {
|
|
697
|
+
try {
|
|
698
|
+
var currentCaptionTrack =
|
|
699
|
+
await RNJWPlayerManager.getCurrentCaptions(
|
|
700
|
+
this.getRNJWPlayerBridgeHandle()
|
|
701
|
+
);
|
|
702
|
+
return currentCaptionTrack;
|
|
703
|
+
} catch (e) {
|
|
704
|
+
console.error(e);
|
|
705
|
+
return null;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
689
709
|
|
|
690
710
|
getRNJWPlayerBridgeHandle() {
|
|
691
711
|
return findNodeHandle(this[this.ref_key]);
|
|
@@ -85,6 +85,8 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
85
85
|
@objc var onCasting: RCTDirectEventBlock?
|
|
86
86
|
@objc var onCastingEnded: RCTDirectEventBlock?
|
|
87
87
|
@objc var onCastingFailed: RCTDirectEventBlock?
|
|
88
|
+
@objc var onCaptionsChanged: RCTDirectEventBlock?
|
|
89
|
+
@objc var onCaptionsList: RCTDirectEventBlock?
|
|
88
90
|
|
|
89
91
|
init() {
|
|
90
92
|
super.init(frame: CGRect(x: 20, y: 0, width: UIScreen.main.bounds.width - 40, height: 300))
|
|
@@ -299,7 +301,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
299
301
|
}
|
|
300
302
|
|
|
301
303
|
if backgroundAudioEnabled || pipEnabled {
|
|
302
|
-
let category = config["category"] as? String
|
|
304
|
+
let category = config["category"] != nil ? config["category"] as? String : "playback" // default category for playback
|
|
303
305
|
let categoryOptions = config["categoryOptions"] as? [String]
|
|
304
306
|
let mode = config["mode"] as? String
|
|
305
307
|
|
|
@@ -960,12 +962,12 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
960
962
|
}
|
|
961
963
|
|
|
962
964
|
func jwplayer(_ player:JWPlayer, failedWithError code:UInt, message:String) {
|
|
963
|
-
self.onPlayerError?(["error": message])
|
|
965
|
+
self.onPlayerError?(["error": message, "errorCode": code])
|
|
964
966
|
playerFailed = true
|
|
965
967
|
}
|
|
966
968
|
|
|
967
969
|
func jwplayer(_ player:JWPlayer, failedWithSetupError code:UInt, message:String) {
|
|
968
|
-
self.onSetupPlayerError?(["
|
|
970
|
+
self.onSetupPlayerError?(["errorMessage": message, "errorCode": code])
|
|
969
971
|
playerFailed = true
|
|
970
972
|
}
|
|
971
973
|
|
|
@@ -979,7 +981,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
979
981
|
|
|
980
982
|
|
|
981
983
|
func jwplayer(_ player:JWPlayer, encounteredAdWarning code:UInt, message:String) {
|
|
982
|
-
self.onPlayerAdWarning?(["warning": message])
|
|
984
|
+
self.onPlayerAdWarning?(["warning": message, "code": code])
|
|
983
985
|
}
|
|
984
986
|
|
|
985
987
|
|
|
@@ -1179,10 +1181,6 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1179
1181
|
|
|
1180
1182
|
// MARK: - JWPlayer State Delegate
|
|
1181
1183
|
|
|
1182
|
-
func jwplayerContentIsBuffering(_ player:JWPlayer) {
|
|
1183
|
-
self.onBuffer?([:])
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
1184
|
func jwplayer(_ player:JWPlayer, isBufferingWithReason reason:JWBufferReason) {
|
|
1187
1185
|
self.onBuffer?([:])
|
|
1188
1186
|
}
|
|
@@ -1192,7 +1190,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1192
1190
|
}
|
|
1193
1191
|
|
|
1194
1192
|
func jwplayer(_ player:JWPlayer, didFinishLoadingWithTime loadTime:TimeInterval) {
|
|
1195
|
-
self.onLoaded?([:])
|
|
1193
|
+
self.onLoaded?(["loadTime":loadTime])
|
|
1196
1194
|
}
|
|
1197
1195
|
|
|
1198
1196
|
func jwplayer(_ player:JWPlayer, isAttemptingToPlay playlistItem:JWPlayerItem, reason:JWPlayReason) {
|
|
@@ -1233,6 +1231,10 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1233
1231
|
func jwplayerContentDidComplete(_ player:JWPlayer) {
|
|
1234
1232
|
self.onComplete?([:])
|
|
1235
1233
|
}
|
|
1234
|
+
|
|
1235
|
+
func jwplayerContentIsBuffering(_ player: any JWPlayerKit.JWPlayer) {
|
|
1236
|
+
|
|
1237
|
+
}
|
|
1236
1238
|
|
|
1237
1239
|
func jwplayer(_ player:JWPlayer, didLoadPlaylistItem item:JWPlayerItem, at index:UInt) {
|
|
1238
1240
|
// var sourceDict: [String: Any] = [:]
|
|
@@ -1400,7 +1402,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1400
1402
|
}
|
|
1401
1403
|
|
|
1402
1404
|
func jwplayer(_ player:JWPlayer, captionTrackChanged index:Int) {
|
|
1403
|
-
|
|
1405
|
+
self.onCaptionsChanged?(["index": index])
|
|
1404
1406
|
}
|
|
1405
1407
|
|
|
1406
1408
|
func jwplayer(_ player: JWPlayer, visualQualityChanged currentVisualQuality: JWVisualQuality) {
|
|
@@ -1416,7 +1418,15 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1416
1418
|
}
|
|
1417
1419
|
|
|
1418
1420
|
func jwplayer(_ player:JWPlayer, updatedCaptionList options:[JWMediaSelectionOption]) {
|
|
1419
|
-
|
|
1421
|
+
var tracks: [[String: Any]] = []
|
|
1422
|
+
for track in player.captionsTracks {
|
|
1423
|
+
var dict: [String: Any] = [:]
|
|
1424
|
+
dict["label"] = track.name
|
|
1425
|
+
dict["default"] = track.defaultOption
|
|
1426
|
+
tracks.append(dict)
|
|
1427
|
+
}
|
|
1428
|
+
let currentIndex = player.currentCaptionsTrack
|
|
1429
|
+
self.onCaptionsList?(["index": currentIndex, "tracks": tracks])
|
|
1420
1430
|
}
|
|
1421
1431
|
|
|
1422
1432
|
// MARK: - JWPlayer audio session && interruption handling
|
|
@@ -1518,29 +1528,32 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1518
1528
|
}
|
|
1519
1529
|
|
|
1520
1530
|
var options: AVAudioSession.CategoryOptions = []
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1531
|
+
// If the user doesn't specify any options
|
|
1532
|
+
if categoryOptions != nil {
|
|
1533
|
+
if categoryOptions.contains("MixWithOthers") {
|
|
1534
|
+
options.insert(.mixWithOthers)
|
|
1535
|
+
}
|
|
1536
|
+
if categoryOptions.contains("DuckOthers") {
|
|
1537
|
+
options.insert(.duckOthers)
|
|
1538
|
+
}
|
|
1539
|
+
if categoryOptions.contains("AllowBluetooth") {
|
|
1540
|
+
options.insert(.allowBluetooth)
|
|
1541
|
+
}
|
|
1542
|
+
if categoryOptions.contains("InterruptSpokenAudioAndMix") {
|
|
1543
|
+
options.insert(.interruptSpokenAudioAndMixWithOthers)
|
|
1544
|
+
}
|
|
1545
|
+
if categoryOptions.contains("AllowBluetoothA2DP") {
|
|
1546
|
+
options.insert(.allowBluetoothA2DP)
|
|
1547
|
+
}
|
|
1548
|
+
if categoryOptions.contains("AllowAirPlay") {
|
|
1549
|
+
options.insert(.allowAirPlay)
|
|
1550
|
+
}
|
|
1551
|
+
if categoryOptions.contains("OverrideMutedMicrophone") {
|
|
1552
|
+
if #available(iOS 14.5, *) {
|
|
1553
|
+
options.insert(.overrideMutedMicrophoneInterruption)
|
|
1554
|
+
} else {
|
|
1555
|
+
// Handle the case for earlier versions if needed
|
|
1556
|
+
}
|
|
1544
1557
|
}
|
|
1545
1558
|
}
|
|
1546
1559
|
|
|
@@ -55,13 +55,13 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
|
|
|
55
55
|
|
|
56
56
|
override func jwplayer(_ player:JWPlayer, failedWithError code:UInt, message:String) {
|
|
57
57
|
super.jwplayer(player, failedWithError:code, message:message)
|
|
58
|
-
parentView?.onPlayerError?(["error": message])
|
|
58
|
+
parentView?.onPlayerError?(["error": message, "errorCode": code])
|
|
59
59
|
parentView?.playerFailed = true
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
override func jwplayer(_ player:JWPlayer, failedWithSetupError code:UInt, message:String) {
|
|
63
63
|
super.jwplayer(player, failedWithSetupError:code, message:message)
|
|
64
|
-
parentView?.onSetupPlayerError?(["
|
|
64
|
+
parentView?.onSetupPlayerError?(["errorMessage": message, "errorCode": code])
|
|
65
65
|
parentView?.playerFailed = true
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -78,7 +78,7 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
|
|
|
78
78
|
|
|
79
79
|
override func jwplayer(_ player:JWPlayer, encounteredAdWarning code:UInt, message:String) {
|
|
80
80
|
super.jwplayer(player, encounteredAdWarning:code, message:message)
|
|
81
|
-
parentView?.onPlayerAdWarning?(["warning": message])
|
|
81
|
+
parentView?.onPlayerAdWarning?(["warning": message, "code": code])
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
|
|
@@ -263,11 +263,6 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
|
|
|
263
263
|
|
|
264
264
|
// MARK: - JWPlayer State Delegate
|
|
265
265
|
|
|
266
|
-
override func jwplayerContentIsBuffering(_ player:JWPlayer) {
|
|
267
|
-
super.jwplayerContentIsBuffering(player)
|
|
268
|
-
parentView?.onBuffer?([:])
|
|
269
|
-
}
|
|
270
|
-
|
|
271
266
|
override func jwplayer(_ player:JWPlayer, isBufferingWithReason reason:JWBufferReason) {
|
|
272
267
|
super.jwplayer(player, isBufferingWithReason:reason)
|
|
273
268
|
parentView?.onBuffer?([:])
|
|
@@ -280,7 +275,7 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
|
|
|
280
275
|
|
|
281
276
|
override func jwplayer(_ player:JWPlayer, didFinishLoadingWithTime loadTime:TimeInterval) {
|
|
282
277
|
super.jwplayer(player, didFinishLoadingWithTime:loadTime)
|
|
283
|
-
parentView?.onLoaded?([:])
|
|
278
|
+
parentView?.onLoaded?(["loadTime":loadTime])
|
|
284
279
|
}
|
|
285
280
|
|
|
286
281
|
override func jwplayer(_ player:JWPlayer, isAttemptingToPlay playlistItem:JWPlayerItem, reason:JWPlayReason) {
|
|
@@ -588,6 +583,7 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
|
|
|
588
583
|
|
|
589
584
|
override func jwplayer(_ player:JWPlayer, captionTrackChanged index:Int) {
|
|
590
585
|
super.jwplayer(player, captionTrackChanged:index)
|
|
586
|
+
parentView.onCaptionsChanged?(["index": index])
|
|
591
587
|
}
|
|
592
588
|
|
|
593
589
|
override func jwplayer(_ player:JWPlayer, qualityLevelChanged currentLevel:Int) {
|
|
@@ -600,6 +596,16 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
|
|
|
600
596
|
|
|
601
597
|
override func jwplayer(_ player:JWPlayer, updatedCaptionList options:[JWMediaSelectionOption]) {
|
|
602
598
|
super.jwplayer(player, updatedCaptionList:options)
|
|
599
|
+
|
|
600
|
+
var tracks: [[String: Any]] = []
|
|
601
|
+
for track in player.captionsTracks {
|
|
602
|
+
var dict: [String: Any] = [:]
|
|
603
|
+
dict["label"] = track.name
|
|
604
|
+
dict["default"] = track.defaultOption
|
|
605
|
+
tracks.append(dict)
|
|
606
|
+
}
|
|
607
|
+
let currentIndex = player.currentCaptionsTrack
|
|
608
|
+
parentView.onCaptionsList?(["index": currentIndex, "tracks": tracks])
|
|
603
609
|
}
|
|
604
610
|
|
|
605
611
|
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
|
@@ -32,6 +32,8 @@ RCT_EXPORT_VIEW_PROPERTY(onPlaylistItem, RCTDirectEventBlock);
|
|
|
32
32
|
|
|
33
33
|
/* av events */
|
|
34
34
|
RCT_EXPORT_VIEW_PROPERTY(onAudioTracks, RCTDirectEventBlock);
|
|
35
|
+
RCT_EXPORT_VIEW_PROPERTY(onCaptionsChanged, RCTDirectEventBlock);
|
|
36
|
+
RCT_EXPORT_VIEW_PROPERTY(onCaptionsList, RCTDirectEventBlock);
|
|
35
37
|
|
|
36
38
|
/* player events */
|
|
37
39
|
RCT_EXPORT_VIEW_PROPERTY(onPlayerReady, RCTDirectEventBlock);
|
|
@@ -93,6 +95,8 @@ RCT_EXTERN_METHOD(setVolume: (nonnull NSNumber *)reactTag :(nonnull NSNumber *)v
|
|
|
93
95
|
|
|
94
96
|
RCT_EXTERN_METHOD(togglePIP: (nonnull NSNumber *)reactTag)
|
|
95
97
|
|
|
98
|
+
#if USE_GOOGLE_CAST
|
|
99
|
+
|
|
96
100
|
RCT_EXTERN_METHOD(setUpCastController: (nonnull NSNumber *)reactTag)
|
|
97
101
|
|
|
98
102
|
RCT_EXTERN_METHOD(presentCastDialog: (nonnull NSNumber *)reactTag)
|
|
@@ -103,6 +107,8 @@ RCT_EXTERN_METHOD(availableDevices: (nonnull NSNumber *)reactTag: (RCTPromiseRes
|
|
|
103
107
|
|
|
104
108
|
RCT_EXTERN_METHOD(castState: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
|
|
105
109
|
|
|
110
|
+
#endif
|
|
111
|
+
|
|
106
112
|
RCT_EXTERN_METHOD(getAudioTracks: (nonnull NSNumber *)reactTag: (RCTPromiseResolveBlock)resolve: (RCTPromiseRejectBlock)reject)
|
|
107
113
|
|
|
108
114
|
RCT_EXTERN_METHOD(getCurrentAudioTrack: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
|
|
@@ -117,7 +123,7 @@ RCT_EXTERN_METHOD(setLockScreenControls: (nonnull NSNumber *)reactTag: (BOOL)sho
|
|
|
117
123
|
|
|
118
124
|
RCT_EXTERN_METHOD(setCurrentCaptions: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
|
|
119
125
|
|
|
120
|
-
RCT_EXTERN_METHOD(
|
|
126
|
+
RCT_EXTERN_METHOD(getCurrentCaptions: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
|
|
121
127
|
|
|
122
128
|
RCT_EXTERN_METHOD(setLicenseKey: (nonnull NSNumber *)reactTag: (nonnull NSString *)license)
|
|
123
129
|
|
|
@@ -127,6 +133,8 @@ RCT_EXTERN_METHOD(reset)
|
|
|
127
133
|
|
|
128
134
|
RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSArray *)playlist)
|
|
129
135
|
|
|
136
|
+
RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSString *)playlist)
|
|
137
|
+
|
|
130
138
|
RCT_EXTERN_METHOD(setFullscreen: (nonnull NSNumber *)reactTag: (BOOL)fullscreen)
|
|
131
139
|
|
|
132
140
|
@end
|