bitmovin-player-react-native 0.9.2 → 0.10.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 (34) hide show
  1. package/RNBitmovinPlayer.podspec +1 -1
  2. package/android/build.gradle +1 -2
  3. package/android/src/main/java/com/bitmovin/player/reactnative/AnalyticsModule.kt +43 -11
  4. package/android/src/main/java/com/bitmovin/player/reactnative/OfflineModule.kt +279 -0
  5. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +37 -1
  6. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +1 -0
  7. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +123 -35
  8. package/android/src/main/java/com/bitmovin/player/reactnative/offline/OfflineContentManagerBridge.kt +216 -0
  9. package/android/src/main/java/com/bitmovin/player/reactnative/offline/OfflineDownloadRequest.kt +7 -0
  10. package/ios/DrmModule.swift +5 -5
  11. package/ios/OfflineContentManagerBridge.swift +141 -0
  12. package/ios/OfflineModule.m +19 -0
  13. package/ios/OfflineModule.swift +465 -0
  14. package/ios/PlayerModule.m +2 -0
  15. package/ios/PlayerModule.swift +40 -7
  16. package/ios/RCTConvert+BitmovinPlayer.swift +135 -1
  17. package/ios/RNBitmovinPlayer.h +1 -0
  18. package/lib/index.d.mts +382 -2
  19. package/lib/index.d.ts +382 -2
  20. package/lib/index.js +233 -0
  21. package/lib/index.mjs +231 -0
  22. package/package.json +1 -1
  23. package/src/adaptationConfig.ts +10 -0
  24. package/src/index.ts +2 -0
  25. package/src/offline/index.ts +7 -0
  26. package/src/offline/offlineContentConfig.ts +18 -0
  27. package/src/offline/offlineContentManager.ts +216 -0
  28. package/src/offline/offlineContentManagerListener.ts +187 -0
  29. package/src/offline/offlineContentOptions.ts +29 -0
  30. package/src/offline/offlineDownloadRequest.ts +20 -0
  31. package/src/offline/offlineSourceOptions.ts +11 -0
  32. package/src/offline/offlineState.ts +22 -0
  33. package/src/player.ts +30 -0
  34. package/src/source.ts +38 -0
