@jwplayer/jwplayer-react-native 1.0.2 → 1.1.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.
- package/README.md +1 -0
- package/RNJWPlayer.podspec +3 -3
- 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 +1 -1
- package/android/build.gradle +8 -1
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerModule.java +368 -471
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +226 -56
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +15 -1
- package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +65 -9
- package/badges/version.svg +1 -1
- package/index.d.ts +47 -8
- package/index.js +51 -2
- package/ios/RNJWPlayer/RNJWPlayerView.swift +96 -34
- package/ios/RNJWPlayer/RNJWPlayerViewController.swift +15 -9
- package/ios/RNJWPlayer/RNJWPlayerViewManager.m +8 -1
- package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +244 -166
- package/jwplayer-jwplayer-react-native-v1.1.0.tgz +0 -0
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ package com.jwplayer.rnjwplayer;
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
import android.app.Activity;
|
|
5
|
+
import android.app.ActivityManager;
|
|
5
6
|
import android.content.BroadcastReceiver;
|
|
6
7
|
import android.content.Context;
|
|
7
8
|
import android.content.Intent;
|
|
@@ -18,16 +19,20 @@ import android.os.Build;
|
|
|
18
19
|
import android.os.Handler;
|
|
19
20
|
import android.os.Looper;
|
|
20
21
|
import android.util.Log;
|
|
21
|
-
import android.view.Choreographer;
|
|
22
22
|
import android.view.View;
|
|
23
23
|
import android.view.ViewGroup;
|
|
24
24
|
import android.view.Window;
|
|
25
25
|
import android.view.WindowManager;
|
|
26
|
-
import android.widget.FrameLayout;
|
|
27
26
|
import android.widget.LinearLayout;
|
|
28
27
|
import android.widget.RelativeLayout;
|
|
29
28
|
|
|
29
|
+
import androidx.annotation.NonNull;
|
|
30
30
|
import androidx.appcompat.app.AppCompatActivity;
|
|
31
|
+
import androidx.lifecycle.Lifecycle;
|
|
32
|
+
import androidx.lifecycle.LifecycleEventObserver;
|
|
33
|
+
import androidx.lifecycle.LifecycleObserver;
|
|
34
|
+
import androidx.lifecycle.LifecycleOwner;
|
|
35
|
+
import androidx.lifecycle.LifecycleRegistry;
|
|
31
36
|
|
|
32
37
|
import com.facebook.react.ReactActivity;
|
|
33
38
|
import com.facebook.react.bridge.Arguments;
|
|
@@ -35,15 +40,18 @@ import com.facebook.react.bridge.LifecycleEventListener;
|
|
|
35
40
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
36
41
|
import com.facebook.react.bridge.ReadableArray;
|
|
37
42
|
import com.facebook.react.bridge.ReadableMap;
|
|
43
|
+
import com.facebook.react.bridge.ReadableType;
|
|
44
|
+
import com.facebook.react.bridge.WritableArray;
|
|
38
45
|
import com.facebook.react.bridge.WritableMap;
|
|
39
46
|
import com.facebook.react.common.MapBuilder;
|
|
40
47
|
import com.facebook.react.uimanager.ThemedReactContext;
|
|
41
48
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
42
49
|
import com.google.common.collect.ImmutableMap;
|
|
43
50
|
import com.google.gson.Gson;
|
|
44
|
-
import com.jwplayer.pub.api.JsonHelper;
|
|
45
51
|
import com.jwplayer.pub.api.JWPlayer;
|
|
52
|
+
import com.jwplayer.pub.api.JsonHelper;
|
|
46
53
|
import com.jwplayer.pub.api.UiGroup;
|
|
54
|
+
import com.jwplayer.pub.api.background.MediaService;
|
|
47
55
|
import com.jwplayer.pub.api.background.MediaServiceController;
|
|
48
56
|
import com.jwplayer.pub.api.configuration.PlayerConfig;
|
|
49
57
|
import com.jwplayer.pub.api.configuration.UiConfig;
|
|
@@ -110,9 +118,12 @@ import com.jwplayer.pub.api.fullscreen.delegates.DeviceOrientationDelegate;
|
|
|
110
118
|
import com.jwplayer.pub.api.fullscreen.delegates.DialogLayoutDelegate;
|
|
111
119
|
import com.jwplayer.pub.api.fullscreen.delegates.SystemUiDelegate;
|
|
112
120
|
import com.jwplayer.pub.api.license.LicenseUtil;
|
|
121
|
+
import com.jwplayer.pub.api.media.captions.Caption;
|
|
113
122
|
import com.jwplayer.pub.api.media.playlists.PlaylistItem;
|
|
114
123
|
import com.jwplayer.ui.views.CueMarkerSeekbar;
|
|
115
124
|
|
|
125
|
+
import org.json.JSONObject;
|
|
126
|
+
|
|
116
127
|
import java.util.ArrayList;
|
|
117
128
|
import java.util.Arrays;
|
|
118
129
|
import java.util.HashMap;
|
|
@@ -120,8 +131,6 @@ import java.util.List;
|
|
|
120
131
|
import java.util.Map;
|
|
121
132
|
import java.util.Objects;
|
|
122
133
|
|
|
123
|
-
import org.json.JSONObject;
|
|
124
|
-
|
|
125
134
|
public class RNJWPlayerView extends RelativeLayout implements
|
|
126
135
|
VideoPlayerEvents.OnFullscreenListener,
|
|
127
136
|
VideoPlayerEvents.OnReadyListener,
|
|
@@ -148,6 +157,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
148
157
|
VideoPlayerEvents.OnCaptionsListListener,
|
|
149
158
|
VideoPlayerEvents.OnCaptionsChangedListener,
|
|
150
159
|
VideoPlayerEvents.OnMetaListener,
|
|
160
|
+
VideoPlayerEvents.PlaylistItemCallbackListener,
|
|
151
161
|
|
|
152
162
|
CastingEvents.OnCastListener,
|
|
153
163
|
|
|
@@ -179,7 +189,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
179
189
|
|
|
180
190
|
AudioManager.OnAudioFocusChangeListener,
|
|
181
191
|
|
|
182
|
-
LifecycleEventListener {
|
|
192
|
+
LifecycleEventListener, LifecycleOwner {
|
|
183
193
|
public RNJWPlayer mPlayerView = null;
|
|
184
194
|
public JWPlayer mPlayer = null;
|
|
185
195
|
|
|
@@ -228,9 +238,18 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
228
238
|
private MediaServiceController mMediaServiceController;
|
|
229
239
|
private PipHandlerReceiver mReceiver = null;
|
|
230
240
|
|
|
241
|
+
// Add completion handler field
|
|
242
|
+
PlaylistItemDecision itemUpdatePromise = null;
|
|
243
|
+
|
|
231
244
|
private void doBindService() {
|
|
232
245
|
if (mMediaServiceController != null) {
|
|
233
|
-
|
|
246
|
+
if (!isBackgroundAudioServiceRunning()) {
|
|
247
|
+
// This may not be your expected behavior, but is necessary to avoid crashing
|
|
248
|
+
// Do not use multiple player instances with background audio enabled
|
|
249
|
+
|
|
250
|
+
// don't rebind me if the service is already active with a player.
|
|
251
|
+
mMediaServiceController.bindService();
|
|
252
|
+
}
|
|
234
253
|
}
|
|
235
254
|
}
|
|
236
255
|
|
|
@@ -265,10 +284,23 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
265
284
|
return superContext;
|
|
266
285
|
}
|
|
267
286
|
|
|
287
|
+
private boolean isBackgroundAudioServiceRunning() {
|
|
288
|
+
ActivityManager manager = (ActivityManager) mAppContext.getSystemService(Context.ACTIVITY_SERVICE);
|
|
289
|
+
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
|
290
|
+
if (MediaService.class.getName().equals(service.service.getClassName())) {
|
|
291
|
+
Log.w(TAG, "MediaService is already running with another player loaded. To avoid crashing, this player, "
|
|
292
|
+
+ mPlayerView.getTag() + " will not be loaded into the background service.");
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
|
|
268
299
|
public RNJWPlayerView(ThemedReactContext reactContext, ReactApplicationContext appContext) {
|
|
269
300
|
super(getNonBuggyContext(reactContext, appContext));
|
|
270
301
|
mAppContext = appContext;
|
|
271
302
|
|
|
303
|
+
registry.setCurrentState(Lifecycle.State.CREATED);
|
|
272
304
|
mThemedReactContext = reactContext;
|
|
273
305
|
|
|
274
306
|
mActivity = (ReactActivity) getActivity();
|
|
@@ -276,11 +308,25 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
276
308
|
mWindow = mActivity.getWindow();
|
|
277
309
|
}
|
|
278
310
|
|
|
311
|
+
if (mActivity != null) {
|
|
312
|
+
mActivity.getLifecycle().addObserver(lifecycleObserver);
|
|
313
|
+
}
|
|
314
|
+
|
|
279
315
|
mRootView = mActivity.findViewById(android.R.id.content);
|
|
280
316
|
|
|
281
317
|
getReactContext().addLifecycleEventListener(this);
|
|
282
318
|
}
|
|
283
319
|
|
|
320
|
+
private LifecycleObserver lifecycleObserver = new LifecycleEventObserver() {
|
|
321
|
+
@Override
|
|
322
|
+
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
|
|
323
|
+
if (event.getTargetState() == Lifecycle.State.DESTROYED) {
|
|
324
|
+
return; // no op: handled elsewhere
|
|
325
|
+
}
|
|
326
|
+
registry.setCurrentState(event.getTargetState());
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
|
|
284
330
|
public ReactApplicationContext getAppContext() {
|
|
285
331
|
return mAppContext;
|
|
286
332
|
}
|
|
@@ -303,12 +349,44 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
303
349
|
return mThemedReactContext.getReactApplicationContext().getCurrentActivity();
|
|
304
350
|
}
|
|
305
351
|
|
|
352
|
+
// The registry for lifecycle events. Required by player object. Main use case if for garbage collection / teardown
|
|
353
|
+
private final LifecycleRegistry registry = new LifecycleRegistry(this);
|
|
354
|
+
|
|
355
|
+
@NonNull
|
|
356
|
+
@Override
|
|
357
|
+
public Lifecycle getLifecycle() {
|
|
358
|
+
return registry;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// // closest to `ondestroy` for a view without listening to the activity event
|
|
362
|
+
// // The activity event can be deceptive in React-Native
|
|
363
|
+
// @Override
|
|
364
|
+
// protected void onDetachedFromWindow() {
|
|
365
|
+
// super.onDetachedFromWindow();
|
|
366
|
+
// registry.setCurrentState(Lifecycle.State.DESTROYED);
|
|
367
|
+
// }
|
|
368
|
+
|
|
306
369
|
public void destroyPlayer() {
|
|
307
370
|
if (mPlayer != null) {
|
|
308
371
|
unRegisterReceiver();
|
|
309
|
-
|
|
372
|
+
|
|
373
|
+
// If we are casting we need to break the cast session as there is no simple
|
|
374
|
+
// way to reconnect to an existing session if the player that created it is dead
|
|
375
|
+
|
|
376
|
+
// If this doesn't match your use case, using a single player object and load content
|
|
377
|
+
// into it rather than creating a new player for every piece of content.
|
|
310
378
|
mPlayer.stop();
|
|
311
379
|
|
|
380
|
+
// send signal to JW SDK player is destroyed
|
|
381
|
+
registry.setCurrentState(Lifecycle.State.DESTROYED);
|
|
382
|
+
|
|
383
|
+
// Stop listening to activities lifecycle
|
|
384
|
+
mActivity.getLifecycle().removeObserver(lifecycleObserver);
|
|
385
|
+
mPlayer.deregisterActivityForPip();
|
|
386
|
+
|
|
387
|
+
// Remove playlist item callback listener
|
|
388
|
+
mPlayer.removePlaylistItemCallbackListener();
|
|
389
|
+
|
|
312
390
|
mPlayer.removeListeners(this,
|
|
313
391
|
// VideoPlayerEvents
|
|
314
392
|
EventType.READY,
|
|
@@ -386,7 +464,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
386
464
|
}
|
|
387
465
|
}
|
|
388
466
|
|
|
389
|
-
public void setupPlayerView(Boolean backgroundAudioEnabled) {
|
|
467
|
+
public void setupPlayerView(Boolean backgroundAudioEnabled, Boolean playlistItemCallbackEnabled) {
|
|
390
468
|
if (mPlayer != null) {
|
|
391
469
|
|
|
392
470
|
mPlayer.addListeners(this,
|
|
@@ -400,6 +478,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
400
478
|
EventType.SETUP_ERROR,
|
|
401
479
|
EventType.BUFFER,
|
|
402
480
|
EventType.TIME,
|
|
481
|
+
EventType.AUDIO_TRACKS,
|
|
482
|
+
EventType.AUDIO_TRACK_CHANGED,
|
|
403
483
|
EventType.PLAYLIST,
|
|
404
484
|
EventType.PLAYLIST_ITEM,
|
|
405
485
|
EventType.PLAYLIST_COMPLETE,
|
|
@@ -449,13 +529,38 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
449
529
|
} else {
|
|
450
530
|
mPlayer.setFullscreenHandler(new fullscreenHandler());
|
|
451
531
|
}
|
|
452
|
-
|
|
453
532
|
mPlayer.allowBackgroundAudio(backgroundAudioEnabled);
|
|
533
|
+
|
|
534
|
+
if (playlistItemCallbackEnabled) {
|
|
535
|
+
mPlayer.setPlaylistItemCallbackListener(this);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
public void resolveNextPlaylistItem(ReadableMap playlistItem) {
|
|
541
|
+
if (itemUpdatePromise == null) {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
if (playlistItem == null) {
|
|
546
|
+
itemUpdatePromise.continuePlayback();
|
|
547
|
+
itemUpdatePromise = null;
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
try {
|
|
552
|
+
PlaylistItem updatedPlaylistItem = Util.getPlaylistItem(playlistItem);
|
|
553
|
+
itemUpdatePromise.modify(updatedPlaylistItem);
|
|
554
|
+
} catch (Exception exception) {
|
|
555
|
+
itemUpdatePromise.continuePlayback();
|
|
454
556
|
}
|
|
557
|
+
|
|
558
|
+
itemUpdatePromise = null;
|
|
455
559
|
}
|
|
456
560
|
|
|
457
561
|
/**
|
|
458
562
|
* Helper to build the a generic `ExtensibleFullscreenHandler` with small tweaks to play nice with Modals
|
|
563
|
+
*
|
|
459
564
|
* @return {@link ExtensibleFullscreenHandler}
|
|
460
565
|
*/
|
|
461
566
|
private ExtensibleFullscreenHandler createModalFullscreenHandler() {
|
|
@@ -554,6 +659,18 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
554
659
|
return delegate;
|
|
555
660
|
}
|
|
556
661
|
|
|
662
|
+
@Override
|
|
663
|
+
public void onBeforeNextPlaylistItem(PlaylistItemDecision playlistItemDecision, PlaylistItem nextItem, int indexOfNextItem) {
|
|
664
|
+
WritableMap event = Arguments.createMap();
|
|
665
|
+
Gson gson = new Gson();
|
|
666
|
+
event.putString("message", "onBeforeNextPlaylistItem");
|
|
667
|
+
event.putInt("index", indexOfNextItem);
|
|
668
|
+
event.putString("playlistItem", gson.toJson(nextItem));
|
|
669
|
+
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topBeforeNextPlaylistItem", event);
|
|
670
|
+
|
|
671
|
+
itemUpdatePromise = playlistItemDecision;
|
|
672
|
+
}
|
|
673
|
+
|
|
557
674
|
private class fullscreenHandler implements FullscreenHandler {
|
|
558
675
|
ViewGroup mPlayerViewContainer = (ViewGroup) mPlayerView.getParent();
|
|
559
676
|
private View mDecorView;
|
|
@@ -622,6 +739,9 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
622
739
|
mPlayerViewContainer.post(new Runnable() {
|
|
623
740
|
@Override
|
|
624
741
|
public void run() {
|
|
742
|
+
// View may not have been removed properly (especially if returning from PiP)
|
|
743
|
+
mPlayerViewContainer.removeView(mPlayerView);
|
|
744
|
+
|
|
625
745
|
mPlayerViewContainer.addView(mPlayerView, new ViewGroup.LayoutParams(
|
|
626
746
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
627
747
|
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
@@ -714,6 +834,11 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
714
834
|
mPlayer.setForceControlsVisibility(true);
|
|
715
835
|
mPlayer.setForceControlsVisibility(false);
|
|
716
836
|
|
|
837
|
+
// If player was in fullscreen when going into PiP, we need to force it back out
|
|
838
|
+
if (mPlayer.getFullscreen()) {
|
|
839
|
+
mPlayer.setFullscreen(false, true);
|
|
840
|
+
}
|
|
841
|
+
|
|
717
842
|
// Strip player view
|
|
718
843
|
rootView.removeView(mPlayerView);
|
|
719
844
|
|
|
@@ -822,7 +947,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
822
947
|
return differences.size() == 1 && differences.containsKey(keyName);
|
|
823
948
|
}
|
|
824
949
|
|
|
825
|
-
boolean playlistNotTheSame(ReadableMap prop) {
|
|
950
|
+
private boolean playlistNotTheSame(ReadableMap prop) {
|
|
826
951
|
return prop.hasKey("playlist") && mPlaylistProp != prop.getArray("playlist") && !Arrays
|
|
827
952
|
.deepEquals(new ReadableArray[]{mPlaylistProp}, new ReadableArray[]{prop.getArray("playlist")});
|
|
828
953
|
}
|
|
@@ -834,6 +959,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
834
959
|
JSONObject obj;
|
|
835
960
|
PlayerConfig jwConfig = null;
|
|
836
961
|
Boolean forceLegacy = prop.hasKey("forceLegacyConfig") ? prop.getBoolean("forceLegacyConfig") : false;
|
|
962
|
+
Boolean playlistItemCallbackEnabled = prop.hasKey("playlistItemCallbackEnabled") ? prop.getBoolean("playlistItemCallbackEnabled") : false;
|
|
837
963
|
Boolean isJwConfig = false;
|
|
838
964
|
if (!forceLegacy) {
|
|
839
965
|
try {
|
|
@@ -940,9 +1066,11 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
940
1066
|
ReadableArray uiGroupsArray = prop.getArray("hideUIGroups");
|
|
941
1067
|
UiConfig.Builder hideConfigBuilder = new UiConfig.Builder().displayAllControls();
|
|
942
1068
|
for (int i = 0; i < uiGroupsArray.size(); i++) {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1069
|
+
if (uiGroupsArray.getType(i) == ReadableType.String) {
|
|
1070
|
+
UiGroup uiGroup = GROUP_TYPES.get(uiGroupsArray.getString(i));
|
|
1071
|
+
if (uiGroup != null) {
|
|
1072
|
+
hideConfigBuilder.hide(uiGroup);
|
|
1073
|
+
}
|
|
946
1074
|
}
|
|
947
1075
|
}
|
|
948
1076
|
UiConfig hideJwControlbarUiConfig = hideConfigBuilder.build();
|
|
@@ -966,6 +1094,11 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
966
1094
|
LinearLayout.LayoutParams.MATCH_PARENT));
|
|
967
1095
|
addView(mPlayerView);
|
|
968
1096
|
|
|
1097
|
+
// Ensure we have a valid state before applying to the player
|
|
1098
|
+
registry.setCurrentState(registry.getCurrentState()); // This is a hack to ensure player and view know the lifecycle state
|
|
1099
|
+
|
|
1100
|
+
mPlayer = mPlayerView.getPlayer(this);
|
|
1101
|
+
|
|
969
1102
|
if (prop.hasKey("controls")) { // Hack for controls hiding not working right away
|
|
970
1103
|
mPlayerView.getPlayer().setControls(prop.getBoolean("controls"));
|
|
971
1104
|
}
|
|
@@ -992,8 +1125,6 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
992
1125
|
mPlayerView.exitFullScreenOnPortrait = exitFullScreenOnPortrait;
|
|
993
1126
|
}
|
|
994
1127
|
|
|
995
|
-
mPlayer = mPlayerView.getPlayer();
|
|
996
|
-
|
|
997
1128
|
if (isJwConfig) {
|
|
998
1129
|
mPlayer.setup(jwConfig);
|
|
999
1130
|
} else {
|
|
@@ -1015,7 +1146,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1015
1146
|
// Legacy
|
|
1016
1147
|
// This isn't the ideal way to do this on Android. All drawables/colors/themes shoudld
|
|
1017
1148
|
// be targed using styling. See `https://docs.jwplayer.com/players/docs/android-styling-guide`
|
|
1018
|
-
// for more information on how best to override the JWP styles using XML. If you are unsure of a
|
|
1149
|
+
// for more information on how best to override the JWP styles using XML. If you are unsure of a
|
|
1019
1150
|
// color/drawable/theme, open an `Ask` issue.
|
|
1020
1151
|
if (mColors != null) {
|
|
1021
1152
|
if (mColors.hasKey("backgroundColor")) {
|
|
@@ -1068,12 +1199,10 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1068
1199
|
backgroundAudioEnabled = prop.getBoolean("backgroundAudioEnabled");
|
|
1069
1200
|
}
|
|
1070
1201
|
|
|
1071
|
-
setupPlayerView(backgroundAudioEnabled);
|
|
1202
|
+
setupPlayerView(backgroundAudioEnabled, playlistItemCallbackEnabled);
|
|
1072
1203
|
|
|
1073
1204
|
if (backgroundAudioEnabled) {
|
|
1074
1205
|
audioManager = (AudioManager) simpleContext.getSystemService(Context.AUDIO_SERVICE);
|
|
1075
|
-
// Throws a fatal error if using a playlistURL instead of manually created playlist
|
|
1076
|
-
// Related to SDK-11346
|
|
1077
1206
|
mMediaServiceController = new MediaServiceController.Builder((AppCompatActivity) mActivity, mPlayer)
|
|
1078
1207
|
.build();
|
|
1079
1208
|
}
|
|
@@ -1232,7 +1361,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1232
1361
|
public void onAdLoaded(AdLoadedEvent adLoadedEvent) {
|
|
1233
1362
|
WritableMap event = Arguments.createMap();
|
|
1234
1363
|
event.putString("message", "onAdEvent");
|
|
1235
|
-
event.
|
|
1364
|
+
event.putInt("client", Util.getAdEventClientValue(adLoadedEvent));
|
|
1236
1365
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1237
1366
|
}
|
|
1238
1367
|
|
|
@@ -1240,7 +1369,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1240
1369
|
public void onAdLoadedXml(AdLoadedXmlEvent adLoadedXmlEvent) {
|
|
1241
1370
|
WritableMap event = Arguments.createMap();
|
|
1242
1371
|
event.putString("message", "onAdEvent");
|
|
1243
|
-
event.
|
|
1372
|
+
event.putInt("client", Util.getAdEventClientValue(adLoadedXmlEvent));
|
|
1244
1373
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1245
1374
|
}
|
|
1246
1375
|
|
|
@@ -1249,7 +1378,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1249
1378
|
WritableMap event = Arguments.createMap();
|
|
1250
1379
|
event.putString("message", "onAdEvent");
|
|
1251
1380
|
event.putString("reason", adPauseEvent.getAdPauseReason().toString());
|
|
1252
|
-
event.putInt("
|
|
1381
|
+
event.putInt("client", Util.getAdEventClientValue(adPauseEvent));
|
|
1382
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypePause));
|
|
1253
1383
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1254
1384
|
}
|
|
1255
1385
|
|
|
@@ -1258,7 +1388,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1258
1388
|
WritableMap event = Arguments.createMap();
|
|
1259
1389
|
event.putString("message", "onAdEvent");
|
|
1260
1390
|
event.putString("reason", adPlayEvent.getAdPlayReason().toString());
|
|
1261
|
-
event.putInt("
|
|
1391
|
+
event.putInt("client", Util.getAdEventClientValue(adPlayEvent));
|
|
1392
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypePlay));
|
|
1262
1393
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1263
1394
|
}
|
|
1264
1395
|
|
|
@@ -1266,8 +1397,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1266
1397
|
public void onAdBreakEnd(AdBreakEndEvent adBreakEndEvent) {
|
|
1267
1398
|
WritableMap event = Arguments.createMap();
|
|
1268
1399
|
event.putString("message", "onAdEvent");
|
|
1269
|
-
event.
|
|
1270
|
-
event.putInt("type", Util.
|
|
1400
|
+
event.putInt("client", Util.getAdEventClientValue(adBreakEndEvent));
|
|
1401
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeAdBreakEnd));
|
|
1271
1402
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1272
1403
|
}
|
|
1273
1404
|
|
|
@@ -1275,8 +1406,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1275
1406
|
public void onAdBreakStart(AdBreakStartEvent adBreakStartEvent) {
|
|
1276
1407
|
WritableMap event = Arguments.createMap();
|
|
1277
1408
|
event.putString("message", "onAdEvent");
|
|
1278
|
-
event.
|
|
1279
|
-
event.putInt("type", Util.
|
|
1409
|
+
event.putInt("client", Util.getAdEventClientValue(adBreakStartEvent));
|
|
1410
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeAdBreakStart));
|
|
1280
1411
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1281
1412
|
}
|
|
1282
1413
|
|
|
@@ -1284,7 +1415,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1284
1415
|
public void onAdBreakIgnored(AdBreakIgnoredEvent adBreakIgnoredEvent) {
|
|
1285
1416
|
WritableMap event = Arguments.createMap();
|
|
1286
1417
|
event.putString("message", "onAdEvent");
|
|
1287
|
-
event.
|
|
1418
|
+
event.putInt("client", Util.getAdEventClientValue(adBreakIgnoredEvent));
|
|
1288
1419
|
// missing type code
|
|
1289
1420
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1290
1421
|
}
|
|
@@ -1293,8 +1424,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1293
1424
|
public void onAdClick(AdClickEvent adClickEvent) {
|
|
1294
1425
|
WritableMap event = Arguments.createMap();
|
|
1295
1426
|
event.putString("message", "onAdEvent");
|
|
1296
|
-
event.
|
|
1297
|
-
event.putInt("type", Util.
|
|
1427
|
+
event.putInt("client", Util.getAdEventClientValue(adClickEvent));
|
|
1428
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeClicked));
|
|
1298
1429
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1299
1430
|
}
|
|
1300
1431
|
|
|
@@ -1302,7 +1433,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1302
1433
|
public void onAdCompanions(AdCompanionsEvent adCompanionsEvent) {
|
|
1303
1434
|
WritableMap event = Arguments.createMap();
|
|
1304
1435
|
event.putString("message", "onAdEvent");
|
|
1305
|
-
event.putInt("
|
|
1436
|
+
event.putInt("client", Util.getAdEventClientValue(adCompanionsEvent));
|
|
1437
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeCompanion));
|
|
1306
1438
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1307
1439
|
}
|
|
1308
1440
|
|
|
@@ -1310,8 +1442,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1310
1442
|
public void onAdComplete(AdCompleteEvent adCompleteEvent) {
|
|
1311
1443
|
WritableMap event = Arguments.createMap();
|
|
1312
1444
|
event.putString("message", "onAdEvent");
|
|
1313
|
-
event.
|
|
1314
|
-
event.putInt("type", Util.
|
|
1445
|
+
event.putInt("client", Util.getAdEventClientValue(adCompleteEvent));
|
|
1446
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeComplete));
|
|
1315
1447
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1316
1448
|
}
|
|
1317
1449
|
|
|
@@ -1331,7 +1463,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1331
1463
|
event.putString("message", "onPlayerAdWarning");
|
|
1332
1464
|
event.putInt("code", adWarningEvent.getCode());
|
|
1333
1465
|
event.putInt("adErrorCode", adWarningEvent.getAdErrorCode());
|
|
1334
|
-
event.putString("
|
|
1466
|
+
event.putString("warning", adWarningEvent.getMessage());
|
|
1335
1467
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topPlayerAdWarning", event);
|
|
1336
1468
|
}
|
|
1337
1469
|
|
|
@@ -1339,8 +1471,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1339
1471
|
public void onAdImpression(AdImpressionEvent adImpressionEvent) {
|
|
1340
1472
|
WritableMap event = Arguments.createMap();
|
|
1341
1473
|
event.putString("message", "onAdEvent");
|
|
1342
|
-
event.
|
|
1343
|
-
event.putInt("type", Util.
|
|
1474
|
+
event.putInt("client", Util.getAdEventClientValue(adImpressionEvent));
|
|
1475
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeImpression));
|
|
1344
1476
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1345
1477
|
}
|
|
1346
1478
|
|
|
@@ -1348,8 +1480,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1348
1480
|
public void onAdMeta(AdMetaEvent adMetaEvent) {
|
|
1349
1481
|
WritableMap event = Arguments.createMap();
|
|
1350
1482
|
event.putString("message", "onAdEvent");
|
|
1351
|
-
event.
|
|
1352
|
-
event.putInt("type", Util.
|
|
1483
|
+
event.putInt("client", Util.getAdEventClientValue(adMetaEvent));
|
|
1484
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeMeta));
|
|
1353
1485
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1354
1486
|
}
|
|
1355
1487
|
|
|
@@ -1357,8 +1489,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1357
1489
|
public void onAdRequest(AdRequestEvent adRequestEvent) {
|
|
1358
1490
|
WritableMap event = Arguments.createMap();
|
|
1359
1491
|
event.putString("message", "onAdEvent");
|
|
1360
|
-
event.
|
|
1361
|
-
event.putInt("type", Util.
|
|
1492
|
+
event.putInt("client", Util.getAdEventClientValue(adRequestEvent));
|
|
1493
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeRequest));
|
|
1362
1494
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1363
1495
|
}
|
|
1364
1496
|
|
|
@@ -1366,8 +1498,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1366
1498
|
public void onAdSchedule(AdScheduleEvent adScheduleEvent) {
|
|
1367
1499
|
WritableMap event = Arguments.createMap();
|
|
1368
1500
|
event.putString("message", "onAdEvent");
|
|
1369
|
-
event.
|
|
1370
|
-
event.putInt("type", Util.
|
|
1501
|
+
event.putInt("client", Util.getAdEventClientValue(adScheduleEvent));
|
|
1502
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeSchedule));
|
|
1371
1503
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1372
1504
|
}
|
|
1373
1505
|
|
|
@@ -1375,8 +1507,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1375
1507
|
public void onAdSkipped(AdSkippedEvent adSkippedEvent) {
|
|
1376
1508
|
WritableMap event = Arguments.createMap();
|
|
1377
1509
|
event.putString("message", "onAdEvent");
|
|
1378
|
-
event.
|
|
1379
|
-
event.putInt("type", Util.
|
|
1510
|
+
event.putInt("client", Util.getAdEventClientValue(adSkippedEvent));
|
|
1511
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeSkipped));
|
|
1380
1512
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1381
1513
|
}
|
|
1382
1514
|
|
|
@@ -1384,7 +1516,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1384
1516
|
public void onAdStarted(AdStartedEvent adStartedEvent) {
|
|
1385
1517
|
WritableMap event = Arguments.createMap();
|
|
1386
1518
|
event.putString("message", "onAdEvent");
|
|
1387
|
-
event.putInt("
|
|
1519
|
+
event.putInt("client", Util.getAdEventClientValue(adStartedEvent));
|
|
1520
|
+
event.putInt("type", Util.getAdEventTypeValue(Util.AdEventType.JWAdEventTypeStarted));
|
|
1388
1521
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topAdEvent", event);
|
|
1389
1522
|
}
|
|
1390
1523
|
|
|
@@ -1437,6 +1570,38 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1437
1570
|
|
|
1438
1571
|
}
|
|
1439
1572
|
|
|
1573
|
+
// Captions Events
|
|
1574
|
+
|
|
1575
|
+
@Override
|
|
1576
|
+
public void onCaptionsChanged(CaptionsChangedEvent captionsChangedEvent) {
|
|
1577
|
+
WritableMap event = Arguments.createMap();
|
|
1578
|
+
event.putString("message", "onCaptionsChanged");
|
|
1579
|
+
event.putInt("index", captionsChangedEvent.getCurrentTrack());
|
|
1580
|
+
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topCaptionsChanged", event);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
@Override
|
|
1584
|
+
public void onCaptionsList(CaptionsListEvent captionsListEvent) {
|
|
1585
|
+
WritableMap event = Arguments.createMap();
|
|
1586
|
+
List<Caption> captionTrackList = captionsListEvent.getCaptions();
|
|
1587
|
+
WritableArray captionTracks = Arguments.createArray();
|
|
1588
|
+
if (captionTrackList != null) {
|
|
1589
|
+
for(int i = 0; i < captionTrackList.size(); i++) {
|
|
1590
|
+
WritableMap captionTrack = Arguments.createMap();
|
|
1591
|
+
Caption track = captionTrackList.get(i);
|
|
1592
|
+
captionTrack.putString("file", track.getFile());
|
|
1593
|
+
captionTrack.putString("label", track.getLabel());
|
|
1594
|
+
captionTrack.putBoolean("default", track.isDefault());
|
|
1595
|
+
captionTracks.pushMap(captionTrack);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
event.putString("message", "onCaptionsList");
|
|
1599
|
+
event.putInt("index", captionsListEvent.getCurrentCaptionIndex());
|
|
1600
|
+
event.putArray("tracks", captionTracks);
|
|
1601
|
+
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topCaptionsList", event);
|
|
1602
|
+
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1440
1605
|
// Player Events
|
|
1441
1606
|
|
|
1442
1607
|
@Override
|
|
@@ -1485,6 +1650,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1485
1650
|
if (ex != null) {
|
|
1486
1651
|
event.putString("error", ex.toString());
|
|
1487
1652
|
event.putString("description", errorEvent.getMessage());
|
|
1653
|
+
event.putInt("errorCode", errorEvent.getErrorCode());
|
|
1488
1654
|
}
|
|
1489
1655
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topPlayerError", event);
|
|
1490
1656
|
|
|
@@ -1635,6 +1801,8 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1635
1801
|
public void onSetupError(SetupErrorEvent setupErrorEvent) {
|
|
1636
1802
|
WritableMap event = Arguments.createMap();
|
|
1637
1803
|
event.putString("message", "onSetupError");
|
|
1804
|
+
event.putString("errorMessage", setupErrorEvent.getMessage());
|
|
1805
|
+
event.putInt("errorCode", setupErrorEvent.getCode());
|
|
1638
1806
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topSetupPlayerError", event);
|
|
1639
1807
|
|
|
1640
1808
|
updateWakeLock(false);
|
|
@@ -1649,16 +1817,6 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1649
1817
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topTime", event);
|
|
1650
1818
|
}
|
|
1651
1819
|
|
|
1652
|
-
@Override
|
|
1653
|
-
public void onCaptionsChanged(CaptionsChangedEvent captionsChangedEvent) {
|
|
1654
|
-
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
@Override
|
|
1658
|
-
public void onCaptionsList(CaptionsListEvent captionsListEvent) {
|
|
1659
|
-
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
1820
|
@Override
|
|
1663
1821
|
public void onMeta(MetaEvent metaEvent) {
|
|
1664
1822
|
|
|
@@ -1678,6 +1836,17 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1678
1836
|
|
|
1679
1837
|
// Casting events
|
|
1680
1838
|
|
|
1839
|
+
private boolean mIsCastActive = false;
|
|
1840
|
+
|
|
1841
|
+
/**
|
|
1842
|
+
* Get if this player-view is currently casting
|
|
1843
|
+
*
|
|
1844
|
+
* @return true if casting
|
|
1845
|
+
*/
|
|
1846
|
+
public boolean getIsCastActive() {
|
|
1847
|
+
return mIsCastActive;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1681
1850
|
@Override
|
|
1682
1851
|
public void onCast(CastEvent castEvent) {
|
|
1683
1852
|
WritableMap event = Arguments.createMap();
|
|
@@ -1686,6 +1855,7 @@ public class RNJWPlayerView extends RelativeLayout implements
|
|
|
1686
1855
|
event.putBoolean("active", castEvent.isActive());
|
|
1687
1856
|
event.putBoolean("available", castEvent.isAvailable());
|
|
1688
1857
|
getReactContext().getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topCasting", event);
|
|
1858
|
+
mIsCastActive = castEvent.isActive();
|
|
1689
1859
|
// stop/start the background audio service if it's running and we're casting
|
|
1690
1860
|
if (castEvent.isActive()) {
|
|
1691
1861
|
doUnbindService();
|