-
Notifications
You must be signed in to change notification settings - Fork 12
/
offlineContentManager.ts
245 lines (218 loc) · 7.96 KB
/
offlineContentManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
import {
EmitterSubscription,
NativeEventEmitter,
NativeModule,
NativeModules,
} from 'react-native';
import NativeInstance from '../nativeInstance';
import { SourceConfig } from '../source';
import {
BitmovinNativeOfflineEventData,
OfflineContentManagerListener,
OfflineEventType,
} from './offlineContentManagerListener';
import { OfflineContentConfig } from './offlineContentConfig';
import { OfflineDownloadRequest } from './offlineDownloadRequest';
import { OfflineState } from './offlineState';
import { Drm } from 'bitmovin-player-react-native';
interface NativeOfflineModule extends NativeModule {
initWithConfig(
nativeId: string,
config: { identifier: string; sourceConfig: SourceConfig },
drmNativeId: string | undefined
): Promise<void>;
getState(nativeId: string): Promise<OfflineState>;
getOptions(nativeId: string): Promise<void>;
download(nativeId: string, request: OfflineDownloadRequest): Promise<void>;
resume(nativeId: string): Promise<void>;
suspend(nativeId: string): Promise<void>;
cancelDownload(nativeId: string): Promise<void>;
usedStorage(nativeId: string): Promise<number>;
deleteAll(nativeId: string): Promise<void>;
downloadLicense(nativeId: string): Promise<void>;
releaseLicense(nativeId: string): Promise<void>;
renewOfflineLicense(nativeId: string): Promise<void>;
release(nativeId: string): Promise<void>;
}
const OfflineModule =
NativeModules.BitmovinOfflineModule as NativeOfflineModule;
const handleBitmovinNativeOfflineEvent = (
data: BitmovinNativeOfflineEventData,
listeners: Set<OfflineContentManagerListener>
) => {
listeners.forEach((listener) => {
if (!listener) return;
if (data.eventType === OfflineEventType.onCompleted) {
listener.onCompleted?.(data);
} else if (data.eventType === OfflineEventType.onError) {
listener.onError?.(data);
} else if (data.eventType === OfflineEventType.onProgress) {
listener.onProgress?.(data);
} else if (data.eventType === OfflineEventType.onOptionsAvailable) {
listener.onOptionsAvailable?.(data);
} else if (data.eventType === OfflineEventType.onDrmLicenseUpdated) {
listener.onDrmLicenseUpdated?.(data);
} else if (data.eventType === OfflineEventType.onDrmLicenseExpired) {
listener.onDrmLicenseExpired?.(data);
} else if (data.eventType === OfflineEventType.onSuspended) {
listener.onSuspended?.(data);
} else if (data.eventType === OfflineEventType.onResumed) {
listener.onResumed?.(data);
} else if (data.eventType === OfflineEventType.onCanceled) {
listener.onCanceled?.(data);
}
});
};
/**
* Provides the means to download and store sources locally that can be played back with a Player
* without an active network connection. An OfflineContentManager instance can be created via
* the constructor and will be idle until initialized.
*
* @platform Android, iOS
*/
export class OfflineContentManager extends NativeInstance<OfflineContentConfig> {
isInitialized = false;
isDestroyed = false;
private eventSubscription?: EmitterSubscription = undefined;
private listeners: Set<OfflineContentManagerListener> =
new Set<OfflineContentManagerListener>();
private drm?: Drm;
constructor(config: OfflineContentConfig) {
super(config);
}
/**
* Allocates the native `OfflineManager` instance and its resources natively.
* Registers the `DeviceEventEmitter` listener to receive data from the native `OfflineContentManagerListener` callbacks
*/
initialize = async (): Promise<void> => {
let initPromise = Promise.resolve();
if (!this.isInitialized && this.config) {
this.eventSubscription = new NativeEventEmitter(
OfflineModule
).addListener(
'BitmovinOfflineEvent',
(data?: BitmovinNativeOfflineEventData) => {
if (this.nativeId !== data?.nativeId) {
return;
}
handleBitmovinNativeOfflineEvent(data, this.listeners);
}
);
if (this.config.sourceConfig.drmConfig) {
this.drm = new Drm(this.config.sourceConfig.drmConfig);
this.drm.initialize();
}
initPromise = OfflineModule.initWithConfig(
this.nativeId,
{
identifier: this.config.identifier,
sourceConfig: this.config.sourceConfig,
},
this.drm?.nativeId
);
}
this.isInitialized = true;
return initPromise;
};
/**
* Adds a listener to the receive data from the native `OfflineContentManagerListener` callbacks
* Returns a function that removes this listener from the `OfflineContentManager` that registered it.
*/
addListener = (listener: OfflineContentManagerListener): (() => void) => {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
};
/**
* Destroys the native `OfflineManager` and releases all of its allocated resources.
*/
destroy = async (): Promise<void> => {
if (!this.isDestroyed) {
this.isDestroyed = true;
this.eventSubscription?.remove?.();
this.listeners.clear();
this.drm?.destroy();
return OfflineModule.release(this.nativeId);
}
return Promise.resolve();
};
/**
* Gets the current state of the `OfflineContentManager`
*/
state = async (): Promise<OfflineState> => {
return OfflineModule.getState(this.nativeId);
};
/**
* Loads the current `OfflineContentOptions`.
* When the options are loaded the data will be passed to the `OfflineContentManagerListener.onOptionsAvailable`.
*/
getOptions = async (): Promise<void> => {
return OfflineModule.getOptions(this.nativeId);
};
/**
* Enqueues downloads according to the `OfflineDownloadRequest`.
* The promise will reject in the event of null or invalid request parameters.
* The promise will reject when calling this method when download has already started or is completed.
* The promise will resolve when the download has been queued. The download will is not finished when the promise resolves.
*/
download = async (request: OfflineDownloadRequest): Promise<void> => {
return OfflineModule.download(this.nativeId, request);
};
/**
* Resumes all suspended actions.
*/
resume = async (): Promise<void> => {
return OfflineModule.resume(this.nativeId);
};
/**
* Suspends all active actions.
*/
suspend = async (): Promise<void> => {
return OfflineModule.suspend(this.nativeId);
};
/**
* Cancels and deletes the active download.
*/
cancelDownload = async (): Promise<void> => {
return OfflineModule.cancelDownload(this.nativeId);
};
/**
* Resolves how many bytes of storage are used by the offline content.
*/
usedStorage = async (): Promise<number> => {
return OfflineModule.usedStorage(this.nativeId);
};
/**
* Deletes everything related to the related content ID.
*/
deleteAll = async (): Promise<void> => {
return OfflineModule.deleteAll(this.nativeId);
};
/**
* Downloads the offline license.
* When finished successfully, data will be passed to the `OfflineContentManagerListener.onDrmLicenseUpdated`.
* Errors are transmitted to the `OfflineContentManagerListener.onError`.
*/
downloadLicense = async (): Promise<void> => {
return OfflineModule.downloadLicense(this.nativeId);
};
/**
* Releases the currently held offline license.
* When finished successfully data will be passed to the `OfflineContentManagerListener.onDrmLicenseUpdated`.
* Errors are transmitted to the `OfflineContentManagerListener.onError`.
*
* @platform Android
*/
releaseLicense = async (): Promise<void> => {
return OfflineModule.releaseLicense(this.nativeId);
};
/**
* Renews the already downloaded DRM license.
* When finished successfully data will be passed to the `OfflineContentManagerListener.onDrmLicenseUpdated`.
* Errors are transmitted to the `OfflineContentManagerListener.onError`.
*/
renewOfflineLicense = async (): Promise<void> => {
return OfflineModule.renewOfflineLicense(this.nativeId);
};
}