@jwplayer/jwplayer-react-native 1.0.0 → 1.0.2
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/CODEOWNERS +1 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +12 -2
- package/.github/ISSUE_TEMPLATE/feature_request.md +12 -2
- package/.github/ISSUE_TEMPLATE/implement.md +26 -0
- package/.github/ISSUE_TEMPLATE/question.md +12 -2
- package/README.md +25 -3
- 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 +2 -2
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +259 -11
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +4 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +24 -3
- package/badges/version.svg +1 -1
- package/index.d.ts +14 -2
- package/index.js +8 -2
- package/ios/RNJWPlayer/RNJWPlayerView.swift +202 -196
- package/ios/RNJWPlayer/RNJWPlayerViewController.swift +27 -23
- package/ios/RNJWPlayer/RNJWPlayerViewManager.m +4 -0
- package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +5 -3
- package/package.json +3 -3
- package/android/.gradle/8.1.1/checksums/checksums.lock +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.2/checksums/checksums.lock +0 -0
- package/android/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.2/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.2/gc.properties +0 -0
- package/android/.gradle/config.properties +0 -2
- package/android/.idea/gradle.xml +0 -12
- package/android/.idea/migrations.xml +0 -10
- package/android/.idea/misc.xml +0 -10
- package/android/.idea/vcs.xml +0 -6
- package/android/.idea/workspace.xml +0 -54
- package/android/local.properties +0 -8
- /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
|
@@ -159,6 +159,10 @@ public class RNJWPlayerViewManager extends SimpleViewManager<RNJWPlayerView> {
|
|
|
159
159
|
MapBuilder.of(
|
|
160
160
|
"phasedRegistrationNames",
|
|
161
161
|
MapBuilder.of("bubbled", "onCasting")))
|
|
162
|
+
.put("topFirstFrame",
|
|
163
|
+
MapBuilder.of(
|
|
164
|
+
"phasedRegistrationNames",
|
|
165
|
+
MapBuilder.of("bubbled", "onLoaded")))
|
|
162
166
|
.build();
|
|
163
167
|
}
|
|
164
168
|
|
|
@@ -21,6 +21,7 @@ import java.net.URL;
|
|
|
21
21
|
import java.util.ArrayList;
|
|
22
22
|
import java.util.List;
|
|
23
23
|
import java.util.Map;
|
|
24
|
+
import java.util.Locale;
|
|
24
25
|
|
|
25
26
|
public class Util {
|
|
26
27
|
|
|
@@ -98,7 +99,7 @@ public class Util {
|
|
|
98
99
|
if (sourceProp.hasKey("file")) {
|
|
99
100
|
String file = sourceProp.getString("file");
|
|
100
101
|
String label = sourceProp.getString("label");
|
|
101
|
-
boolean isDefault = sourceProp.getBoolean("default");
|
|
102
|
+
boolean isDefault = sourceProp.hasKey("default") ? sourceProp.getBoolean("default") : false;
|
|
102
103
|
MediaSource source = new MediaSource.Builder().file(file).label(label).isDefault(isDefault).build();
|
|
103
104
|
sources.add(source);
|
|
104
105
|
}
|
|
@@ -147,8 +148,13 @@ public class Util {
|
|
|
147
148
|
if (trackProp.hasKey("file")) {
|
|
148
149
|
String file = trackProp.getString("file");
|
|
149
150
|
String label = trackProp.getString("label");
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
CaptionType kind = CaptionType.CAPTIONS;
|
|
152
|
+
// Being safe to old implementations though this should be required.
|
|
153
|
+
if (trackProp.hasKey("kind")) {
|
|
154
|
+
kind = getCaptionType(trackProp.getString("kind").toUpperCase(Locale.US));
|
|
155
|
+
}
|
|
156
|
+
boolean isDefault = trackProp.hasKey("default") ? trackProp.getBoolean("default") : false;
|
|
157
|
+
Caption caption = new Caption.Builder().file(file).label(label).kind(kind).isDefault(isDefault).build();
|
|
152
158
|
tracks.add(caption);
|
|
153
159
|
}
|
|
154
160
|
}
|
|
@@ -186,6 +192,21 @@ public class Util {
|
|
|
186
192
|
return itemBuilder.build();
|
|
187
193
|
}
|
|
188
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Internal helper for parsing a caption type from a known string
|
|
197
|
+
* @param type one of "CAPTIONS", "CHAPTERS", "THUMBNAILS"
|
|
198
|
+
* @return the correct Enum CaptionType
|
|
199
|
+
*/
|
|
200
|
+
public static CaptionType getCaptionType(String type){
|
|
201
|
+
for (CaptionType captionType: CaptionType.values()) {
|
|
202
|
+
if (captionType.name().equals(type)) {
|
|
203
|
+
return CaptionType.valueOf(type);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// This should never happen. If a null is returned, expect a crash. Check `type` is specified type
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
189
210
|
public enum AdEventType {
|
|
190
211
|
JWAdEventTypeAdBreakEnd(0),
|
|
191
212
|
JWAdEventTypeAdBreakStart(1),
|
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.2"><title>version: 1.0.2</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.2</text><text x="695" y="140" transform="scale(.1)" fill="#fff" textLength="290">1.0.2</text></g></svg>
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare module "jwplayer-react-native" {
|
|
1
|
+
declare module "@jwplayer/jwplayer-react-native" {
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { ViewStyle } from "react-native";
|
|
4
4
|
|
|
@@ -216,7 +216,7 @@ declare module "jwplayer-react-native" {
|
|
|
216
216
|
interface JwTrack {
|
|
217
217
|
id?: string;
|
|
218
218
|
file?: string;
|
|
219
|
-
kind:
|
|
219
|
+
kind: TrackKind;
|
|
220
220
|
label?: string;
|
|
221
221
|
default?: boolean;
|
|
222
222
|
}
|
|
@@ -251,9 +251,13 @@ declare module "jwplayer-react-native" {
|
|
|
251
251
|
label: string;
|
|
252
252
|
default?: boolean;
|
|
253
253
|
}
|
|
254
|
+
|
|
255
|
+
type TrackKind = "captions" | "chapters" | "thumbnails";
|
|
256
|
+
|
|
254
257
|
interface Track {
|
|
255
258
|
file: string;
|
|
256
259
|
label: string;
|
|
260
|
+
kind: TrackKind;
|
|
257
261
|
default?: boolean;
|
|
258
262
|
}
|
|
259
263
|
interface JWAdSettings {
|
|
@@ -349,6 +353,9 @@ declare module "jwplayer-react-native" {
|
|
|
349
353
|
size?: number;
|
|
350
354
|
}
|
|
351
355
|
type EdgeStyles = "none" | "dropshadow" | "raised" | "depressed" | "uniform";
|
|
356
|
+
|
|
357
|
+
// All `Styling` is only intended to be used with iOS. Android requires overloading
|
|
358
|
+
// of the JWP IDs seen here: https://docs.jwplayer.com/players/docs/android-styling-guide
|
|
352
359
|
interface Styling {
|
|
353
360
|
colors?: {
|
|
354
361
|
buttons?: string;
|
|
@@ -441,6 +448,7 @@ declare module "jwplayer-react-native" {
|
|
|
441
448
|
landscapeOnFullScreen?: boolean;
|
|
442
449
|
portraitOnExitFullScreen?: boolean;
|
|
443
450
|
exitFullScreenOnPortrait?: boolean;
|
|
451
|
+
playerInModal?: boolean;
|
|
444
452
|
playlist?: PlaylistItem[];
|
|
445
453
|
stretching?: string;
|
|
446
454
|
related?: Related;
|
|
@@ -479,6 +487,9 @@ declare module "jwplayer-react-native" {
|
|
|
479
487
|
interface PlaylistEventProps {
|
|
480
488
|
playlist: PlaylistItem[]
|
|
481
489
|
}
|
|
490
|
+
interface LoadEventProps {
|
|
491
|
+
loadTime: number;
|
|
492
|
+
}
|
|
482
493
|
interface PlaylistItemEventProps {
|
|
483
494
|
playlistItem: PlaylistItem
|
|
484
495
|
}
|
|
@@ -504,6 +515,7 @@ declare module "jwplayer-react-native" {
|
|
|
504
515
|
forceLegacyConfig?: boolean;
|
|
505
516
|
onPlayerReady?: () => void;
|
|
506
517
|
onPlaylist?: (event: BaseEvent<PlaylistEventProps>) => void;
|
|
518
|
+
onLoaded? : (event: BaseEvent<LoadEventProps>) => void;
|
|
507
519
|
onBeforePlay?: () => void;
|
|
508
520
|
onBeforeComplete?: () => void;
|
|
509
521
|
onComplete?: () => void;
|
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'
|
|
@@ -232,6 +232,8 @@ export default class JWPlayer extends Component {
|
|
|
232
232
|
PropTypes.shape({
|
|
233
233
|
file: PropTypes.string,
|
|
234
234
|
label: PropTypes.string,
|
|
235
|
+
kind: PropTypes.oneOf(['captions', 'thumbnails', 'chapters']),
|
|
236
|
+
default: PropTypes.bool
|
|
235
237
|
})
|
|
236
238
|
),
|
|
237
239
|
adSchedule: PropTypes.arrayOf(
|
|
@@ -252,6 +254,8 @@ export default class JWPlayer extends Component {
|
|
|
252
254
|
'hidden',
|
|
253
255
|
'onscreen',
|
|
254
256
|
]),
|
|
257
|
+
// All `Styling` is only intended to be used with iOS. Android requires overloading
|
|
258
|
+
// of the JWP IDs seen here: https://docs.jwplayer.com/players/docs/android-styling-guide
|
|
255
259
|
styling: PropTypes.shape({
|
|
256
260
|
colors: PropTypes.shape({
|
|
257
261
|
buttons: PropTypes.string,
|
|
@@ -302,6 +306,7 @@ export default class JWPlayer extends Component {
|
|
|
302
306
|
offlineImage: PropTypes.string,
|
|
303
307
|
forceFullScreenOnLandscape: PropTypes.bool,
|
|
304
308
|
forceLandscapeOnFullScreen: PropTypes.bool,
|
|
309
|
+
playerInModal: PropTypes.bool,
|
|
305
310
|
enableLockScreenControls: PropTypes.bool,
|
|
306
311
|
stretching: PropTypes.oneOf([
|
|
307
312
|
'uniform',
|
|
@@ -315,6 +320,7 @@ export default class JWPlayer extends Component {
|
|
|
315
320
|
}),
|
|
316
321
|
onPlayerReady: PropTypes.func,
|
|
317
322
|
onPlaylist: PropTypes.func,
|
|
323
|
+
onLoaded: PropTypes.func,
|
|
318
324
|
changePlaylist: PropTypes.func,
|
|
319
325
|
play: PropTypes.func,
|
|
320
326
|
pause: PropTypes.func,
|
|
@@ -385,7 +391,7 @@ export default class JWPlayer extends Component {
|
|
|
385
391
|
var { config, controls } = nextProps;
|
|
386
392
|
var thisConfig = this.props.config || {};
|
|
387
393
|
|
|
388
|
-
var result = !
|
|
394
|
+
var result = !isEqualWith(
|
|
389
395
|
config,
|
|
390
396
|
thisConfig,
|
|
391
397
|
(value1, value2, key) => {
|
|
@@ -10,14 +10,17 @@ import AVFoundation
|
|
|
10
10
|
import AVKit
|
|
11
11
|
import MediaPlayer
|
|
12
12
|
import React
|
|
13
|
-
import GoogleCast
|
|
14
13
|
import JWPlayerKit
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
#if USE_GOOGLE_CAST
|
|
16
|
+
import GoogleCast
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDelegate, JWAVDelegate, JWPlayerViewDelegate, JWPlayerViewControllerDelegate, JWDRMContentKeyDataSource, JWTimeEventListener, AVPictureInPictureControllerDelegate {
|
|
17
20
|
|
|
18
21
|
// MARK: - RNJWPlayer allocation
|
|
19
22
|
|
|
20
|
-
var playerViewController:RNJWPlayerViewController!
|
|
23
|
+
var playerViewController: RNJWPlayerViewController!
|
|
21
24
|
var playerView: JWPlayerView!
|
|
22
25
|
var audioSession: AVAudioSession!
|
|
23
26
|
var pipEnabled: Bool = true
|
|
@@ -39,49 +42,49 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
39
42
|
var isCasting: Bool = false
|
|
40
43
|
var availableDevices: [AnyObject]!
|
|
41
44
|
|
|
42
|
-
@objc var onBuffer:RCTDirectEventBlock?
|
|
43
|
-
@objc var onUpdateBuffer:RCTDirectEventBlock?
|
|
44
|
-
@objc var onPlay:RCTDirectEventBlock?
|
|
45
|
-
@objc var onBeforePlay:RCTDirectEventBlock?
|
|
46
|
-
@objc var onAttemptPlay:RCTDirectEventBlock?
|
|
47
|
-
@objc var onPause:RCTDirectEventBlock?
|
|
48
|
-
@objc var onIdle:RCTDirectEventBlock?
|
|
49
|
-
@objc var onPlaylistItem:RCTDirectEventBlock?
|
|
50
|
-
@objc var onLoaded:RCTDirectEventBlock?
|
|
51
|
-
@objc var onVisible:RCTDirectEventBlock?
|
|
52
|
-
@objc var onTime:RCTDirectEventBlock?
|
|
53
|
-
@objc var onSeek:RCTDirectEventBlock?
|
|
54
|
-
@objc var onSeeked:RCTDirectEventBlock?
|
|
55
|
-
@objc var onRateChanged:RCTDirectEventBlock?
|
|
56
|
-
@objc var onPlaylist:RCTDirectEventBlock?
|
|
57
|
-
@objc var onPlaylistComplete:RCTDirectEventBlock?
|
|
58
|
-
@objc var onBeforeComplete:RCTDirectEventBlock?
|
|
59
|
-
@objc var onComplete:RCTDirectEventBlock?
|
|
60
|
-
@objc var onAudioTracks:RCTDirectEventBlock?
|
|
61
|
-
@objc var onPlayerReady:RCTDirectEventBlock?
|
|
62
|
-
@objc var onSetupPlayerError:RCTDirectEventBlock?
|
|
63
|
-
@objc var onPlayerError:RCTDirectEventBlock?
|
|
64
|
-
@objc var onPlayerWarning:RCTDirectEventBlock?
|
|
65
|
-
@objc var onPlayerAdWarning:RCTDirectEventBlock?
|
|
66
|
-
@objc var onPlayerAdError:RCTDirectEventBlock?
|
|
67
|
-
@objc var onAdEvent:RCTDirectEventBlock?
|
|
68
|
-
@objc var onAdTime:RCTDirectEventBlock?
|
|
69
|
-
@objc var onScreenTapped:RCTDirectEventBlock?
|
|
70
|
-
@objc var onControlBarVisible:RCTDirectEventBlock?
|
|
71
|
-
@objc var onFullScreen:RCTDirectEventBlock?
|
|
72
|
-
@objc var onFullScreenRequested:RCTDirectEventBlock?
|
|
73
|
-
@objc var onFullScreenExit:RCTDirectEventBlock?
|
|
74
|
-
@objc var onFullScreenExitRequested:RCTDirectEventBlock?
|
|
75
|
-
@objc var onPlayerSizeChange:RCTDirectEventBlock?
|
|
76
|
-
@objc var onCastingDevicesAvailable:RCTDirectEventBlock?
|
|
77
|
-
@objc var onConnectedToCastingDevice:RCTDirectEventBlock?
|
|
78
|
-
@objc var onDisconnectedFromCastingDevice:RCTDirectEventBlock?
|
|
79
|
-
@objc var onConnectionTemporarilySuspended:RCTDirectEventBlock?
|
|
80
|
-
@objc var onConnectionRecovered:RCTDirectEventBlock?
|
|
81
|
-
@objc var onConnectionFailed:RCTDirectEventBlock?
|
|
82
|
-
@objc var onCasting:RCTDirectEventBlock?
|
|
83
|
-
@objc var onCastingEnded:RCTDirectEventBlock?
|
|
84
|
-
@objc var onCastingFailed:RCTDirectEventBlock?
|
|
45
|
+
@objc var onBuffer: RCTDirectEventBlock?
|
|
46
|
+
@objc var onUpdateBuffer: RCTDirectEventBlock?
|
|
47
|
+
@objc var onPlay: RCTDirectEventBlock?
|
|
48
|
+
@objc var onBeforePlay: RCTDirectEventBlock?
|
|
49
|
+
@objc var onAttemptPlay: RCTDirectEventBlock?
|
|
50
|
+
@objc var onPause: RCTDirectEventBlock?
|
|
51
|
+
@objc var onIdle: RCTDirectEventBlock?
|
|
52
|
+
@objc var onPlaylistItem: RCTDirectEventBlock?
|
|
53
|
+
@objc var onLoaded: RCTDirectEventBlock?
|
|
54
|
+
@objc var onVisible: RCTDirectEventBlock?
|
|
55
|
+
@objc var onTime: RCTDirectEventBlock?
|
|
56
|
+
@objc var onSeek: RCTDirectEventBlock?
|
|
57
|
+
@objc var onSeeked: RCTDirectEventBlock?
|
|
58
|
+
@objc var onRateChanged: RCTDirectEventBlock?
|
|
59
|
+
@objc var onPlaylist: RCTDirectEventBlock?
|
|
60
|
+
@objc var onPlaylistComplete: RCTDirectEventBlock?
|
|
61
|
+
@objc var onBeforeComplete: RCTDirectEventBlock?
|
|
62
|
+
@objc var onComplete: RCTDirectEventBlock?
|
|
63
|
+
@objc var onAudioTracks: RCTDirectEventBlock?
|
|
64
|
+
@objc var onPlayerReady: RCTDirectEventBlock?
|
|
65
|
+
@objc var onSetupPlayerError: RCTDirectEventBlock?
|
|
66
|
+
@objc var onPlayerError: RCTDirectEventBlock?
|
|
67
|
+
@objc var onPlayerWarning: RCTDirectEventBlock?
|
|
68
|
+
@objc var onPlayerAdWarning: RCTDirectEventBlock?
|
|
69
|
+
@objc var onPlayerAdError: RCTDirectEventBlock?
|
|
70
|
+
@objc var onAdEvent: RCTDirectEventBlock?
|
|
71
|
+
@objc var onAdTime: RCTDirectEventBlock?
|
|
72
|
+
@objc var onScreenTapped: RCTDirectEventBlock?
|
|
73
|
+
@objc var onControlBarVisible: RCTDirectEventBlock?
|
|
74
|
+
@objc var onFullScreen: RCTDirectEventBlock?
|
|
75
|
+
@objc var onFullScreenRequested: RCTDirectEventBlock?
|
|
76
|
+
@objc var onFullScreenExit: RCTDirectEventBlock?
|
|
77
|
+
@objc var onFullScreenExitRequested: RCTDirectEventBlock?
|
|
78
|
+
@objc var onPlayerSizeChange: RCTDirectEventBlock?
|
|
79
|
+
@objc var onCastingDevicesAvailable: RCTDirectEventBlock?
|
|
80
|
+
@objc var onConnectedToCastingDevice: RCTDirectEventBlock?
|
|
81
|
+
@objc var onDisconnectedFromCastingDevice: RCTDirectEventBlock?
|
|
82
|
+
@objc var onConnectionTemporarilySuspended: RCTDirectEventBlock?
|
|
83
|
+
@objc var onConnectionRecovered: RCTDirectEventBlock?
|
|
84
|
+
@objc var onConnectionFailed: RCTDirectEventBlock?
|
|
85
|
+
@objc var onCasting: RCTDirectEventBlock?
|
|
86
|
+
@objc var onCastingEnded: RCTDirectEventBlock?
|
|
87
|
+
@objc var onCastingFailed: RCTDirectEventBlock?
|
|
85
88
|
|
|
86
89
|
init() {
|
|
87
90
|
super.init(frame: CGRect(x: 20, y: 0, width: UIScreen.main.bounds.width - 40, height: 300))
|
|
@@ -279,7 +282,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
279
282
|
func setNewConfig(config: [String : Any]) {
|
|
280
283
|
let forceLegacyConfig = config["forceLegacyConfig"] as? Bool?
|
|
281
284
|
let data:Data! = try? JSONSerialization.data(withJSONObject: config, options:.prettyPrinted)
|
|
282
|
-
let jwConfig = try? JWJSONParser.
|
|
285
|
+
let jwConfig = try? JWJSONParser.config(from:data)
|
|
283
286
|
|
|
284
287
|
currentConfig = config
|
|
285
288
|
|
|
@@ -1071,11 +1074,11 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1071
1074
|
|
|
1072
1075
|
// MARK: Time events
|
|
1073
1076
|
|
|
1074
|
-
func onAdTimeEvent(time:JWTimeData) {
|
|
1077
|
+
func onAdTimeEvent(_ time:JWTimeData) {
|
|
1075
1078
|
self.onAdTime?(["position": time.position, "duration": time.duration])
|
|
1076
1079
|
}
|
|
1077
1080
|
|
|
1078
|
-
func onMediaTimeEvent(time:JWTimeData) {
|
|
1081
|
+
func onMediaTimeEvent(_ time:JWTimeData) {
|
|
1079
1082
|
self.onTime?(["position": time.position, "duration": time.duration])
|
|
1080
1083
|
}
|
|
1081
1084
|
|
|
@@ -1189,7 +1192,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1189
1192
|
}
|
|
1190
1193
|
|
|
1191
1194
|
func jwplayer(_ player:JWPlayer, didFinishLoadingWithTime loadTime:TimeInterval) {
|
|
1192
|
-
self.onLoaded?([:])
|
|
1195
|
+
self.onLoaded?(["loadTime":loadTime])
|
|
1193
1196
|
}
|
|
1194
1197
|
|
|
1195
1198
|
func jwplayer(_ player:JWPlayer, isAttemptingToPlay playlistItem:JWPlayerItem, reason:JWPlayReason) {
|
|
@@ -1382,152 +1385,6 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1382
1385
|
self.onAdEvent?(["client": event.client, "type": event.type])
|
|
1383
1386
|
}
|
|
1384
1387
|
|
|
1385
|
-
// pragma Mark - Casting methods
|
|
1386
|
-
|
|
1387
|
-
func setUpCastController() {
|
|
1388
|
-
if (playerView != nil) && playerView.player as! Bool && (castController == nil) {
|
|
1389
|
-
castController = JWCastController(player:playerView.player)
|
|
1390
|
-
castController.delegate = self
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
self.scanForDevices()
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
func scanForDevices() {
|
|
1397
|
-
if castController != nil {
|
|
1398
|
-
castController.startDiscovery()
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
func stopScanForDevices() {
|
|
1403
|
-
if castController != nil {
|
|
1404
|
-
castController.stopDiscovery()
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
func presentCastDialog() {
|
|
1409
|
-
GCKCastContext.sharedInstance().presentCastDialog()
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
func startDiscovery() {
|
|
1413
|
-
GCKCastContext.sharedInstance().discoveryManager.startDiscovery()
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
func stopDiscovery() {
|
|
1417
|
-
GCKCastContext.sharedInstance().discoveryManager.stopDiscovery()
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1420
|
-
func discoveryActive() -> Bool {
|
|
1421
|
-
return GCKCastContext.sharedInstance().discoveryManager.discoveryActive
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
func hasDiscoveredDevices() -> Bool {
|
|
1425
|
-
return GCKCastContext.sharedInstance().discoveryManager.hasDiscoveredDevices
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
func discoveryState() -> GCKDiscoveryState {
|
|
1429
|
-
return GCKCastContext.sharedInstance().discoveryManager.discoveryState
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
func setPassiveScan(passive:Bool) {
|
|
1433
|
-
GCKCastContext.sharedInstance().discoveryManager.passiveScan = passive
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
func castState() -> GCKCastState {
|
|
1437
|
-
return GCKCastContext.sharedInstance().castState
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
func deviceCount() -> UInt {
|
|
1441
|
-
return GCKCastContext.sharedInstance().discoveryManager.deviceCount
|
|
1442
|
-
}
|
|
1443
|
-
|
|
1444
|
-
func getAvailableDevices() -> [JWCastingDevice]! {
|
|
1445
|
-
return castController.availableDevices
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
func connectedDevice() -> JWCastingDevice! {
|
|
1449
|
-
return castController.connectedDevice
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
|
-
func connectToDevice(device:JWCastingDevice!) {
|
|
1453
|
-
return castController.connectToDevice(device)
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
func cast() {
|
|
1457
|
-
return castController.cast()
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
func stopCasting() {
|
|
1461
|
-
return castController.stopCasting()
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
// MARK: - JWPlayer Cast Delegate
|
|
1465
|
-
|
|
1466
|
-
func castController(_ controller: JWCastController, castingBeganWithDevice device: JWCastingDevice) {
|
|
1467
|
-
self.onCasting?([:])
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
|
-
func castController(_ controller:JWCastController, castingEndedWithError error: Error?) {
|
|
1471
|
-
self.onCastingEnded?(["error": error as Any])
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
func castController(_ controller:JWCastController, castingFailedWithError error: Error) {
|
|
1475
|
-
self.onCastingFailed?(["error": error as Any])
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
func castController(_ controller:JWCastController, connectedTo device: JWCastingDevice) {
|
|
1479
|
-
let dict:NSMutableDictionary! = NSMutableDictionary()
|
|
1480
|
-
|
|
1481
|
-
dict.setObject(device.name, forKey:"name" as NSCopying)
|
|
1482
|
-
dict.setObject(device.identifier, forKey:"identifier" as NSCopying)
|
|
1483
|
-
|
|
1484
|
-
do {
|
|
1485
|
-
let data:Data! = try JSONSerialization.data(withJSONObject: dict as Any, options:.prettyPrinted)
|
|
1486
|
-
|
|
1487
|
-
self.onConnectedToCastingDevice?(["device": String(data:data as Data, encoding:String.Encoding.utf8) as Any])
|
|
1488
|
-
} catch {
|
|
1489
|
-
print("Error converting dictionary to JSON data: \(error)")
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
func castController(_ controller:JWCastController, connectionFailedWithError error: Error) {
|
|
1494
|
-
self.onConnectionFailed?(["error": error as Any])
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
func castController(_ controller: JWCastController, connectionRecoveredWithDevice device:JWCastingDevice) {
|
|
1498
|
-
self.onConnectionRecovered?([:])
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
func castController(_ controller: JWCastController, connectionSuspendedWithDevice device: JWCastingDevice) {
|
|
1502
|
-
self.onConnectionTemporarilySuspended?([:])
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
func castController(_ controller: JWCastController, devicesAvailable devices:[JWCastingDevice]) {
|
|
1506
|
-
self.availableDevices = devices
|
|
1507
|
-
|
|
1508
|
-
var devicesInfo: [[String: Any]] = []
|
|
1509
|
-
for device in devices {
|
|
1510
|
-
var dict: [String: Any] = [:]
|
|
1511
|
-
|
|
1512
|
-
dict["name"] = device.name
|
|
1513
|
-
dict["identifier"] = device.identifier
|
|
1514
|
-
|
|
1515
|
-
devicesInfo.append(dict)
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
do {
|
|
1519
|
-
let data:Data! = try JSONSerialization.data(withJSONObject: devicesInfo as Any, options:.prettyPrinted)
|
|
1520
|
-
|
|
1521
|
-
self.onCastingDevicesAvailable?(["devices": String(data:data as Data, encoding:String.Encoding.utf8) as Any])
|
|
1522
|
-
} catch {
|
|
1523
|
-
print("Error converting dictionary to JSON data: \(error)")
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
func castController(_ controller: JWCastController, disconnectedWithError error: (Error)?) {
|
|
1528
|
-
self.onDisconnectedFromCastingDevice?(["error": error as Any])
|
|
1529
|
-
}
|
|
1530
|
-
|
|
1531
1388
|
// MARK: - JWPlayer AV Delegate
|
|
1532
1389
|
|
|
1533
1390
|
func jwplayer(_ player:JWPlayer, audioTracksUpdated levels:[JWMediaSelectionOption]) {
|
|
@@ -1835,3 +1692,152 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
|
|
|
1835
1692
|
}
|
|
1836
1693
|
|
|
1837
1694
|
}
|
|
1695
|
+
|
|
1696
|
+
#if USE_GOOGLE_CAST
|
|
1697
|
+
extension RNJWPlayerView: JWCastDelegate {
|
|
1698
|
+
// pragma Mark - Casting methods
|
|
1699
|
+
func setUpCastController() {
|
|
1700
|
+
if (playerView != nil) && playerView.player as! Bool && (castController == nil) {
|
|
1701
|
+
castController = JWCastController(player:playerView.player)
|
|
1702
|
+
castController.delegate = self
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
self.scanForDevices()
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
func scanForDevices() {
|
|
1709
|
+
if castController != nil {
|
|
1710
|
+
castController.startDiscovery()
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
func stopScanForDevices() {
|
|
1715
|
+
if castController != nil {
|
|
1716
|
+
castController.stopDiscovery()
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
func presentCastDialog() {
|
|
1721
|
+
GCKCastContext.sharedInstance().presentCastDialog()
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
func startDiscovery() {
|
|
1725
|
+
GCKCastContext.sharedInstance().discoveryManager.startDiscovery()
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
func stopDiscovery() {
|
|
1729
|
+
GCKCastContext.sharedInstance().discoveryManager.stopDiscovery()
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
func discoveryActive() -> Bool {
|
|
1733
|
+
return GCKCastContext.sharedInstance().discoveryManager.discoveryActive
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
func hasDiscoveredDevices() -> Bool {
|
|
1737
|
+
return GCKCastContext.sharedInstance().discoveryManager.hasDiscoveredDevices
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
func discoveryState() -> GCKDiscoveryState {
|
|
1741
|
+
return GCKCastContext.sharedInstance().discoveryManager.discoveryState
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
func setPassiveScan(passive:Bool) {
|
|
1745
|
+
GCKCastContext.sharedInstance().discoveryManager.passiveScan = passive
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
func castState() -> GCKCastState {
|
|
1749
|
+
return GCKCastContext.sharedInstance().castState
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
func deviceCount() -> UInt {
|
|
1753
|
+
return GCKCastContext.sharedInstance().discoveryManager.deviceCount
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
func getAvailableDevices() -> [JWCastingDevice]! {
|
|
1757
|
+
return castController.availableDevices
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
func connectedDevice() -> JWCastingDevice! {
|
|
1761
|
+
return castController.connectedDevice
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
func connectToDevice(device:JWCastingDevice!) {
|
|
1765
|
+
return castController.connectToDevice(device)
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
func cast() {
|
|
1769
|
+
return castController.cast()
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
func stopCasting() {
|
|
1773
|
+
return castController.stopCasting()
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
// MARK: - JWPlayer Cast Delegate
|
|
1777
|
+
|
|
1778
|
+
func castController(_ controller: JWCastController, castingBeganWithDevice device: JWCastingDevice) {
|
|
1779
|
+
self.onCasting?([:])
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
func castController(_ controller:JWCastController, castingEndedWithError error: Error?) {
|
|
1783
|
+
self.onCastingEnded?(["error": error as Any])
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
func castController(_ controller:JWCastController, castingFailedWithError error: Error) {
|
|
1787
|
+
self.onCastingFailed?(["error": error as Any])
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
func castController(_ controller:JWCastController, connectedTo device: JWCastingDevice) {
|
|
1791
|
+
let dict:NSMutableDictionary! = NSMutableDictionary()
|
|
1792
|
+
|
|
1793
|
+
dict.setObject(device.name, forKey:"name" as NSCopying)
|
|
1794
|
+
dict.setObject(device.identifier, forKey:"identifier" as NSCopying)
|
|
1795
|
+
|
|
1796
|
+
do {
|
|
1797
|
+
let data:Data! = try JSONSerialization.data(withJSONObject: dict as Any, options:.prettyPrinted)
|
|
1798
|
+
|
|
1799
|
+
self.onConnectedToCastingDevice?(["device": String(data:data as Data, encoding:String.Encoding.utf8) as Any])
|
|
1800
|
+
} catch {
|
|
1801
|
+
print("Error converting dictionary to JSON data: \(error)")
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
func castController(_ controller:JWCastController, connectionFailedWithError error: Error) {
|
|
1806
|
+
self.onConnectionFailed?(["error": error as Any])
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
func castController(_ controller: JWCastController, connectionRecoveredWithDevice device:JWCastingDevice) {
|
|
1810
|
+
self.onConnectionRecovered?([:])
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
func castController(_ controller: JWCastController, connectionSuspendedWithDevice device: JWCastingDevice) {
|
|
1814
|
+
self.onConnectionTemporarilySuspended?([:])
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
func castController(_ controller: JWCastController, devicesAvailable devices:[JWCastingDevice]) {
|
|
1818
|
+
self.availableDevices = devices
|
|
1819
|
+
|
|
1820
|
+
var devicesInfo: [[String: Any]] = []
|
|
1821
|
+
for device in devices {
|
|
1822
|
+
var dict: [String: Any] = [:]
|
|
1823
|
+
|
|
1824
|
+
dict["name"] = device.name
|
|
1825
|
+
dict["identifier"] = device.identifier
|
|
1826
|
+
|
|
1827
|
+
devicesInfo.append(dict)
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
do {
|
|
1831
|
+
let data:Data! = try JSONSerialization.data(withJSONObject: devicesInfo as Any, options:.prettyPrinted)
|
|
1832
|
+
|
|
1833
|
+
self.onCastingDevicesAvailable?(["devices": String(data:data as Data, encoding:String.Encoding.utf8) as Any])
|
|
1834
|
+
} catch {
|
|
1835
|
+
print("Error converting dictionary to JSON data: \(error)")
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
func castController(_ controller: JWCastController, disconnectedWithError error: (Error)?) {
|
|
1840
|
+
self.onDisconnectedFromCastingDevice?(["error": error as Any])
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
#endif
|