@@ -0,0 +1,216 @@
1
+ import {
2
+ EmitterSubscription,
3
+ NativeEventEmitter,
4
+ NativeModule,
5
+ NativeModules,
6
+ } from 'react-native';
7
+ import NativeInstance from '../nativeInstance';
8
+ import { SourceConfig } from '../source';
9
+ import {
10
+ BitmovinNativeOfflineEventData,
11
+ handleBitmovinNativeOfflineEvent,
12
+ OfflineContentManagerListener,
13
+ } from './offlineContentManagerListener';
14
+ import { OfflineContentConfig } from './offlineContentConfig';
15
+ import { OfflineDownloadRequest } from './offlineDownloadRequest';
16
+ import { OfflineState } from './offlineState';
17
+ import { Drm } from 'bitmovin-player-react-native';
18
+
19
+ interface NativeOfflineModule extends NativeModule {
20
+ initWithConfig(
21
+ nativeId: string,
22
+ config: { identifier: string; sourceConfig: SourceConfig },
23
+ drmNativeId: string | undefined
24
+ ): Promise<void>;
25
+ getState(nativeId: string): Promise<OfflineState>;
26
+ getOptions(nativeId: string): Promise<void>;
27
+ download(nativeId: string, request: OfflineDownloadRequest): Promise<void>;
28
+ resume(nativeId: string): Promise<void>;
29
+ suspend(nativeId: string): Promise<void>;
30
+ cancelDownload(nativeId: string): Promise<void>;
31
+ usedStorage(nativeId: string): Promise<number>;
32
+ deleteAll(nativeId: string): Promise<void>;
33
+ downloadLicense(nativeId: string): Promise<void>;
34
+ releaseLicense(nativeId: string): Promise<void>;
35
+ renewOfflineLicense(nativeId: string): Promise<void>;
36
+ release(nativeId: string): Promise<void>;
37
+ }
38
+
39
+ const OfflineModule =
40
+ NativeModules.BitmovinOfflineModule as NativeOfflineModule;
41
+
42
+ /**
43
+ * Provides the means to download and store sources locally that can be played back with a Player
44
+ * without an active network connection. An OfflineContentManager instance can be created via
45
+ * the constructor and will be idle until initialized.
46
+ *
47
+ * @platform Android, iOS
48
+ */
49
+ export class OfflineContentManager extends NativeInstance<OfflineContentConfig> {
50
+ isInitialized = false;
51
+ isDestroyed = false;
52
+ eventSubscription?: EmitterSubscription = undefined;
53
+ listeners: Set<OfflineContentManagerListener> =
54
+ new Set<OfflineContentManagerListener>();
55
+ drm?: Drm;
56
+
57
+ constructor(config: OfflineContentConfig) {
58
+ super(config);
59
+ }
60
+
61
+ /**
62
+ * Allocates the native `OfflineManager` instance and its resources natively.
63
+ * Registers the `DeviceEventEmitter` listener to receive data from the native `OfflineContentManagerListener` callbacks
64
+ */
65
+ initialize = async (): Promise<void> => {
66
+ let initPromise = Promise.resolve();
67
+ if (!this.isInitialized && this.config) {
68
+ this.eventSubscription = new NativeEventEmitter(
69
+ OfflineModule
70
+ ).addListener(
71
+ 'BitmovinOfflineEvent',
72
+ (data?: BitmovinNativeOfflineEventData) => {
73
+ if (this.nativeId !== data?.nativeId) {
74
+ return;
75
+ }
76
+
77
+ handleBitmovinNativeOfflineEvent(data, this.listeners);
78
+ }
79
+ );
80
+
81
+ if (this.config.sourceConfig.drmConfig) {
82
+ this.drm = new Drm(this.config.sourceConfig.drmConfig);
83
+ this.drm.initialize();
84
+ }
85
+
86
+ initPromise = OfflineModule.initWithConfig(
87
+ this.nativeId,
88
+ {
89
+ identifier: this.config.identifier,
90
+ sourceConfig: this.config.sourceConfig,
91
+ },
92
+ this.drm?.nativeId
93
+ );
94
+ }
95
+
96
+ this.isInitialized = true;
97
+ return initPromise;
98
+ };
99
+
100
+ /**
101
+ * Adds a listener to the receive data from the native `OfflineContentManagerListener` callbacks
102
+ * Returns a function that removes this listener from the `OfflineContentManager` that registered it.
103
+ */
104
+ addListener = (listener: OfflineContentManagerListener): (() => void) => {
105
+ this.listeners.add(listener);
106
+
107
+ return () => {
108
+ this.listeners.delete(listener);
109
+ };
110
+ };
111
+
112
+ /**
113
+ * Destroys the native `OfflineManager` and releases all of its allocated resources.
114
+ */
115
+ destroy = async (): Promise<void> => {
116
+ if (!this.isDestroyed) {
117
+ this.isDestroyed = true;
118
+ this.eventSubscription?.remove?.();
119
+ this.listeners.clear();
120
+ this.drm?.destroy();
121
+
122
+ return OfflineModule.release(this.nativeId);
123
+ }
124
+
125
+ return Promise.resolve();
126
+ };
127
+
128
+ /**
129
+ * Gets the current state of the `OfflineContentManager`
130
+ */
131
+ state = async (): Promise<OfflineState> => {
132
+ return OfflineModule.getState(this.nativeId);
133
+ };
134
+
135
+ /**
136
+ * Loads the current `OfflineContentOptions`.
137
+ * When the options are loaded the data will be passed to the `OfflineContentManagerListener.onOptionsAvailable`.
138
+ */
139
+ getOptions = async (): Promise<void> => {
140
+ return OfflineModule.getOptions(this.nativeId);
141
+ };
142
+
143
+ /**
144
+ * Enqueues downloads according to the `OfflineDownloadRequest`.
145
+ * The promise will reject in the event of null or invalid request parameters.
146
+ * The promise will reject when calling this method when download has already started or is completed.
147
+ * The promise will resolve when the download has been queued. The download will is not finished when the promise resolves.
148
+ */
149
+ download = async (request: OfflineDownloadRequest): Promise<void> => {
150
+ return OfflineModule.download(this.nativeId, request);
151
+ };
152
+
153
+ /**
154
+ * Resumes all suspended actions.
155
+ */
156
+ resume = async (): Promise<void> => {
157
+ return OfflineModule.resume(this.nativeId);
158
+ };
159
+
160
+ /**
161
+ * Suspends all active actions.
162
+ */
163
+ suspend = async (): Promise<void> => {
164
+ return OfflineModule.suspend(this.nativeId);
165
+ };
166
+
167
+ /**
168
+ * Cancels and deletes the active download.
169
+ */
170
+ cancelDownload = async (): Promise<void> => {
171
+ return OfflineModule.cancelDownload(this.nativeId);
172
+ };
173
+
174
+ /**
175
+ * Resolves how many bytes of storage are used by the offline content.
176
+ */
177
+ usedStorage = async (): Promise<number> => {
178
+ return OfflineModule.usedStorage(this.nativeId);
179
+ };
180
+
181
+ /**
182
+ * Deletes everything related to the related content ID.
183
+ */
184
+ deleteAll = async (): Promise<void> => {
185
+ return OfflineModule.deleteAll(this.nativeId);
186
+ };
187
+
188
+ /**
189
+ * Downloads the offline license.
190
+ * When finished successfully, data will be passed to the `OfflineContentManagerListener.onDrmLicenseUpdated`.
191
+ * Errors are transmitted to the `OfflineContentManagerListener.onError`.
192
+ */
193
+ downloadLicense = async (): Promise<void> => {
194
+ return OfflineModule.downloadLicense(this.nativeId);
195
+ };
196
+
197
+ /**
198
+ * Releases the currently held offline license.
199
+ * When finished successfully data will be passed to the `OfflineContentManagerListener.onDrmLicenseUpdated`.
200
+ * Errors are transmitted to the `OfflineContentManagerListener.onError`.
201
+ *
202
+ * @platform Android
203
+ */
204
+ releaseLicense = async (): Promise<void> => {
205
+ return OfflineModule.releaseLicense(this.nativeId);
206
+ };
207
+
208
+ /**
209
+ * Renews the already downloaded DRM license.
210
+ * When finished successfully data will be passed to the `OfflineContentManagerListener.onDrmLicenseUpdated`.
211
+ * Errors are transmitted to the `OfflineContentManagerListener.onError`.
212
+ */
213
+ renewOfflineLicense = async (): Promise<void> => {
214
+ return OfflineModule.renewOfflineLicense(this.nativeId);
215
+ };
216
+ }
@@ -0,0 +1,187 @@
1
+ import { OfflineContentOptions } from './offlineContentOptions';
2
+ import { OfflineState } from './offlineState';
3
+
4
+ /**
5
+ * Enum to hold the `eventType` on the `BitmovinNativeOfflineEventData`
6
+ * @platform Android, iOS
7
+ */
8
+ export enum OfflineEventType {
9
+ onCompleted = 'onCompleted',
10
+ onError = 'onError',
11
+ onProgress = 'onProgress',
12
+ onOptionsAvailable = 'onOptionsAvailable',
13
+ onDrmLicenseUpdated = 'onDrmLicenseUpdated',
14
+ onDrmLicenseExpired = 'onDrmLicenseExpired',
15
+ onSuspended = 'onSuspended',
16
+ onResumed = 'onResumed',
17
+ onCanceled = 'onCanceled',
18
+ }
19
+
20
+ /**
21
+ * The base interface for all offline events.
22
+ * @platform Android, iOS
23
+ */
24
+ export interface OfflineEvent<T extends OfflineEventType> {
25
+ /**
26
+ * The native id associated with the `OfflineContentManager` emitting this event
27
+ */
28
+ nativeId: string;
29
+ /**
30
+ * The supplied id representing the source associated with the `OfflineContentManager` emitting this event.
31
+ */
32
+ identifier: string;
33
+ /**
34
+ * The `OfflineEventType` that correlates to which native `OfflineContentManagerListener` method was called.
35
+ */
36
+ eventType: T;
37
+ /**
38
+ * The current offline download state
39
+ */
40
+ state: OfflineState;
41
+ }
42
+
43
+ /**
44
+ * Emitted when the download process has completed.
45
+ * @platform Android, iOS
46
+ */
47
+ export interface OnCompletedEvent
48
+ extends OfflineEvent<OfflineEventType.onCompleted> {
49
+ /**
50
+ * The options that are available to download
51
+ */
52
+ options?: OfflineContentOptions;
53
+ }
54
+
55
+ /**
56
+ * Emitted when an error has occurred.
57
+ * @platform Android, iOS
58
+ */
59
+ export interface OnErrorEvent extends OfflineEvent<OfflineEventType.onError> {
60
+ /**
61
+ * The error code of the process error
62
+ */
63
+ code?: number;
64
+ /**
65
+ * The error message of the process error
66
+ */
67
+ message?: string;
68
+ }
69
+
70
+ /**
71
+ * Emitted when there is a progress change for the process call.
72
+ * @platform Android, iOS
73
+ */
74
+ export interface OnProgressEvent
75
+ extends OfflineEvent<OfflineEventType.onProgress> {
76
+ /**
77
+ * The progress for the current process
78
+ */
79
+ progress: number;
80
+ }
81
+
82
+ /**
83
+ * Emitted when the `OfflineContentOptions` is available after a `OfflineContentManager.getOptions` call.
84
+ * @platform Android, iOS
85
+ */
86
+ export interface OnOptionsAvailableEvent
87
+ extends OfflineEvent<OfflineEventType.onOptionsAvailable> {
88
+ /**
89
+ * The options that are available to download
90
+ */
91
+ options?: OfflineContentOptions;
92
+ }
93
+
94
+ /**
95
+ * Emitted when the DRM license was updated.
96
+ * @platform Android, iOS
97
+ */
98
+ export interface OnDrmLicenseUpdatedEvent
99
+ extends OfflineEvent<OfflineEventType.onDrmLicenseUpdated> {}
100
+
101
+ /**
102
+ * Emitted when the DRM license has expired.
103
+ * @platform iOS
104
+ */
105
+ export interface OnDrmLicenseExpiredEvent
106
+ extends OfflineEvent<OfflineEventType.onDrmLicenseExpired> {}
107
+
108
+ /**
109
+ * Emitted when all active actions have been suspended.
110
+ * @platform Android, iOS
111
+ */
112
+ export interface OnSuspendedEvent
113
+ extends OfflineEvent<OfflineEventType.onSuspended> {}
114
+
115
+ /**
116
+ * Emitted when all actions have been resumed.
117
+ * @platform Android, iOS
118
+ */
119
+ export interface OnResumedEvent
120
+ extends OfflineEvent<OfflineEventType.onResumed> {}
121
+
122
+ /**
123
+ * Emitted when the download of the media content was canceled by the user and all partially downloaded content has been deleted from disk.
124
+ * @platform Android, iOS
125
+ */
126
+ export interface OnCanceledEvent
127
+ extends OfflineEvent<OfflineEventType.onCanceled> {}
128
+
129
+ /**
130
+ * The type aggregation for all possible native offline events received from the `DeviceEventEmitter`
131
+ * @platform Android, iOS
132
+ */
133
+ export type BitmovinNativeOfflineEventData =
134
+ | OnCompletedEvent
135
+ | OnOptionsAvailableEvent
136
+ | OnProgressEvent
137
+ | OnErrorEvent
138
+ | OnDrmLicenseUpdatedEvent
139
+ | OnDrmLicenseExpiredEvent
140
+ | OnSuspendedEvent
141
+ | OnResumedEvent
142
+ | OnCanceledEvent;
143
+
144
+ /**
145
+ * The listener that can be passed to the `OfflineContentManager` to receive callbacks for different events.
146
+ * @platform Android, iOS
147
+ */
148
+ export interface OfflineContentManagerListener {
149
+ onCompleted?: (e: OnCompletedEvent) => void;
150
+ onError?: (e: OnErrorEvent) => void;
151
+ onProgress?: (e: OnProgressEvent) => void;
152
+ onOptionsAvailable?: (e: OnOptionsAvailableEvent) => void;
153
+ onDrmLicenseUpdated?: (e: OnDrmLicenseUpdatedEvent) => void;
154
+ onDrmLicenseExpired?: (e: OnDrmLicenseExpiredEvent) => void;
155
+ onSuspended?: (e: OnSuspendedEvent) => void;
156
+ onResumed?: (e: OnResumedEvent) => void;
157
+ onCanceled?: (e: OnCanceledEvent) => void;
158
+ }
159
+
160
+ export const handleBitmovinNativeOfflineEvent = (
161
+ data: BitmovinNativeOfflineEventData,
162
+ listeners: Set<OfflineContentManagerListener>
163
+ ) => {
164
+ listeners.forEach((listener) => {
165
+ if (!listener) return;
166
+
167
+ if (data.eventType === OfflineEventType.onCompleted) {
168
+ listener.onCompleted?.(data);
169
+ } else if (data.eventType === OfflineEventType.onError) {
170
+ listener.onError?.(data);
171
+ } else if (data.eventType === OfflineEventType.onProgress) {
172
+ listener.onProgress?.(data);
173
+ } else if (data.eventType === OfflineEventType.onOptionsAvailable) {
174
+ listener.onOptionsAvailable?.(data);
175
+ } else if (data.eventType === OfflineEventType.onDrmLicenseUpdated) {
176
+ listener.onDrmLicenseUpdated?.(data);
177
+ } else if (data.eventType === OfflineEventType.onDrmLicenseExpired) {
178
+ listener.onDrmLicenseExpired?.(data);
179
+ } else if (data.eventType === OfflineEventType.onSuspended) {
180
+ listener.onSuspended?.(data);
181
+ } else if (data.eventType === OfflineEventType.onResumed) {
182
+ listener.onResumed?.(data);
183
+ } else if (data.eventType === OfflineEventType.onCanceled) {
184
+ listener.onCanceled?.(data);
185
+ }
186
+ });
187
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Superclass of entries which can be selected to download for offline playback
3
+ * @platform Android, iOS
4
+ */
5
+ export interface OfflineContentOptionEntry {
6
+ /**
7
+ * The ID of the option.
8
+ */
9
+ id: string;
10
+ /**
11
+ * The language of the option.
12
+ */
13
+ language?: string;
14
+ }
15
+
16
+ /**
17
+ * Represents the downloadable options provided via the `onOptionsAvailable` callback on `OfflineContentManagerListener`
18
+ * @platform Android, iOS
19
+ */
20
+ export interface OfflineContentOptions {
21
+ /**
22
+ * Represents the audio options available for download
23
+ */
24
+ audioOptions: OfflineContentOptionEntry[];
25
+ /**
26
+ * Represents the text options available for download
27
+ */
28
+ textOptions: OfflineContentOptionEntry[];
29
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Represents the configuration to start a download.
3
+ * @platform Android, iOS
4
+ */
5
+ export interface OfflineDownloadRequest {
6
+ /**
7
+ * Minimum video bitrate to download. The nearest higher available bitrate will be selected.
8
+ */
9
+ minimumBitrate?: number;
10
+
11
+ /**
12
+ * Audio tracks with IDs to download.
13
+ */
14
+ audioOptionIds?: string[];
15
+
16
+ /**
17
+ * Text tracks with IDs to download.
18
+ */
19
+ textOptionIds?: string[];
20
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Object used configure how the native offline managers create and get offline source configurations
3
+ * @platform Android, iOS
4
+ */
5
+ export interface OfflineSourceOptions {
6
+ /**
7
+ * Whether or not the player should restrict playback only to audio, video and subtitle tracks which are stored offline on the device. This has to be set to true if the device has no network access.
8
+ * @platform iOS
9
+ */
10
+ restrictedToAssetCache?: boolean;
11
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Contains the state an OfflineContentManager can have.
3
+ * @platform Android, iOS
4
+ */
5
+ export enum OfflineState {
6
+ /**
7
+ * The offline content is downloaded and ready for offline playback.
8
+ */
9
+ Downloaded = 'Downloaded',
10
+ /**
11
+ * The offline content is currently downloading.
12
+ */
13
+ Downloading = 'Downloading',
14
+ /**
15
+ * The download of the offline content is suspended, and is only partly downloaded yet.
16
+ */
17
+ Suspended = 'Suspended',
18
+ /**
19
+ * The offline content is not downloaded. However, some data may be still cached.
20
+ */
21
+ NotDownloaded = 'NotDownloaded',
22
+ }
package/src/player.ts CHANGED
@@ -7,6 +7,8 @@ import { AudioTrack } from './audioTrack';
7
7
  import { SubtitleTrack } from './subtitleTrack';
8
8
  import { StyleConfig } from './styleConfig';
9
9
  import { TweaksConfig } from './tweaksConfig';
10
+ import { AdaptationConfig } from './adaptationConfig';
11
+ import { OfflineContentManager, OfflineSourceOptions } from './offline';
10
12
 
11
13
  const PlayerModule = NativeModules.PlayerModule;
12
14
 
@@ -53,6 +55,10 @@ export interface PlayerConfig extends NativeInstanceConfig {
53
55
  * Configures analytics functionality.
54
56
  */
55
57
  analyticsConfig?: AnalyticsConfig;
58
+ /**
59
+ * Configures adaptation logic.
60
+ */
61
+ adaptationConfig?: AdaptationConfig;
56
62
  }
57
63
 
58
64
  /**
@@ -194,6 +200,20 @@ export class Player extends NativeInstance<PlayerConfig> {
194
200
  this.loadSource(new Source(sourceConfig));
195
201
  };
196
202
 
203
+ /**
204
+ * Loads the downloaded content from `OfflineContentManager` into the player.
205
+ */
206
+ loadOfflineContent = (
207
+ offlineContentManager: OfflineContentManager,
208
+ options?: OfflineSourceOptions
209
+ ) => {
210
+ PlayerModule.loadOfflineContent(
211
+ this.nativeId,
212
+ offlineContentManager.nativeId,
213
+ options
214
+ );
215
+ };
216
+
197
217
  /**
198
218
  * Loads the given `Source` into the player.
199
219
  */
@@ -428,4 +448,14 @@ export class Player extends NativeInstance<PlayerConfig> {
428
448
  getMaxTimeShift = async (): Promise<number> => {
429
449
  return PlayerModule.getMaxTimeShift(this.nativeId);
430
450
  };
451
+
452
+ /**
453
+ * Sets the upper bitrate boundary for video qualities. All qualities with a bitrate
454
+ * that is higher than this threshold will not be eligible for automatic quality selection.
455
+ *
456
+ * Can be set to `undefined` for no limitation.
457
+ */
458
+ setMaxSelectableBitrate = (bitrate: number | null) => {
459
+ PlayerModule.setMaxSelectableBitrate(this.nativeId, bitrate || -1);
460
+ };
431
461
  }
package/src/source.ts CHANGED
@@ -45,6 +45,40 @@ export enum LoadingState {
45
45
  LOADED = 2,
46
46
  }
47
47
 
48
+ /**
49
+ * Types of SourceOptions.
50
+ */
51
+ export interface SourceOptions {
52
+ /**
53
+ * The position where the stream should be started.
54
+ * Number can be positive or negative depending on the used `TimelineReferencePoint`.
55
+ * Invalid numbers will be corrected according to the stream boundaries.
56
+ * For VOD this is applied at the time the stream is loaded, for LIVE when playback starts.
57
+ */
58
+ startOffset?: number;
59
+ /**
60
+ * Sets the Timeline reference point to calculate the startOffset from.
61
+ * Default for live: `TimelineReferencePoint.END`.
62
+ * Default for VOD: `TimelineReferencePoint.START`.
63
+ */
64
+ startOffsetTimelineReference?: TimelineReferencePoint;
65
+ }
66
+
67
+ /**
68
+ Timeline reference point to calculate SourceOptions.startOffset from.
69
+ Default for live: TimelineReferencePoint.EBD Default for VOD: TimelineReferencePoint.START.
70
+ */
71
+ export enum TimelineReferencePoint {
72
+ /**
73
+ * Relative offset will be calculated from the beginning of the stream or DVR window.
74
+ */
75
+ START = 'start',
76
+ /**
77
+ * Relative offset will be calculated from the end of the stream or the live edge in case of a live stream with DVR window.
78
+ */
79
+ END = 'end',
80
+ }
81
+
48
82
  /**
49
83
  * Represents a source configuration that be loaded into a player instance.
50
84
  */
@@ -86,6 +120,10 @@ export interface SourceConfig extends NativeInstanceConfig {
86
120
  * The optional custom metadata. Also sent to the cast receiver when loading the Source.
87
121
  */
88
122
  metadata?: Record<string, string>;
123
+ /**
124
+ * The `SourceOptions` for this configuration.
125
+ */
126
+ options?: SourceOptions;
89
127
  }
90
128
 
91
129
  /**