bitmovin-player-react-native 0.2.0 → 0.3.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 CHANGED
@@ -3,23 +3,42 @@
3
3
  Official React Native bindings for Bitmovin's mobile Player SDKs.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/bitmovin-player-react-native)](https://www.npmjs.com/package/bitmovin-player-react-native)
6
- ![Supports Android and iOS](https://img.shields.io/badge/platforms-android%20%7C%20ios-lightgrey.svg)
6
+ ![Platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20tvOS%20%7C%20Android%20%7C%20Android%20TV-lightgrey.svg)
7
7
  [![MIT License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
8
8
  [![Bitmovin Community](https://img.shields.io/discourse/users?label=community&server=https%3A%2F%2Fcommunity.bitmovin.com)](https://community.bitmovin.com/?utm_source=github&utm_medium=bitmovin-player-react-native&utm_campaign=dev-community)
9
9
 
10
- > :warning: **Beta Version**: The library is under active development.
11
-
12
- - [Installation](#installation)
13
- - [Add package dependency](#add-package-dependency)
14
- - [Setup iOS Player SDK](#setup-ios-player-sdk)
15
- - [Setup Android Player SDK](#setup-android-player-sdk)
16
- - [Getting Started](#getting-started)
17
- - [Setting up a license key](#setting-up-a-license-key)
18
- - [Accessing native `Player` instances](#accessing-native-player-instances)
19
- - [Listening to events](#listening-to-events)
20
- - [Enabling DRM protection](#enabling-drm-protection)
21
- - [Adding external subtitle tracks](#adding-subtitle-tracks)
22
- - [Contributing](#contributing)
10
+ > The library is under active development.
11
+
12
+ - [Bitmovin Player React Native](#bitmovin-player-react-native)
13
+ - [Platform Support](#platform-support)
14
+ - [Installation](#installation)
15
+ - [Add package dependency](#add-package-dependency)
16
+ - [Setup iOS Player SDK](#setup-ios-player-sdk)
17
+ - [Setup Android Player SDK](#setup-android-player-sdk)
18
+ - [Getting Started](#getting-started)
19
+ - [Setting up a license key](#setting-up-a-license-key)
20
+ - [Configuring through code](#configuring-through-code)
21
+ - [Setting up a playback configurations](#setting-up-a-playback-configurations)
22
+ - [Configuring `Info.plist`](#configuring-infoplist)
23
+ - [Configuring `AndroidManifest.xml`](#configuring-androidmanifestxml)
24
+ - [Accessing native `Player` instances](#accessing-native-player-instances)
25
+ - [Listening to events](#listening-to-events)
26
+ - [Enabling DRM protection](#enabling-drm-protection)
27
+ - [Prepare hooks](#prepare-hooks)
28
+ - [Adding external subtitle tracks](#adding-external-subtitle-tracks)
29
+ - [Contributing](#contributing)
30
+
31
+ ## Platform Support
32
+
33
+ This library requires at least React Native 0.64+ and React 17+ to work properly. The currently supported platforms are:
34
+
35
+ - iOS 12.0+
36
+ - tvOS 12.0+
37
+ - Android API 16+
38
+ - Android TV API 17+
39
+ - Fire TV (just make sure the Android API level is at least 17+)
40
+
41
+ Please note that browsers and other browser-like environments such as webOS and Tizen are not supported.
23
42
 
24
43
  ## Installation
25
44
 
@@ -200,6 +219,42 @@ const player = new Player({
200
219
  });
201
220
  ```
202
221
 
222
+ ### Setting up a playback configurations
223
+
224
+ If needed, the default player behavior can be configured through the `playbackConfig` key when initialized.
225
+
226
+ ```typescript
227
+ // Simply pass the `playbackConfig` property to `PlayerConfig` when instantiating a player.
228
+
229
+ // With hooks
230
+ import { usePlayer } from 'bitmovin-player-react-native';
231
+ const player = usePlayer({
232
+ playbackConfig: {
233
+ // Specifies whether the playback starts immediately after loading a source or not. Default is false.
234
+ isAutoplayEnabled: true,
235
+ // Specifies if playback starts muted. Default is false.
236
+ isMuted: true,
237
+ // Specifies if time shift for live streams should be enabled. Default is true.
238
+ isTimeShiftEnabled: true,
239
+ // Whether background playback is enabled or not. Default is false.
240
+ // Only available for iOS.
241
+ isBackgroundPlaybackEnabled: true,
242
+ },
243
+ });
244
+
245
+ // Without hooks
246
+ import { Player } from 'bitmovin-player-react-native';
247
+ const player = new Player({
248
+ // Make sure to use React.createRef if instantiating inside a component.
249
+ playbackConfig: {
250
+ isAutoplayEnabled: true,
251
+ isMuted: true,
252
+ isTimeShiftEnabled: true,
253
+ isBackgroundPlaybackEnabled: true,
254
+ },
255
+ });
256
+ ```
257
+
203
258
  #### Configuring `Info.plist`
204
259
 
205
260
  Add the following lines to the `<dict>` section of your `ios/Info.plist`:
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.license = package["license"]
11
11
  s.authors = package["author"]
12
12
 
13
- s.platforms = { :ios => "12.4" }
13
+ s.platforms = { :ios => "12.4", :tvos => "12.4" }
14
14
  s.source = {
15
15
  :git => "https://github.com/bitmovin/bitmovin-player-react-native.git",
16
16
  :tag => "v#{s.version}"
@@ -19,5 +19,5 @@ Pod::Spec.new do |s|
19
19
  s.source_files = "ios/**/*.{h,m,mm,swift}"
20
20
 
21
21
  s.dependency "React-Core"
22
- s.dependency "BitmovinPlayer", "3.23.0"
22
+ s.dependency "BitmovinPlayer", "3.28.0"
23
23
  end
@@ -50,6 +50,6 @@ android {
50
50
 
51
51
  dependencies {
52
52
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
53
- implementation 'com.bitmovin.player:player:3.20.0'
53
+ implementation 'com.bitmovin.player:player:3.24.2'
54
54
  implementation 'com.facebook.react:react-native:+'
55
55
  }
@@ -1,5 +1,6 @@
1
1
  package com.bitmovin.player.reactnative.converter
2
2
 
3
+ import com.bitmovin.player.api.PlaybackConfig
3
4
  import com.bitmovin.player.api.PlayerConfig
4
5
  import com.bitmovin.player.api.drm.WidevineConfig
5
6
  import com.bitmovin.player.api.event.PlayerEvent
@@ -25,10 +26,25 @@ class JsonConverter {
25
26
  */
26
27
  @JvmStatic
27
28
  fun toPlayerConfig(json: ReadableMap?): PlayerConfig {
28
- if (json != null && json.hasKey("licenseKey")) {
29
- return PlayerConfig(key = json.getString("licenseKey"))
29
+ if (json == null) return PlayerConfig()
30
+ val playerConfig = if (json.hasKey("licenseKey")) {
31
+ PlayerConfig(key = json.getString("licenseKey"))
32
+ } else {
33
+ PlayerConfig()
34
+ }
35
+ if (json.hasKey("playbackConfig")) {
36
+ var playbackConfigJson = json.getMap("playbackConfig")
37
+ if (playbackConfigJson?.hasKey("isAutoplayEnabled") == true) {
38
+ playerConfig.playbackConfig.isAutoplayEnabled = playbackConfigJson.getBoolean("isAutoplayEnabled")
39
+ }
40
+ if(playbackConfigJson?.hasKey("isMuted") == true) {
41
+ playerConfig.playbackConfig.isMuted = playbackConfigJson.getBoolean("isMuted")
42
+ }
43
+ if(playbackConfigJson?.hasKey("isTimeShiftEnabled") == true) {
44
+ playerConfig.playbackConfig.isTimeShiftEnabled = playbackConfigJson.getBoolean("isTimeShiftEnabled")
45
+ }
30
46
  }
31
- return PlayerConfig()
47
+ return playerConfig
32
48
  }
33
49
 
34
50
  /**
@@ -15,6 +15,23 @@ extension RCTConvert {
15
15
  if let licenseKey = json["licenseKey"] as? String {
16
16
  playerConfig.key = licenseKey
17
17
  }
18
+ if let playbackConfig = json["playbackConfig"] as? [String: Any?] {
19
+ if let isAutoplayEnabled = playbackConfig["isAutoplayEnabled"] as? Bool {
20
+ playerConfig.playbackConfig.isAutoplayEnabled = isAutoplayEnabled
21
+ }
22
+ if let isMuted = playbackConfig["isMuted"] as? Bool {
23
+ playerConfig.playbackConfig.isMuted = isMuted
24
+ }
25
+ if let isTimeShiftEnabled = playbackConfig["isTimeShiftEnabled"] as? Bool {
26
+ playerConfig.playbackConfig.isTimeShiftEnabled = isTimeShiftEnabled
27
+ }
28
+ if let isBackgroundPlaybackEnabled = playbackConfig["isBackgroundPlaybackEnabled"] as? Bool {
29
+ playerConfig.playbackConfig.isBackgroundPlaybackEnabled = isBackgroundPlaybackEnabled
30
+ }
31
+ if let isPictureInPictureEnabled = playbackConfig["isPictureInPictureEnabled"] as? Bool {
32
+ playerConfig.playbackConfig.isPictureInPictureEnabled = isPictureInPictureEnabled
33
+ }
34
+ }
18
35
  return playerConfig
19
36
  }
20
37
 
package/lib/index.d.ts CHANGED
@@ -570,7 +570,7 @@ declare class Drm extends NativeInstance<DrmConfig> {
570
570
  * @param message - Base64 encoded message data.
571
571
  * @param assetId - Optional asset ID. Only sent by iOS.
572
572
  */
573
- onPrepareMessage: (message: string, assetId?: string | undefined) => void;
573
+ onPrepareMessage: (message: string, assetId?: string) => void;
574
574
  /**
575
575
  * iOS only.
576
576
  *
@@ -763,6 +763,86 @@ interface PlayerConfig extends NativeInstanceConfig {
763
763
  * ```
764
764
  */
765
765
  licenseKey?: string;
766
+ /**
767
+ * Configures playback behaviour. A default PlaybackConfig is set initially.
768
+ */
769
+ playbackConfig?: PlaybackConfig;
770
+ }
771
+ /**
772
+ * Configures the playback behaviour of the player.
773
+ */
774
+ interface PlaybackConfig {
775
+ /**
776
+ * Whether the player starts playing automatically after loading a source or not. Default is `false`.
777
+ * @example
778
+ * ```
779
+ * const player = new Player({
780
+ * playbackConfig: {
781
+ * isAutoplayEnabled: true,
782
+ * },
783
+ * });
784
+ * ```
785
+ */
786
+ isAutoplayEnabled?: boolean;
787
+ /**
788
+ * Whether the sound is muted on startup or not. Default value is `false`.
789
+ * @example
790
+ * ```
791
+ * const player = new Player({
792
+ * playbackConfig: {
793
+ * isMuted: true,
794
+ * },
795
+ * });
796
+ * ```
797
+ */
798
+ isMuted?: boolean;
799
+ /**
800
+ * Whether time shift / DVR for live streams is enabled or not. Default is `true`.
801
+ * @example
802
+ * ```
803
+ * const player = new Player({
804
+ * playbackConfig: {
805
+ * isTimeShiftEnabled: false,
806
+ * },
807
+ * });
808
+ * ```
809
+ */
810
+ isTimeShiftEnabled?: boolean;
811
+ /**
812
+ * Whether background playback is enabled or not.
813
+ * Default is `false`.
814
+ *
815
+ * When set to `true`, playback is not automatically paused
816
+ * anymore when the app moves to the background.
817
+ * When set to `true`, also make sure to properly configure your app to allow
818
+ * background playback.
819
+ *
820
+ * On tvOS, background playback is only supported for audio-only content.
821
+ *
822
+ * Default is `false`.
823
+ *
824
+ * @example
825
+ * ```
826
+ * const player = new Player({
827
+ * {
828
+ * isBackgroundPlaybackEnabled: true,
829
+ * }
830
+ * })
831
+ * ```
832
+ */
833
+ isBackgroundPlaybackEnabled?: boolean;
834
+ /**
835
+ * Whether the picture-in-picture mode option is enabled for iOS or not. Default is `false`.
836
+ * @example
837
+ * ```
838
+ * const player = new Player({
839
+ * playbackConfig: {
840
+ * isPictureInPictureEnabled: true,
841
+ * },
842
+ * });
843
+ * ```
844
+ */
845
+ isPictureInPictureEnabled?: boolean;
766
846
  }
767
847
  /**
768
848
  * Loads, controls and renders audio and video content represented through `Source`s. A player
@@ -850,7 +930,7 @@ declare class Player extends NativeInstance<PlayerConfig> {
850
930
  *
851
931
  * @param mode - The time mode to specify: an absolute UNIX timestamp ('absolute') or relative time ('relative').
852
932
  */
853
- getCurrentTime: (mode?: "relative" | "absolute" | undefined) => Promise<number>;
933
+ getCurrentTime: (mode?: 'relative' | 'absolute') => Promise<number>;
854
934
  /**
855
935
  * @returns The total duration in seconds of the current video or INFINITY if it’s a live stream.
856
936
  */
@@ -918,4 +998,4 @@ declare function PlayerView(props: PlayerViewProps): JSX.Element;
918
998
  */
919
999
  declare function usePlayer(config?: PlayerConfig): Player;
920
1000
 
921
- export { BasePlayerViewProps, DestroyEvent, Drm, DrmConfig, ErrorEvent, Event, EventSource, FairplayConfig, LoadingState, MutedEvent, PausedEvent, PlayEvent, PlaybackFinishedEvent, Player, PlayerActiveEvent, PlayerConfig, PlayerErrorEvent, PlayerView, PlayerViewProps, PlayerWarningEvent, PlayingEvent, ReadyEvent, SeekEvent, SeekedEvent, SideLoadedSubtitleTrack, Source, SourceConfig, SourceErrorEvent, SourceLoadEvent, SourceLoadedEvent, SourceType, SourceUnloadedEvent, SourceWarningEvent, SubtitleAddedEvent, SubtitleChangedEvent, SubtitleFormat, SubtitleRemovedEvent, SubtitleTrack, TimeChangedEvent, UnmutedEvent, WidevineConfig, usePlayer };
1001
+ export { BasePlayerViewProps, DestroyEvent, Drm, DrmConfig, ErrorEvent, Event, EventSource, FairplayConfig, LoadingState, MutedEvent, PausedEvent, PlayEvent, PlaybackConfig, PlaybackFinishedEvent, Player, PlayerActiveEvent, PlayerConfig, PlayerErrorEvent, PlayerView, PlayerViewProps, PlayerWarningEvent, PlayingEvent, ReadyEvent, SeekEvent, SeekedEvent, SideLoadedSubtitleTrack, Source, SourceConfig, SourceErrorEvent, SourceLoadEvent, SourceLoadedEvent, SourceType, SourceUnloadedEvent, SourceWarningEvent, SubtitleAddedEvent, SubtitleChangedEvent, SubtitleFormat, SubtitleRemovedEvent, SubtitleTrack, TimeChangedEvent, UnmutedEvent, WidevineConfig, usePlayer };
package/lib/index.js CHANGED
@@ -18,7 +18,10 @@ var __copyProps = (to, from, except, desc) => {
18
18
  }
19
19
  return to;
20
20
  };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
22
25
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
26
  var __publicField = (obj, key, value) => {
24
27
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -55,12 +58,15 @@ function unwrapNativeEvent(event) {
55
58
  return (0, import_lodash.default)(event.nativeEvent, ["target"]);
56
59
  }
57
60
  function useProxy(viewRef) {
58
- return (0, import_react.useCallback)((callback) => (event) => {
59
- const node = event.target._nativeTag;
60
- if (node === (0, import_react_native2.findNodeHandle)(viewRef.current)) {
61
- callback?.(unwrapNativeEvent(event));
62
- }
63
- }, [viewRef]);
61
+ return (0, import_react.useCallback)(
62
+ (callback) => (event) => {
63
+ const node = event.target._nativeTag;
64
+ if (node === (0, import_react_native2.findNodeHandle)(viewRef.current)) {
65
+ callback?.(unwrapNativeEvent(event));
66
+ }
67
+ },
68
+ [viewRef]
69
+ );
64
70
  }
65
71
 
66
72
  // src/components/PlayerView/index.tsx
@@ -71,10 +77,14 @@ var styles = import_react_native3.StyleSheet.create({
71
77
  });
72
78
  function dispatch(command, node, playerId) {
73
79
  const commandId = import_react_native3.Platform.OS === "android" ? import_react_native3.UIManager.NativePlayerView.Commands[command].toString() : import_react_native3.UIManager.getViewManagerConfig("NativePlayerView").Commands[command];
74
- import_react_native3.UIManager.dispatchViewManagerCommand(node, commandId, import_react_native3.Platform.select({
75
- ios: [playerId],
76
- android: [node, playerId]
77
- }));
80
+ import_react_native3.UIManager.dispatchViewManagerCommand(
81
+ node,
82
+ commandId,
83
+ import_react_native3.Platform.select({
84
+ ios: [playerId],
85
+ android: [node, playerId]
86
+ })
87
+ );
78
88
  }
79
89
  function PlayerView(props) {
80
90
  const nativeView = (0, import_react2.useRef)(null);
@@ -152,18 +162,27 @@ var Drm = class extends NativeInstance {
152
162
  });
153
163
  __publicField(this, "onPrepareCertificate", (certificate) => {
154
164
  if (this.config?.fairplay?.prepareCertificate) {
155
- DrmModule.setPreparedCertificate(this.nativeId, this.config?.fairplay?.prepareCertificate?.(certificate));
165
+ DrmModule.setPreparedCertificate(
166
+ this.nativeId,
167
+ this.config?.fairplay?.prepareCertificate?.(certificate)
168
+ );
156
169
  }
157
170
  });
158
171
  __publicField(this, "onPrepareMessage", (message, assetId) => {
159
172
  const config = import_react_native5.Platform.OS === "ios" ? this.config?.fairplay : this.config?.widevine;
160
173
  if (config && config.prepareMessage) {
161
- DrmModule.setPreparedMessage(this.nativeId, import_react_native5.Platform.OS === "ios" ? config.prepareMessage?.(message, assetId) : config.prepareMessage?.(message));
174
+ DrmModule.setPreparedMessage(
175
+ this.nativeId,
176
+ import_react_native5.Platform.OS === "ios" ? config.prepareMessage?.(message, assetId) : config.prepareMessage?.(message)
177
+ );
162
178
  }
163
179
  });
164
180
  __publicField(this, "onPrepareSyncMessage", (syncMessage, assetId) => {
165
181
  if (this.config?.fairplay?.prepareSyncMessage) {
166
- DrmModule.setPreparedSyncMessage(this.nativeId, this.config?.fairplay?.prepareSyncMessage?.(syncMessage, assetId));
182
+ DrmModule.setPreparedSyncMessage(
183
+ this.nativeId,
184
+ this.config?.fairplay?.prepareSyncMessage?.(syncMessage, assetId)
185
+ );
167
186
  }
168
187
  });
169
188
  __publicField(this, "onPrepareLicense", (license) => {
@@ -174,12 +193,18 @@ var Drm = class extends NativeInstance {
174
193
  });
175
194
  __publicField(this, "onPrepareLicenseServerUrl", (licenseServerUrl) => {
176
195
  if (this.config?.fairplay?.prepareLicenseServerUrl) {
177
- DrmModule.setPreparedLicenseServerUrl(this.nativeId, this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl));
196
+ DrmModule.setPreparedLicenseServerUrl(
197
+ this.nativeId,
198
+ this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl)
199
+ );
178
200
  }
179
201
  });
180
202
  __publicField(this, "onPrepareContentId", (contentId) => {
181
203
  if (this.config?.fairplay?.prepareContentId) {
182
- DrmModule.setPreparedContentId(this.nativeId, this.config?.fairplay?.prepareContentId?.(contentId));
204
+ DrmModule.setPreparedContentId(
205
+ this.nativeId,
206
+ this.config?.fairplay?.prepareContentId?.(contentId)
207
+ );
183
208
  }
184
209
  });
185
210
  }
@@ -218,7 +243,11 @@ var Source = class extends NativeInstance {
218
243
  if (this.config?.drmConfig) {
219
244
  this.drm = new Drm(this.config.drmConfig);
220
245
  this.drm.initialize();
221
- SourceModule.initWithDrmConfig(this.nativeId, this.drm.nativeId, this.config);
246
+ SourceModule.initWithDrmConfig(
247
+ this.nativeId,
248
+ this.drm.nativeId,
249
+ this.config
250
+ );
222
251
  } else {
223
252
  SourceModule.initWithConfig(this.nativeId, this.config);
224
253
  }
@@ -326,14 +355,18 @@ var Player = class extends NativeInstance {
326
355
  });
327
356
  __publicField(this, "isAirPlayActive", async () => {
328
357
  if (import_react_native7.Platform.OS === "android") {
329
- console.warn(`[Player ${this.nativeId}] Method isAirPlayActive is not available for Android. Only iOS devices.`);
358
+ console.warn(
359
+ `[Player ${this.nativeId}] Method isAirPlayActive is not available for Android. Only iOS devices.`
360
+ );
330
361
  return false;
331
362
  }
332
363
  return PlayerModule.isAirPlayActive(this.nativeId);
333
364
  });
334
365
  __publicField(this, "isAirPlayAvailable", async () => {
335
366
  if (import_react_native7.Platform.OS === "android") {
336
- console.warn(`[Player ${this.nativeId}] Method isAirPlayAvailable is not available for Android. Only iOS devices.`);
367
+ console.warn(
368
+ `[Player ${this.nativeId}] Method isAirPlayAvailable is not available for Android. Only iOS devices.`
369
+ );
337
370
  return false;
338
371
  }
339
372
  return PlayerModule.isAirPlayAvailable(this.nativeId);
package/lib/index.mjs CHANGED
@@ -26,12 +26,15 @@ function unwrapNativeEvent(event) {
26
26
  return omit(event.nativeEvent, ["target"]);
27
27
  }
28
28
  function useProxy(viewRef) {
29
- return useCallback((callback) => (event) => {
30
- const node = event.target._nativeTag;
31
- if (node === findNodeHandle(viewRef.current)) {
32
- callback?.(unwrapNativeEvent(event));
33
- }
34
- }, [viewRef]);
29
+ return useCallback(
30
+ (callback) => (event) => {
31
+ const node = event.target._nativeTag;
32
+ if (node === findNodeHandle(viewRef.current)) {
33
+ callback?.(unwrapNativeEvent(event));
34
+ }
35
+ },
36
+ [viewRef]
37
+ );
35
38
  }
36
39
 
37
40
  // src/components/PlayerView/index.tsx
@@ -42,10 +45,14 @@ var styles = StyleSheet.create({
42
45
  });
43
46
  function dispatch(command, node, playerId) {
44
47
  const commandId = Platform.OS === "android" ? UIManager.NativePlayerView.Commands[command].toString() : UIManager.getViewManagerConfig("NativePlayerView").Commands[command];
45
- UIManager.dispatchViewManagerCommand(node, commandId, Platform.select({
46
- ios: [playerId],
47
- android: [node, playerId]
48
- }));
48
+ UIManager.dispatchViewManagerCommand(
49
+ node,
50
+ commandId,
51
+ Platform.select({
52
+ ios: [playerId],
53
+ android: [node, playerId]
54
+ })
55
+ );
49
56
  }
50
57
  function PlayerView(props) {
51
58
  const nativeView = useRef(null);
@@ -123,18 +130,27 @@ var Drm = class extends NativeInstance {
123
130
  });
124
131
  __publicField(this, "onPrepareCertificate", (certificate) => {
125
132
  if (this.config?.fairplay?.prepareCertificate) {
126
- DrmModule.setPreparedCertificate(this.nativeId, this.config?.fairplay?.prepareCertificate?.(certificate));
133
+ DrmModule.setPreparedCertificate(
134
+ this.nativeId,
135
+ this.config?.fairplay?.prepareCertificate?.(certificate)
136
+ );
127
137
  }
128
138
  });
129
139
  __publicField(this, "onPrepareMessage", (message, assetId) => {
130
140
  const config = Platform2.OS === "ios" ? this.config?.fairplay : this.config?.widevine;
131
141
  if (config && config.prepareMessage) {
132
- DrmModule.setPreparedMessage(this.nativeId, Platform2.OS === "ios" ? config.prepareMessage?.(message, assetId) : config.prepareMessage?.(message));
142
+ DrmModule.setPreparedMessage(
143
+ this.nativeId,
144
+ Platform2.OS === "ios" ? config.prepareMessage?.(message, assetId) : config.prepareMessage?.(message)
145
+ );
133
146
  }
134
147
  });
135
148
  __publicField(this, "onPrepareSyncMessage", (syncMessage, assetId) => {
136
149
  if (this.config?.fairplay?.prepareSyncMessage) {
137
- DrmModule.setPreparedSyncMessage(this.nativeId, this.config?.fairplay?.prepareSyncMessage?.(syncMessage, assetId));
150
+ DrmModule.setPreparedSyncMessage(
151
+ this.nativeId,
152
+ this.config?.fairplay?.prepareSyncMessage?.(syncMessage, assetId)
153
+ );
138
154
  }
139
155
  });
140
156
  __publicField(this, "onPrepareLicense", (license) => {
@@ -145,12 +161,18 @@ var Drm = class extends NativeInstance {
145
161
  });
146
162
  __publicField(this, "onPrepareLicenseServerUrl", (licenseServerUrl) => {
147
163
  if (this.config?.fairplay?.prepareLicenseServerUrl) {
148
- DrmModule.setPreparedLicenseServerUrl(this.nativeId, this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl));
164
+ DrmModule.setPreparedLicenseServerUrl(
165
+ this.nativeId,
166
+ this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl)
167
+ );
149
168
  }
150
169
  });
151
170
  __publicField(this, "onPrepareContentId", (contentId) => {
152
171
  if (this.config?.fairplay?.prepareContentId) {
153
- DrmModule.setPreparedContentId(this.nativeId, this.config?.fairplay?.prepareContentId?.(contentId));
172
+ DrmModule.setPreparedContentId(
173
+ this.nativeId,
174
+ this.config?.fairplay?.prepareContentId?.(contentId)
175
+ );
154
176
  }
155
177
  });
156
178
  }
@@ -189,7 +211,11 @@ var Source = class extends NativeInstance {
189
211
  if (this.config?.drmConfig) {
190
212
  this.drm = new Drm(this.config.drmConfig);
191
213
  this.drm.initialize();
192
- SourceModule.initWithDrmConfig(this.nativeId, this.drm.nativeId, this.config);
214
+ SourceModule.initWithDrmConfig(
215
+ this.nativeId,
216
+ this.drm.nativeId,
217
+ this.config
218
+ );
193
219
  } else {
194
220
  SourceModule.initWithConfig(this.nativeId, this.config);
195
221
  }
@@ -297,14 +323,18 @@ var Player = class extends NativeInstance {
297
323
  });
298
324
  __publicField(this, "isAirPlayActive", async () => {
299
325
  if (Platform3.OS === "android") {
300
- console.warn(`[Player ${this.nativeId}] Method isAirPlayActive is not available for Android. Only iOS devices.`);
326
+ console.warn(
327
+ `[Player ${this.nativeId}] Method isAirPlayActive is not available for Android. Only iOS devices.`
328
+ );
301
329
  return false;
302
330
  }
303
331
  return PlayerModule.isAirPlayActive(this.nativeId);
304
332
  });
305
333
  __publicField(this, "isAirPlayAvailable", async () => {
306
334
  if (Platform3.OS === "android") {
307
- console.warn(`[Player ${this.nativeId}] Method isAirPlayAvailable is not available for Android. Only iOS devices.`);
335
+ console.warn(
336
+ `[Player ${this.nativeId}] Method isAirPlayAvailable is not available for Android. Only iOS devices.`
337
+ );
308
338
  return false;
309
339
  }
310
340
  return PlayerModule.isAirPlayAvailable(this.nativeId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitmovin-player-react-native",
3
- "version": "0.2.0",
3
+ "version": "0.3.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",
@@ -30,7 +30,7 @@
30
30
  "example": "yarn --cwd example",
31
31
  "pods": "cd example && pod-install --quiet",
32
32
  "bootstrap": "yarn && yarn example && yarn pods",
33
- "postinstall": "husky install"
33
+ "prepare": "husky install"
34
34
  },
35
35
  "keywords": [
36
36
  "react-native",
@@ -45,24 +45,28 @@
45
45
  "homepage": "https://github.com/bitmovin/bitmovin-player-react-native",
46
46
  "repository": "https://github.com/bitmovin/bitmovin-player-react-native",
47
47
  "devDependencies": {
48
+ "@babel/core": "7.19.3",
49
+ "@babel/runtime": "7.19.0",
48
50
  "@commitlint/config-conventional": "11.0.0",
49
- "@react-native-community/eslint-config": "3.0.2",
51
+ "@react-native-community/eslint-config": "3.1.0",
50
52
  "@types/jest": "26.0.24",
51
53
  "@types/lodash.omit": "4.5.0",
52
54
  "@types/react": "18.0.15",
53
55
  "@types/react-native": "0.69.2",
54
- "commitlint": "11.0.0",
55
- "eslint": "8.18.0",
56
+ "babel-plugin-module-resolver": "4.1.0",
57
+ "commitlint": "17.1.2",
58
+ "eslint": "8.24.0",
56
59
  "eslint-config-prettier": "8.5.0",
57
- "eslint-plugin-prettier": "4.0.0",
60
+ "eslint-plugin-prettier": "4.2.1",
58
61
  "husky": "8.0.1",
59
62
  "jest": "26.6.3",
60
63
  "lint-staged": "13.0.3",
61
- "pod-install": "0.1.37",
64
+ "metro-config": "0.72.3",
65
+ "metro-react-native-babel-preset": "0.72.3",
66
+ "pod-install": "0.1.38",
62
67
  "prettier": "2.7.1",
63
- "react": "17.0.2",
64
- "tsup": "5.12.9",
65
- "typescript": "4.5.5"
68
+ "tsup": "6.2.3",
69
+ "typescript": "4.8.4"
66
70
  },
67
71
  "dependencies": {
68
72
  "lodash.omit": "4.5.0"
package/src/player.ts CHANGED
@@ -28,6 +28,87 @@ export interface PlayerConfig extends NativeInstanceConfig {
28
28
  * ```
29
29
  */
30
30
  licenseKey?: string;
31
+ /**
32
+ * Configures playback behaviour. A default PlaybackConfig is set initially.
33
+ */
34
+ playbackConfig?: PlaybackConfig;
35
+ }
36
+
37
+ /**
38
+ * Configures the playback behaviour of the player.
39
+ */
40
+ export interface PlaybackConfig {
41
+ /**
42
+ * Whether the player starts playing automatically after loading a source or not. Default is `false`.
43
+ * @example
44
+ * ```
45
+ * const player = new Player({
46
+ * playbackConfig: {
47
+ * isAutoplayEnabled: true,
48
+ * },
49
+ * });
50
+ * ```
51
+ */
52
+ isAutoplayEnabled?: boolean;
53
+ /**
54
+ * Whether the sound is muted on startup or not. Default value is `false`.
55
+ * @example
56
+ * ```
57
+ * const player = new Player({
58
+ * playbackConfig: {
59
+ * isMuted: true,
60
+ * },
61
+ * });
62
+ * ```
63
+ */
64
+ isMuted?: boolean;
65
+ /**
66
+ * Whether time shift / DVR for live streams is enabled or not. Default is `true`.
67
+ * @example
68
+ * ```
69
+ * const player = new Player({
70
+ * playbackConfig: {
71
+ * isTimeShiftEnabled: false,
72
+ * },
73
+ * });
74
+ * ```
75
+ */
76
+ isTimeShiftEnabled?: boolean;
77
+ /**
78
+ * Whether background playback is enabled or not.
79
+ * Default is `false`.
80
+ *
81
+ * When set to `true`, playback is not automatically paused
82
+ * anymore when the app moves to the background.
83
+ * When set to `true`, also make sure to properly configure your app to allow
84
+ * background playback.
85
+ *
86
+ * On tvOS, background playback is only supported for audio-only content.
87
+ *
88
+ * Default is `false`.
89
+ *
90
+ * @example
91
+ * ```
92
+ * const player = new Player({
93
+ * {
94
+ * isBackgroundPlaybackEnabled: true,
95
+ * }
96
+ * })
97
+ * ```
98
+ */
99
+ isBackgroundPlaybackEnabled?: boolean;
100
+ /**
101
+ * Whether the picture-in-picture mode option is enabled for iOS or not. Default is `false`.
102
+ * @example
103
+ * ```
104
+ * const player = new Player({
105
+ * playbackConfig: {
106
+ * isPictureInPictureEnabled: true,
107
+ * },
108
+ * });
109
+ * ```
110
+ */
111
+ isPictureInPictureEnabled?: boolean;
31
112
  }
32
113
 
33
114
  /**