@applicaster/quick-brick-player 12.0.0-alpha.5895113034 → 12.0.0-alpha.6115034951

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-player",
3
- "version": "12.0.0-alpha.5895113034",
3
+ "version": "12.0.0-alpha.6115034951",
4
4
  "description": "Quick Brick Player",
5
5
  "main": "./src/index.ts",
6
6
  "types": "index.d.ts",
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "homepage": "https://github.com/applicaster/quickbrick#readme",
38
38
  "dependencies": {
39
- "@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.68",
40
- "@applicaster/quick-brick-tv-transport-controls": "12.0.0-alpha.5895113034",
41
- "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5895113034",
42
- "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5895113034",
43
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5895113034",
39
+ "@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.83",
40
+ "@applicaster/quick-brick-tv-transport-controls": "12.0.0-rc.83",
41
+ "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.6115034951",
42
+ "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.6115034951",
43
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.6115034951",
44
44
  "keymirror": "^0.1.1",
45
45
  "query-string": "7.1.3",
46
46
  "react-native-web-linear-gradient": "1.1.2",
@@ -388,6 +388,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
388
388
  <AnimationComponent
389
389
  animationType={ComponentAnimationType.moveUpComponent}
390
390
  additionalData={{ saveArea: true }}
391
+ style={Styles.playerContainer}
391
392
  >
392
393
  <AnimatedScrollModal>
393
394
  <View style={Styles.playerContainer} onLayout={onLayout}>
@@ -4,7 +4,7 @@
4
4
  import React from "react";
5
5
  import * as R from "ramda";
6
6
 
7
- import { findNodeHandle, NativeModules, StyleSheet, View } from "react-native";
7
+ import { findNodeHandle, StyleSheet, View } from "react-native";
8
8
  import TransportControlsMobile from "@applicaster/quick-brick-mobile-transport-controls";
9
9
  import TransportControlsTV from "@applicaster/quick-brick-tv-transport-controls";
10
10
 
@@ -21,8 +21,14 @@ import { PlayerWrapper } from "@applicaster/zapp-react-native-ui-components/Comp
21
21
 
22
22
  import { PlayNextOverlay } from "./PlayNextOverlay";
23
23
  import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
24
+ import { AnalyticsTracker } from "@applicaster/zapp-react-native-utils/analyticsUtils/analyticsTracker";
24
25
 
25
- import { GENERAL_EVENT } from "@applicaster/zapp-react-native-utils/analyticsUtils/events";
26
+ import {
27
+ AD_EVENT,
28
+ GENERAL_EVENT,
29
+ PLAYBACK_EVENT,
30
+ QOS_EVENT,
31
+ } from "@applicaster/zapp-react-native-utils/analyticsUtils/events";
26
32
  import { Categories, createLogger, Subsystem } from "../logger";
27
33
  import { parseLanguageTracks } from "@applicaster/zapp-react-native-utils/playerUtils/configurationUtils";
28
34
  import { DEFAULT_COLORS, SEEK_TIME } from "../utils/const";
@@ -36,17 +42,7 @@ import {
36
42
  AnimationComponent,
37
43
  ComponentAnimationType,
38
44
  } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
39
- import { PlayerAnalyticsManager } from "@applicaster/zapp-react-native-utils/analyticsUtils/PlayerAnalyticsManager";
40
- import { PlayerAnalyticsTrackerI } from "@applicaster/zapp-react-native-utils/analyticsUtils/playerAnalyticsTracker";
41
-
42
- const RNPlayerManager = {
43
- QuickBrickPlayerPlugin: isApplePlatform()
44
- ? NativeModules.PlayerModule
45
- : NativeModules.QuickBrickDefaultPlayerModule,
46
- KalturaPlayerPlugin: isApplePlatform()
47
- ? NativeModules.KalturaPlayerModule
48
- : NativeModules.QBKalturaPlayerModule,
49
- };
45
+ import { RNPlayerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/nativePlayerManager";
50
46
 
51
47
  const styles = StyleSheet.create({
52
48
  container: { flex: 1 },
@@ -71,6 +67,7 @@ export default class VideoPlayer extends React.Component<
71
67
  > {
72
68
  public static propTypes = {};
73
69
  _root: any;
70
+ analyticsTracker: AnalyticsTracker;
74
71
  playerPluginId: string;
75
72
  takeParentStyle: Record<any, any>;
76
73
  playbackStarted = false;
@@ -101,17 +98,6 @@ export default class VideoPlayer extends React.Component<
101
98
  duration: 0,
102
99
  };
103
100
 
104
- private _tracker: PlayerAnalyticsTrackerI;
105
- get analyticsTracker() {
106
- if (!this._tracker) {
107
- this._tracker = PlayerAnalyticsManager.getInstance().getTracker(
108
- this.props.playerId
109
- );
110
- }
111
-
112
- return this._tracker;
113
- }
114
-
115
101
  constructor(props) {
116
102
  super(props);
117
103
  this.onVideoLoadCalled = false; // android
@@ -120,15 +106,14 @@ export default class VideoPlayer extends React.Component<
120
106
  ? { width: "100%", flex: "1 1 auto", objectFit: "contain" }
121
107
  : { flexBasis: "auto", flexGrow: 1, flexShrink: 1 };
122
108
 
109
+ const entry = this.props?.entry;
110
+ this.analyticsTracker = new AnalyticsTracker(entry);
123
111
  this.playerPluginId = this.props?.playerPluginIdentifier;
124
112
  }
125
113
 
126
114
  componentWillUnmount() {
127
- this.stopBackgroundPlayback();
128
-
129
115
  this.playbackStarted = false;
130
-
131
- this.analyticsTracker.handleAnalyticEvent(GENERAL_EVENT.session_end);
116
+ this.handleAnalyticEvent(GENERAL_EVENT.session_end);
132
117
  this.onPlayerClosed();
133
118
 
134
119
  if (isAndroidPlatform()) {
@@ -171,6 +156,11 @@ export default class VideoPlayer extends React.Component<
171
156
  }
172
157
  }
173
158
 
159
+ // For close button
160
+ public closeNativePlayer = () => {
161
+ this.stopBackgroundPlayback();
162
+ };
163
+
174
164
  getPlayNextData = () => this.props.playNextData as PlayNextData;
175
165
 
176
166
  /**
@@ -184,6 +174,27 @@ export default class VideoPlayer extends React.Component<
184
174
  return this.props.pluginConfiguration;
185
175
  };
186
176
 
177
+ /**
178
+ * Handles analytic events, generates a new analytics tracker and transmits events
179
+ * Passes entry data, and playerState to the tracker for additional context
180
+ * The end result is an event formatted and passed to AnalyticsBridge.postEvent
181
+ * When we get the synthetic event we need to pull the data in the nativeEvent object
182
+ * nativeEvent contains the return value from native
183
+ */
184
+ handleAnalyticEvent = (event, data = {}) => {
185
+ const entry = this.props?.entry;
186
+ const playerState = this.getState();
187
+
188
+ if (this.analyticsTracker?.handleAnalyticEvent) {
189
+ this.analyticsTracker?.handleAnalyticEvent?.(
190
+ event,
191
+ { ...data, player_type: this.props.playerPluginIdentifier },
192
+ entry,
193
+ playerState
194
+ );
195
+ }
196
+ };
197
+
187
198
  /**
188
199
  * This method is for the events that have no implementation in react but are being invoked by native
189
200
  * When we get the synthetic event we need to pull the data in the nativeEvent object
@@ -324,11 +335,7 @@ export default class VideoPlayer extends React.Component<
324
335
  }
325
336
  };
326
337
 
327
- /**
328
- * Sets either subtitle language, or audio language if we have a selected a new locale.
329
- * If no locale is set it defaults to system language for audio, and leaves subtitles unaltered.
330
- */
331
- setLanguage = (selected = null) => {
338
+ selectTrack = (selected) => {
332
339
  const { trackType, id, language } = selected || {};
333
340
 
334
341
  const isOff = language === "Off";
@@ -387,16 +394,28 @@ export default class VideoPlayer extends React.Component<
387
394
  };
388
395
 
389
396
  onPlayerPresented = () => {
390
- this.analyticsTracker?.handleAnalyticEvent(GENERAL_EVENT.player_presented);
397
+ this.handleAnalyticEvent(GENERAL_EVENT.player_presented);
391
398
  };
392
399
 
393
400
  onPlayerClosed = () => {
394
- this.analyticsTracker?.handleAnalyticEvent(GENERAL_EVENT.player_closed);
401
+ this.handleAnalyticEvent(GENERAL_EVENT.player_closed);
402
+ };
403
+
404
+ onPlayerSessionEnd = () => {
405
+ // TODO: Implement method on native android, ios exists
406
+ this.handleAnalyticEvent(GENERAL_EVENT.session_end);
407
+ };
408
+
409
+ onPlayerSessionStart = () => {
410
+ // TODO: Implement method on native android, ios exists
411
+
412
+ this.handleAnalyticEvent(GENERAL_EVENT.session_start);
395
413
  };
396
414
 
397
415
  onVideoEnd = () => {
398
416
  this.setState({ displayOverlay: !this.state.displayOverlay }, () => {
399
417
  if (this.state?.displayOverlay) {
418
+ this.handleAnalyticEvent(PLAYBACK_EVENT.complete);
400
419
  this.props?.listener?.onVideoEnd({});
401
420
  }
402
421
  });
@@ -406,12 +425,15 @@ export default class VideoPlayer extends React.Component<
406
425
  onVideoError = ({ nativeEvent }) => {
407
426
  const { message } = nativeEvent;
408
427
 
428
+ this.handleAnalyticEvent(PLAYBACK_EVENT.error, nativeEvent);
429
+
409
430
  return this.props?.listener?.onError(new Error(message));
410
431
  };
411
432
 
412
433
  onPlayerPause = ({ nativeEvent = null }) => {
413
434
  this.setState({ paused: true });
414
435
  this.props?.listener?.onPlayerPause(nativeEvent);
436
+ this.handleAnalyticEvent(PLAYBACK_EVENT.pause, nativeEvent);
415
437
  };
416
438
 
417
439
  onPlayerResume = ({ nativeEvent = null }) => {
@@ -422,61 +444,98 @@ export default class VideoPlayer extends React.Component<
422
444
 
423
445
  if (isNotAnAd && !resume) {
424
446
  this.setState({ resume: true });
447
+ this.handleAnalyticEvent(PLAYBACK_EVENT.play, nativeEvent);
425
448
  }
426
449
  };
427
450
 
428
451
  onPlayerSeekComplete = ({ nativeEvent }) => {
429
452
  this.props?.listener?.onPlayerSeekComplete(nativeEvent);
453
+ this.handleAnalyticEvent(PLAYBACK_EVENT.seek_complete, nativeEvent);
430
454
  };
431
455
 
432
456
  onPlayerSeekStart = ({ nativeEvent }) => {
433
457
  this.props?.listener?.onPlayerSeekStart(nativeEvent);
458
+ this.handleAnalyticEvent(PLAYBACK_EVENT.seek_start, nativeEvent);
434
459
  };
435
460
 
436
461
  onBufferStart = ({ nativeEvent }) => {
437
462
  this.props?.listener?.onBufferStart(nativeEvent);
463
+ this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_start, nativeEvent);
438
464
  };
439
465
 
440
466
  onBufferComplete = ({ nativeEvent }) => {
441
467
  this.props?.listener?.onBufferComplete(nativeEvent);
468
+ this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_complete, nativeEvent);
469
+ };
470
+
471
+ onPlayerNext = ({ nativeEvent }) => {
472
+ // TODO: Implement method on native
473
+
474
+ this.handleAnalyticEvent(PLAYBACK_EVENT.next, nativeEvent);
475
+ };
476
+
477
+ onPlayerPrevious = ({ nativeEvent }) => {
478
+ // TODO: Implement method on native
479
+
480
+ this.handleAnalyticEvent(PLAYBACK_EVENT.previous, nativeEvent);
481
+ };
482
+
483
+ onPlayerStop = ({ nativeEvent }) => {
484
+ // TODO: Implement method on native
485
+
486
+ this.handleAnalyticEvent(PLAYBACK_EVENT.stop, nativeEvent);
487
+ };
488
+
489
+ onVideoBandwidthUpdate = ({ nativeEvent }) => {
490
+ // TODO: Implement method on native
491
+
492
+ this.handleAnalyticEvent(QOS_EVENT.bitrate_changed, nativeEvent);
442
493
  };
443
494
 
444
495
  onAdBegin = ({ nativeEvent }) => {
445
496
  this.setState({ isAd: true });
497
+ this.handleAnalyticEvent(AD_EVENT.ad_start, nativeEvent);
446
498
  this.props.listener?.onAdBegin?.(nativeEvent);
447
499
  };
448
500
 
449
501
  onAdBreakBegin = ({ nativeEvent }) => {
450
502
  this.setState({ isAd: true });
503
+ this.handleAnalyticEvent(AD_EVENT.ad_break_start, nativeEvent);
451
504
  this.props.listener?.onAdBreakBegin?.(nativeEvent);
452
505
  };
453
506
 
454
507
  onAdBreakEnd = ({ nativeEvent }) => {
455
508
  this.setState({ isAd: false });
509
+ this.handleAnalyticEvent(AD_EVENT.ad_break_completed, nativeEvent);
456
510
  this.props.listener?.onAdBreakEnd?.(nativeEvent);
457
511
  };
458
512
 
459
513
  onAdEnd = ({ nativeEvent }) => {
460
514
  this.setState({ isAd: false });
515
+ this.handleAnalyticEvent(AD_EVENT.ad_complete, nativeEvent);
461
516
  this.props.listener?.onAdEnd?.(nativeEvent);
462
517
  };
463
518
 
464
519
  onAdError = ({ nativeEvent }) => {
465
520
  this.setState({ isAd: false });
521
+ this.handleAnalyticEvent(AD_EVENT.ad_error, nativeEvent);
466
522
  this.props.listener?.onAdError?.(nativeEvent);
467
523
  };
468
524
 
469
525
  onAdRequest = ({ nativeEvent }) => {
526
+ this.handleAnalyticEvent(AD_EVENT.ad_request, nativeEvent);
470
527
  this.props.listener?.onAdRequest?.(nativeEvent);
471
528
  };
472
529
 
473
530
  onAdClicked = ({ nativeEvent }) => {
531
+ this.handleAnalyticEvent(AD_EVENT.ad_clicked, nativeEvent);
474
532
  // Broadcast click event
475
533
  this.props.playerEvent("ad-clicked", nativeEvent);
476
534
  this.props.listener?.onAdClicked?.(nativeEvent);
477
535
  };
478
536
 
479
537
  onAdTapped = ({ nativeEvent }) => {
538
+ this.handleAnalyticEvent(AD_EVENT.ad_tapped, nativeEvent);
480
539
  // Broadcast click event
481
540
  this.props.playerEvent("ad-tapped", nativeEvent);
482
541
  this.props.listener?.onAdTapped?.(nativeEvent);
@@ -589,6 +648,10 @@ export default class VideoPlayer extends React.Component<
589
648
  }
590
649
 
591
650
  if (!this.state.isAd && !this.onVideoLoadCalled) {
651
+ this.handleAnalyticEvent(PLAYBACK_EVENT.load_video, {
652
+ player_type: this.props.playerPluginIdentifier,
653
+ });
654
+
592
655
  // TODO: Hack, needs to remove
593
656
  this.onVideoLoadCalled = true;
594
657
  }
@@ -856,6 +919,8 @@ export default class VideoPlayer extends React.Component<
856
919
  onPlayerResume: this.onPlayerResume, // play
857
920
  onPlayerSeekComplete: this.onPlayerSeekComplete, // seek_complete
858
921
  onPlayerSeekStart: this.onPlayerSeekStart, // seek_start
922
+ onPlayerSessionEnd: this.onPlayerSessionEnd, // session_end
923
+ onPlayerSessionStart: this.onPlayerSessionStart, // session_start
859
924
  };
860
925
 
861
926
  const lifecycleEvents = {
@@ -888,6 +953,7 @@ export default class VideoPlayer extends React.Component<
888
953
  onTimedMetadata: this.unHandledEvent("onTimedMetadata"),
889
954
  onTracksChanged: this.onTracksChanged,
890
955
  eventSubtitlesChange: this.unHandledEvent("eventSubtitlesChange"),
956
+ onVideoBandwidthUpdate: this.onVideoBandwidthUpdate,
891
957
  };
892
958
 
893
959
  const playerSystemEvents = {
@@ -907,6 +973,9 @@ export default class VideoPlayer extends React.Component<
907
973
  const unsupportedEvents = {
908
974
  onBufferComplete: this.onBufferComplete, // buffer_complete
909
975
  onBufferStart: this.onBufferStart, // buffer_start
976
+ onPlayerNext: this.onPlayerNext, // next
977
+ onPlayerPrevious: this.onPlayerPrevious, // previous
978
+ onPlayerStop: this.onPlayerStop, // stop
910
979
  };
911
980
 
912
981
  const nativeEvents = {
@@ -920,7 +989,13 @@ export default class VideoPlayer extends React.Component<
920
989
  ...androidLifecyclePiPEvents,
921
990
  };
922
991
 
923
- const needToShowPlayNextOverlay = this.getPlayNextData() && !docked;
992
+ const needToShowPlayNextOverlay =
993
+ isTV() && this.getPlayNextData() && !docked;
994
+
995
+ const needToShowDefaultControls = !(
996
+ (controls && !castAction?.state?.connected) ||
997
+ this.getPlayNextData()
998
+ );
924
999
 
925
1000
  const playerContainerStyles = isApplePlatform()
926
1001
  ? styles.playerContainerBlack
@@ -962,7 +1037,7 @@ export default class VideoPlayer extends React.Component<
962
1037
  extraInfoText={castAction?.state?.friendlyStatus}
963
1038
  controlsAlwaysVisible={castAction?.state?.connected}
964
1039
  playNextData={this.getPlayNextData()}
965
- nativeControls={!!controls}
1040
+ needToShowDefaultControls={needToShowDefaultControls}
966
1041
  />
967
1042
  ) : null;
968
1043
  };