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.
Files changed (43) hide show
  1. package/README.md +249 -1
  2. package/RNBitmovinPlayer.podspec +3 -1
  3. package/android/build.gradle +3 -2
  4. package/android/src/main/java/com/bitmovin/player/reactnative/AnalyticsModule.kt +154 -0
  5. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +45 -0
  6. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +25 -4
  7. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
  8. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +172 -0
  9. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Any.kt +27 -0
  10. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +8 -0
  11. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/String.kt +8 -0
  12. package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerBridge.kt +37 -0
  13. package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerModule.kt +73 -0
  14. package/ios/AnalyticsModule.m +14 -0
  15. package/ios/AnalyticsModule.swift +180 -0
  16. package/ios/Event+JSON.swift +11 -0
  17. package/ios/FullscreenHandlerBridge.swift +33 -0
  18. package/ios/FullscreenHandlerModule.m +9 -0
  19. package/ios/FullscreenHandlerModule.swift +71 -0
  20. package/ios/RCTConvert+BitmovinPlayer.swift +174 -0
  21. package/ios/RNPlayerView+PlayerListener.swift +5 -1
  22. package/ios/RNPlayerView+UserInterfaceListener.swift +16 -0
  23. package/ios/RNPlayerView.swift +5 -0
  24. package/ios/RNPlayerViewManager.m +6 -0
  25. package/ios/RNPlayerViewManager.swift +21 -0
  26. package/lib/index.d.ts +498 -51
  27. package/lib/index.js +186 -42
  28. package/lib/index.mjs +167 -26
  29. package/package.json +1 -1
  30. package/src/analytics/collector.ts +97 -0
  31. package/src/analytics/config.ts +218 -0
  32. package/src/analytics/index.ts +2 -0
  33. package/src/components/PlayerView/events.ts +10 -0
  34. package/src/components/PlayerView/index.tsx +38 -1
  35. package/src/components/PlayerView/native.ts +4 -1
  36. package/src/events.ts +43 -0
  37. package/src/index.ts +2 -0
  38. package/src/media.ts +33 -0
  39. package/src/player.ts +21 -0
  40. package/src/source.ts +4 -0
  41. package/src/styleConfig.ts +87 -0
  42. package/src/ui/fullscreenhandler.ts +19 -0
  43. package/src/ui/fullscreenhandlerbridge.ts +59 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitmovin-player-react-native",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Official React Native bindings for Bitmovin's mobile Player SDKs.",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ export * from './config';
2
+ export * from './collector';
@@ -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({ style, player, ...props }: PlayerViewProps) {
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
  /**