@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.
|
|
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.
|
|
40
|
-
"@applicaster/quick-brick-tv-transport-controls": "12.0.0-
|
|
41
|
-
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.
|
|
43
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
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}>
|
package/src/Player/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import * as R from "ramda";
|
|
6
6
|
|
|
7
|
-
import { findNodeHandle,
|
|
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 {
|
|
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 {
|
|
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.
|
|
397
|
+
this.handleAnalyticEvent(GENERAL_EVENT.player_presented);
|
|
391
398
|
};
|
|
392
399
|
|
|
393
400
|
onPlayerClosed = () => {
|
|
394
|
-
this.
|
|
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 =
|
|
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
|
-
|
|
1040
|
+
needToShowDefaultControls={needToShowDefaultControls}
|
|
966
1041
|
/>
|
|
967
1042
|
) : null;
|
|
968
1043
|
};
|