bitmovin-player-react-native 0.4.0 → 0.5.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 +249 -1
- package/RNBitmovinPlayer.podspec +3 -1
- package/android/build.gradle +3 -2
- package/android/src/main/java/com/bitmovin/player/reactnative/AnalyticsModule.kt +154 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +45 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +25 -4
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +172 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Any.kt +27 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +8 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/String.kt +8 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerBridge.kt +37 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerModule.kt +73 -0
- package/ios/AnalyticsModule.m +14 -0
- package/ios/AnalyticsModule.swift +180 -0
- package/ios/Event+JSON.swift +11 -0
- package/ios/FullscreenHandlerBridge.swift +33 -0
- package/ios/FullscreenHandlerModule.m +9 -0
- package/ios/FullscreenHandlerModule.swift +71 -0
- package/ios/RCTConvert+BitmovinPlayer.swift +174 -0
- package/ios/RNPlayerView+PlayerListener.swift +5 -1
- package/ios/RNPlayerView+UserInterfaceListener.swift +16 -0
- package/ios/RNPlayerView.swift +5 -0
- package/ios/RNPlayerViewManager.m +6 -0
- package/ios/RNPlayerViewManager.swift +21 -0
- package/lib/index.d.ts +498 -51
- package/lib/index.js +186 -42
- package/lib/index.mjs +167 -26
- package/package.json +1 -1
- package/src/analytics/collector.ts +97 -0
- package/src/analytics/config.ts +218 -0
- package/src/analytics/index.ts +2 -0
- package/src/components/PlayerView/events.ts +10 -0
- package/src/components/PlayerView/index.tsx +38 -1
- package/src/components/PlayerView/native.ts +4 -1
- package/src/events.ts +43 -0
- package/src/index.ts +2 -0
- package/src/media.ts +33 -0
- package/src/player.ts +21 -0
- package/src/source.ts +4 -0
- package/src/styleConfig.ts +87 -0
- package/src/ui/fullscreenhandler.ts +19 -0
- package/src/ui/fullscreenhandlerbridge.ts +59 -0
package/package.json
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { NativeModules } from 'react-native';
|
|
2
|
+
import NativeInstance from '../nativeInstance';
|
|
3
|
+
import { AnalyticsConfig, CustomDataConfig } from './config';
|
|
4
|
+
|
|
5
|
+
const AnalyticsModule = NativeModules.AnalyticsModule;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Analytics collector that can be attached to a player object in order to collect and send
|
|
9
|
+
* its analytics information.
|
|
10
|
+
*/
|
|
11
|
+
export class AnalyticsCollector extends NativeInstance<AnalyticsConfig> {
|
|
12
|
+
/**
|
|
13
|
+
* Whether the native `AnalyticsCollector` object has been created.
|
|
14
|
+
*/
|
|
15
|
+
isInitialized = false;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Whether the native `AnalyticsCollector` object has been disposed.
|
|
19
|
+
*/
|
|
20
|
+
isDestroyed = false;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Initializes a native `BitmovinPlayerCollector` object.
|
|
24
|
+
*/
|
|
25
|
+
initialize = () => {
|
|
26
|
+
if (!this.isInitialized) {
|
|
27
|
+
AnalyticsModule.initWithConfig(this.nativeId, this.config);
|
|
28
|
+
this.isInitialized = true;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Disposes the native `BitmovinPlayerCollector` object that has been created
|
|
34
|
+
* during initialization.
|
|
35
|
+
*/
|
|
36
|
+
destroy = () => {
|
|
37
|
+
if (!this.isDestroyed) {
|
|
38
|
+
AnalyticsModule.destroy(this.nativeId);
|
|
39
|
+
this.isDestroyed = true;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Attach a player instance to this analytics plugin. After this is completed, BitmovinAnalytics
|
|
45
|
+
* will start monitoring and sending analytics data based on the attached player instance.
|
|
46
|
+
*
|
|
47
|
+
* @param playerId - Native Id of the player to attach this collector instance.
|
|
48
|
+
*/
|
|
49
|
+
attach = (playerId: string): void => {
|
|
50
|
+
AnalyticsModule.attach(this.nativeId, playerId);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Detach a player instance from this analytics plugin if there's any attached. If no player is attached,
|
|
55
|
+
* nothing happens.
|
|
56
|
+
*/
|
|
57
|
+
detach = (): void => {
|
|
58
|
+
AnalyticsModule.detach(this.nativeId);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Dynamically updates analytics custom data information. Use this method
|
|
63
|
+
* to update your custom data during runtime.
|
|
64
|
+
*
|
|
65
|
+
* @param customData - Analytics custom data config.
|
|
66
|
+
*/
|
|
67
|
+
setCustomDataOnce = (customData: CustomDataConfig) => {
|
|
68
|
+
AnalyticsModule.setCustomDataOnce(this.nativeId, customData);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Sets the internal analytics custom data state.
|
|
73
|
+
*
|
|
74
|
+
* @param customData - Analytics custom data config.
|
|
75
|
+
*/
|
|
76
|
+
setCustomData = (customData: CustomDataConfig) => {
|
|
77
|
+
AnalyticsModule.setCustomData(this.nativeId, customData);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets the current custom data config from the native `BitmovinPlayerCollector` instance.
|
|
82
|
+
*
|
|
83
|
+
* @returns The current custom data config.
|
|
84
|
+
*/
|
|
85
|
+
getCustomData = async (): Promise<CustomDataConfig> => {
|
|
86
|
+
return AnalyticsModule.getCustomData(this.nativeId);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Gets the current user id used by the native `BitmovinPlayerCollector` instance.
|
|
91
|
+
*
|
|
92
|
+
* @returns The current user id.
|
|
93
|
+
*/
|
|
94
|
+
getUserId = async (): Promise<string> => {
|
|
95
|
+
return AnalyticsModule.getUserId(this.nativeId);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { NativeInstanceConfig } from '../nativeInstance';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Available cdn provider options for AnalyticsConfig.
|
|
5
|
+
*/
|
|
6
|
+
export enum CdnProvider {
|
|
7
|
+
BITMOVIN = 'bitmovin',
|
|
8
|
+
AKAMAI = 'akamai',
|
|
9
|
+
FASTLY = 'fastly',
|
|
10
|
+
MAXCDN = 'maxcdn',
|
|
11
|
+
CLOUDFRONT = 'cloudfront',
|
|
12
|
+
CHINACACHE = 'chinacache',
|
|
13
|
+
BITGRAVITY = 'bitgravity',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Object used to configure a new `AnalyticsCollector` instance.
|
|
18
|
+
*/
|
|
19
|
+
export interface AnalyticsConfig
|
|
20
|
+
extends NativeInstanceConfig,
|
|
21
|
+
CustomDataConfig {
|
|
22
|
+
/**
|
|
23
|
+
* CDN Provide that the video playback session is using.
|
|
24
|
+
*/
|
|
25
|
+
cdnProvider?: CdnProvider;
|
|
26
|
+
/**
|
|
27
|
+
* User ID of the customer.
|
|
28
|
+
*/
|
|
29
|
+
customUserId?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Experiment name needed for A/B testing.
|
|
32
|
+
*/
|
|
33
|
+
experimentName?: string;
|
|
34
|
+
/**
|
|
35
|
+
* ID of the video in the CMS system.
|
|
36
|
+
*/
|
|
37
|
+
videoId?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Human readable title of the video asset currently playing.
|
|
40
|
+
*/
|
|
41
|
+
title?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Analytics key.
|
|
44
|
+
*/
|
|
45
|
+
key: string;
|
|
46
|
+
/**
|
|
47
|
+
* Player key.
|
|
48
|
+
*/
|
|
49
|
+
playerKey?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Breadcrumb path to show where in the app the user is.
|
|
52
|
+
*/
|
|
53
|
+
path?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Flag to see if stream is live before stream metadata is available (default: false).
|
|
56
|
+
*/
|
|
57
|
+
isLive?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Flag to enable Ad tracking (default: false).
|
|
60
|
+
*/
|
|
61
|
+
ads?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Flag to use randomised userId not depending on device specific values (default: false).
|
|
64
|
+
*/
|
|
65
|
+
randomizeUserId?: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface CustomDataConfig {
|
|
69
|
+
/**
|
|
70
|
+
* Optional free-form custom data
|
|
71
|
+
*/
|
|
72
|
+
customData1?: string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Optional free-form custom data
|
|
76
|
+
*/
|
|
77
|
+
customData2?: string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Optional free-form custom data
|
|
81
|
+
*/
|
|
82
|
+
customData3?: string;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Optional free-form custom data
|
|
86
|
+
*/
|
|
87
|
+
customData4?: string;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Optional free-form custom data
|
|
91
|
+
*/
|
|
92
|
+
customData5?: string;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Optional free-form custom data
|
|
96
|
+
*/
|
|
97
|
+
customData6?: string;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Optional free-form custom data
|
|
101
|
+
*/
|
|
102
|
+
customData7?: string;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Optional free-form custom data
|
|
106
|
+
*/
|
|
107
|
+
customData8?: string;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Optional free-form custom data
|
|
111
|
+
*/
|
|
112
|
+
customData9?: string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Optional free-form custom data
|
|
116
|
+
*/
|
|
117
|
+
customData10?: string;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Optional free-form custom data
|
|
121
|
+
*/
|
|
122
|
+
customData11?: string;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Optional free-form custom data
|
|
126
|
+
*/
|
|
127
|
+
customData12?: string;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Optional free-form custom data
|
|
131
|
+
*/
|
|
132
|
+
customData13?: string;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Optional free-form custom data
|
|
136
|
+
*/
|
|
137
|
+
customData14?: string;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Optional free-form custom data
|
|
141
|
+
*/
|
|
142
|
+
customData15?: string;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Optional free-form custom data
|
|
146
|
+
*/
|
|
147
|
+
customData16?: string;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Optional free-form custom data
|
|
151
|
+
*/
|
|
152
|
+
customData17?: string;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Optional free-form custom data
|
|
156
|
+
*/
|
|
157
|
+
customData18?: string;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Optional free-form custom data
|
|
161
|
+
*/
|
|
162
|
+
customData19?: string;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Optional free-form custom data
|
|
166
|
+
*/
|
|
167
|
+
customData20?: string;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Optional free-form custom data
|
|
171
|
+
*/
|
|
172
|
+
customData21?: string;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Optional free-form custom data
|
|
176
|
+
*/
|
|
177
|
+
customData22?: string;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Optional free-form custom data
|
|
181
|
+
*/
|
|
182
|
+
customData23?: string;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Optional free-form custom data
|
|
186
|
+
*/
|
|
187
|
+
customData24?: string;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Optional free-form custom data
|
|
191
|
+
*/
|
|
192
|
+
customData25?: string;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Optional free-form custom data
|
|
196
|
+
*/
|
|
197
|
+
customData26?: string;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Optional free-form custom data
|
|
201
|
+
*/
|
|
202
|
+
customData27?: string;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Optional free-form custom data
|
|
206
|
+
*/
|
|
207
|
+
customData28?: string;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Optional free-form custom data
|
|
211
|
+
*/
|
|
212
|
+
customData29?: string;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Optional free-form custom data
|
|
216
|
+
*/
|
|
217
|
+
customData30?: string;
|
|
218
|
+
}
|
|
@@ -13,6 +13,10 @@ import {
|
|
|
13
13
|
AdStartedEvent,
|
|
14
14
|
DestroyEvent,
|
|
15
15
|
Event,
|
|
16
|
+
FullscreenEnabledEvent,
|
|
17
|
+
FullscreenDisabledEvent,
|
|
18
|
+
FullscreenEnterEvent,
|
|
19
|
+
FullscreenExitEvent,
|
|
16
20
|
MutedEvent,
|
|
17
21
|
PausedEvent,
|
|
18
22
|
PictureInPictureAvailabilityChangedEvent,
|
|
@@ -41,6 +45,7 @@ import {
|
|
|
41
45
|
SubtitleRemovedEvent,
|
|
42
46
|
TimeChangedEvent,
|
|
43
47
|
UnmutedEvent,
|
|
48
|
+
VideoPlaybackQualityChangedEvent,
|
|
44
49
|
} from '../../events';
|
|
45
50
|
|
|
46
51
|
/**
|
|
@@ -61,6 +66,10 @@ interface EventProps {
|
|
|
61
66
|
onAdStarted: AdStartedEvent;
|
|
62
67
|
onDestroy: DestroyEvent;
|
|
63
68
|
onEvent: Event;
|
|
69
|
+
onFullscreenEnabled: FullscreenEnabledEvent;
|
|
70
|
+
onFullscreenDisabled: FullscreenDisabledEvent;
|
|
71
|
+
onFullscreenEnter: FullscreenEnterEvent;
|
|
72
|
+
onFullscreenExit: FullscreenExitEvent;
|
|
64
73
|
onMuted: MutedEvent;
|
|
65
74
|
onPaused: PausedEvent;
|
|
66
75
|
onPictureInPictureAvailabilityChanged: PictureInPictureAvailabilityChangedEvent;
|
|
@@ -89,6 +98,7 @@ interface EventProps {
|
|
|
89
98
|
onSubtitleRemoved: SubtitleRemovedEvent;
|
|
90
99
|
onTimeChanged: TimeChangedEvent;
|
|
91
100
|
onUnmuted: UnmutedEvent;
|
|
101
|
+
onVideoPlaybackQualityChanged: VideoPlaybackQualityChangedEvent;
|
|
92
102
|
}
|
|
93
103
|
|
|
94
104
|
/**
|
|
@@ -11,6 +11,8 @@ import { PlayerViewEvents } from './events';
|
|
|
11
11
|
import { NativePlayerView } from './native';
|
|
12
12
|
import { Player } from '../../player';
|
|
13
13
|
import { useProxy } from '../../hooks/useProxy';
|
|
14
|
+
import { FullscreenHandler } from '../../ui/fullscreenhandler';
|
|
15
|
+
import { FullscreenHandlerBridge } from '../../ui/fullscreenhandlerbridge';
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Base `PlayerView` component props. Used to stablish common
|
|
@@ -31,6 +33,8 @@ export interface PlayerViewProps extends BasePlayerViewProps, PlayerViewEvents {
|
|
|
31
33
|
* and render audio/video inside the `PlayerView`.
|
|
32
34
|
*/
|
|
33
35
|
player: Player;
|
|
36
|
+
|
|
37
|
+
fullscreenHandler?: FullscreenHandler;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
/**
|
|
@@ -61,13 +65,29 @@ function dispatch(command: string, node: NodeHandle, ...args: any[]) {
|
|
|
61
65
|
* Component that provides the Bitmovin Player UI and default UI handling to an attached `Player` instance.
|
|
62
66
|
* This component needs a `Player` instance to work properly so make sure one is passed to it as a prop.
|
|
63
67
|
*/
|
|
64
|
-
export function PlayerView({
|
|
68
|
+
export function PlayerView({
|
|
69
|
+
style,
|
|
70
|
+
player,
|
|
71
|
+
fullscreenHandler,
|
|
72
|
+
...props
|
|
73
|
+
}: PlayerViewProps) {
|
|
65
74
|
// Native view reference.
|
|
66
75
|
const nativeView = useRef(null);
|
|
67
76
|
// Native events proxy helper.
|
|
68
77
|
const proxy = useProxy(nativeView);
|
|
69
78
|
// Style resulting from merging `baseStyle` and `props.style`.
|
|
70
79
|
const nativeViewStyle = StyleSheet.flatten([styles.baseStyle, style]);
|
|
80
|
+
|
|
81
|
+
const fullscreenBridge: React.MutableRefObject<
|
|
82
|
+
FullscreenHandlerBridge | undefined
|
|
83
|
+
> = useRef(undefined);
|
|
84
|
+
if (fullscreenHandler && !fullscreenBridge.current) {
|
|
85
|
+
fullscreenBridge.current = new FullscreenHandlerBridge();
|
|
86
|
+
}
|
|
87
|
+
if (fullscreenBridge.current) {
|
|
88
|
+
fullscreenBridge.current.fullscreenHandler = fullscreenHandler;
|
|
89
|
+
}
|
|
90
|
+
|
|
71
91
|
useEffect(() => {
|
|
72
92
|
// Initialize native player instance if needed.
|
|
73
93
|
player.initialize();
|
|
@@ -75,12 +95,24 @@ export function PlayerView({ style, player, ...props }: PlayerViewProps) {
|
|
|
75
95
|
const node = findNodeHandle(nativeView.current);
|
|
76
96
|
if (node) {
|
|
77
97
|
dispatch('attachPlayer', node, player.nativeId, player.config);
|
|
98
|
+
if (fullscreenBridge.current) {
|
|
99
|
+
dispatch(
|
|
100
|
+
'attachFullscreenBridge',
|
|
101
|
+
node,
|
|
102
|
+
fullscreenBridge.current.nativeId
|
|
103
|
+
);
|
|
104
|
+
}
|
|
78
105
|
}
|
|
106
|
+
return () => {
|
|
107
|
+
fullscreenBridge.current?.destroy();
|
|
108
|
+
fullscreenBridge.current = undefined;
|
|
109
|
+
};
|
|
79
110
|
}, [player]);
|
|
80
111
|
return (
|
|
81
112
|
<NativePlayerView
|
|
82
113
|
ref={nativeView}
|
|
83
114
|
style={nativeViewStyle}
|
|
115
|
+
fullscreenBridge={fullscreenBridge.current}
|
|
84
116
|
onAdBreakFinished={proxy(props.onAdBreakFinished)}
|
|
85
117
|
onAdBreakStarted={proxy(props.onAdBreakStarted)}
|
|
86
118
|
onAdClicked={proxy(props.onAdClicked)}
|
|
@@ -94,6 +126,10 @@ export function PlayerView({ style, player, ...props }: PlayerViewProps) {
|
|
|
94
126
|
onAdStarted={proxy(props.onAdStarted)}
|
|
95
127
|
onDestroy={proxy(props.onDestroy)}
|
|
96
128
|
onEvent={proxy(props.onEvent)}
|
|
129
|
+
onFullscreenEnabled={proxy(props.onFullscreenEnabled)}
|
|
130
|
+
onFullscreenDisabled={proxy(props.onFullscreenDisabled)}
|
|
131
|
+
onFullscreenEnter={proxy(props.onFullscreenEnter)}
|
|
132
|
+
onFullscreenExit={proxy(props.onFullscreenExit)}
|
|
97
133
|
onMuted={proxy(props.onMuted)}
|
|
98
134
|
onPaused={proxy(props.onPaused)}
|
|
99
135
|
onPictureInPictureAvailabilityChanged={proxy(
|
|
@@ -124,6 +160,7 @@ export function PlayerView({ style, player, ...props }: PlayerViewProps) {
|
|
|
124
160
|
onSubtitleRemoved={proxy(props.onSubtitleRemoved)}
|
|
125
161
|
onTimeChanged={proxy(props.onTimeChanged)}
|
|
126
162
|
onUnmuted={proxy(props.onUnmuted)}
|
|
163
|
+
onVideoPlaybackQualityChanged={proxy(props.onVideoPlaybackQualityChanged)}
|
|
127
164
|
/>
|
|
128
165
|
);
|
|
129
166
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { requireNativeComponent } from 'react-native';
|
|
2
2
|
import { NativePlayerViewEvents } from './events';
|
|
3
3
|
import { BasePlayerViewProps } from './index';
|
|
4
|
+
import { FullscreenHandlerBridge } from '../../ui/fullscreenhandlerbridge';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Props type for `NativePlayerView` native component.
|
|
@@ -8,7 +9,9 @@ import { BasePlayerViewProps } from './index';
|
|
|
8
9
|
*/
|
|
9
10
|
export interface NativePlayerViewProps
|
|
10
11
|
extends BasePlayerViewProps,
|
|
11
|
-
NativePlayerViewEvents {
|
|
12
|
+
NativePlayerViewEvents {
|
|
13
|
+
fullscreenBridge?: FullscreenHandlerBridge;
|
|
14
|
+
}
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* Native host component bridging Bitmovin's `PlayerView`.
|
package/src/events.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
AdSourceType,
|
|
8
8
|
} from './advertising';
|
|
9
9
|
import { SubtitleTrack } from './subtitleTrack';
|
|
10
|
+
import { VideoQuality } from './media';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Base event type for all events.
|
|
@@ -290,6 +291,34 @@ export interface PictureInPictureEnteredEvent extends Event {}
|
|
|
290
291
|
*/
|
|
291
292
|
export interface PictureInPictureExitedEvent extends Event {}
|
|
292
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Emitted when the fullscreen functionality has been enabled.
|
|
296
|
+
*
|
|
297
|
+
* @platform iOS, Android
|
|
298
|
+
*/
|
|
299
|
+
export interface FullscreenEnabledEvent extends Event {}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Emitted when the fullscreen functionality has been disabled.
|
|
303
|
+
*
|
|
304
|
+
* @platform iOS, Android
|
|
305
|
+
*/
|
|
306
|
+
export interface FullscreenDisabledEvent extends Event {}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Emitted when the player enters fullscreen mode.
|
|
310
|
+
*
|
|
311
|
+
* @platform iOS, Android
|
|
312
|
+
*/
|
|
313
|
+
export interface FullscreenEnterEvent extends Event {}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Emitted when the player exits fullscreen mode.
|
|
317
|
+
*
|
|
318
|
+
* @platform iOS, Android
|
|
319
|
+
*/
|
|
320
|
+
export interface FullscreenExitEvent extends Event {}
|
|
321
|
+
|
|
293
322
|
/**
|
|
294
323
|
* Emitted when the availability of the Picture in Picture mode changed on Android.
|
|
295
324
|
*
|
|
@@ -455,3 +484,17 @@ export interface AdManifestLoadedEvent extends Event {
|
|
|
455
484
|
*/
|
|
456
485
|
downloadTime: number;
|
|
457
486
|
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Emitted when the current video playback quality has changed.
|
|
490
|
+
*/
|
|
491
|
+
export interface VideoPlaybackQualityChangedEvent extends Event {
|
|
492
|
+
/**
|
|
493
|
+
* The new quality
|
|
494
|
+
*/
|
|
495
|
+
newVideoQuality: VideoQuality;
|
|
496
|
+
/**
|
|
497
|
+
* The previous quality
|
|
498
|
+
*/
|
|
499
|
+
oldVideoQuality: VideoQuality;
|
|
500
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './advertising';
|
|
2
|
+
export * from './analytics';
|
|
2
3
|
export * from './audioSession';
|
|
3
4
|
export * from './components';
|
|
4
5
|
export * from './drm';
|
|
@@ -7,3 +8,4 @@ export * from './hooks';
|
|
|
7
8
|
export * from './player';
|
|
8
9
|
export * from './source';
|
|
9
10
|
export * from './subtitleTrack';
|
|
11
|
+
export * from './styleConfig';
|
package/src/media.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality definition of a video representation.
|
|
3
|
+
*/
|
|
4
|
+
export interface VideoQuality {
|
|
5
|
+
/**
|
|
6
|
+
* The id of the media quality.
|
|
7
|
+
*/
|
|
8
|
+
id: string;
|
|
9
|
+
/**
|
|
10
|
+
* The label of the media quality that should be exposed to the user.
|
|
11
|
+
*/
|
|
12
|
+
label?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The bitrate of the media quality.
|
|
15
|
+
*/
|
|
16
|
+
bitrate?: number;
|
|
17
|
+
/**
|
|
18
|
+
* The codec of the media quality.
|
|
19
|
+
*/
|
|
20
|
+
codec?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The frame rate of the video quality. If the frame rate is not known or not applicable a value of -1 will be returned.
|
|
23
|
+
*/
|
|
24
|
+
frameRate?: number;
|
|
25
|
+
/**
|
|
26
|
+
* The height of the video quality.
|
|
27
|
+
*/
|
|
28
|
+
height?: number;
|
|
29
|
+
/**
|
|
30
|
+
* The width of the video quality.
|
|
31
|
+
*/
|
|
32
|
+
width?: number;
|
|
33
|
+
}
|
package/src/player.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { NativeModules, Platform } from 'react-native';
|
|
2
2
|
import { AdItem, AdvertisingConfig } from './advertising';
|
|
3
|
+
import { AnalyticsCollector, AnalyticsConfig } from './analytics';
|
|
3
4
|
import NativeInstance, { NativeInstanceConfig } from './nativeInstance';
|
|
4
5
|
import { Source, SourceConfig } from './source';
|
|
5
6
|
import { SubtitleTrack } from './subtitleTrack';
|
|
7
|
+
import { StyleConfig } from './styleConfig';
|
|
6
8
|
import { TweaksConfig } from './tweaksConfig';
|
|
7
9
|
|
|
8
10
|
const PlayerModule = NativeModules.PlayerModule;
|
|
@@ -34,6 +36,10 @@ export interface PlayerConfig extends NativeInstanceConfig {
|
|
|
34
36
|
* Configures playback behaviour. A default PlaybackConfig is set initially.
|
|
35
37
|
*/
|
|
36
38
|
playbackConfig?: PlaybackConfig;
|
|
39
|
+
/**
|
|
40
|
+
* Configures the visual presentation and behaviour of the player UI. A default StyleConfig is set initially.
|
|
41
|
+
*/
|
|
42
|
+
styleConfig?: StyleConfig;
|
|
37
43
|
/**
|
|
38
44
|
* Configures advertising functionality. A default AdvertisingConfig is set initially.
|
|
39
45
|
*/
|
|
@@ -42,6 +48,10 @@ export interface PlayerConfig extends NativeInstanceConfig {
|
|
|
42
48
|
* Configures experimental features. A default TweaksConfig is set initially.
|
|
43
49
|
*/
|
|
44
50
|
tweaksConfig?: TweaksConfig;
|
|
51
|
+
/**
|
|
52
|
+
* Configures analytics functionality.
|
|
53
|
+
*/
|
|
54
|
+
analyticsConfig?: AnalyticsConfig;
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
/**
|
|
@@ -135,6 +145,10 @@ export class Player extends NativeInstance<PlayerConfig> {
|
|
|
135
145
|
* Currently active source, or `null` if none is active.
|
|
136
146
|
*/
|
|
137
147
|
source?: Source;
|
|
148
|
+
/**
|
|
149
|
+
* Analytics collector currently attached to this player instance.
|
|
150
|
+
*/
|
|
151
|
+
analyticsCollector?: AnalyticsCollector;
|
|
138
152
|
/**
|
|
139
153
|
* Whether the native `Player` object has been created.
|
|
140
154
|
*/
|
|
@@ -150,6 +164,12 @@ export class Player extends NativeInstance<PlayerConfig> {
|
|
|
150
164
|
initialize = () => {
|
|
151
165
|
if (!this.isInitialized) {
|
|
152
166
|
PlayerModule.initWithConfig(this.nativeId, this.config);
|
|
167
|
+
const analyticsConfig = this.config?.analyticsConfig;
|
|
168
|
+
if (analyticsConfig) {
|
|
169
|
+
this.analyticsCollector = new AnalyticsCollector(analyticsConfig);
|
|
170
|
+
this.analyticsCollector?.initialize();
|
|
171
|
+
this.analyticsCollector?.attach(this.nativeId);
|
|
172
|
+
}
|
|
153
173
|
this.isInitialized = true;
|
|
154
174
|
}
|
|
155
175
|
};
|
|
@@ -161,6 +181,7 @@ export class Player extends NativeInstance<PlayerConfig> {
|
|
|
161
181
|
if (!this.isDestroyed) {
|
|
162
182
|
PlayerModule.destroy(this.nativeId);
|
|
163
183
|
this.source?.destroy();
|
|
184
|
+
this.analyticsCollector?.destroy();
|
|
164
185
|
this.isDestroyed = true;
|
|
165
186
|
}
|
|
166
187
|
};
|
package/src/source.ts
CHANGED
|
@@ -78,6 +78,10 @@ export interface SourceConfig extends NativeInstanceConfig {
|
|
|
78
78
|
* External subtitle tracks to be added into the player.
|
|
79
79
|
*/
|
|
80
80
|
subtitleTracks?: SideLoadedSubtitleTrack[];
|
|
81
|
+
/**
|
|
82
|
+
* External thumbnails to be added into the player.
|
|
83
|
+
*/
|
|
84
|
+
thumbnailTrack?: string;
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
/**
|