@playkit-js/playkit-js-providers 2.40.1 → 2.40.2-canary.0-c7a43ae

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 (135) hide show
  1. package/dist/index.d.ts +1624 -0
  2. package/dist/playkit-analytics-service.js +1 -1
  3. package/dist/playkit-analytics-service.js.map +1 -1
  4. package/dist/playkit-bookmark-service.js +1 -1
  5. package/dist/playkit-bookmark-service.js.map +1 -1
  6. package/dist/playkit-ott-provider.js +1 -1
  7. package/dist/playkit-ott-provider.js.map +1 -1
  8. package/dist/playkit-ovp-provider.js +1 -1
  9. package/dist/playkit-ovp-provider.js.map +1 -1
  10. package/dist/playkit-stats-service.js +1 -1
  11. package/dist/playkit-stats-service.js.map +1 -1
  12. package/dist/tsdoc-metadata.json +11 -0
  13. package/flow-typed/types/media-config-sources.js +1 -1
  14. package/flow-typed/types/media-sources.js +1 -1
  15. package/package.json +49 -46
  16. package/playkit-analytics-service/package.json +5 -0
  17. package/playkit-bookmark-service/package.json +5 -0
  18. package/playkit-ott-provider/package.json +5 -0
  19. package/playkit-ovp-provider/package.json +5 -0
  20. package/playkit-stats-service/package.json +5 -0
  21. package/src/entities/bumper.ts +21 -0
  22. package/src/entities/drm.ts +47 -0
  23. package/src/entities/entry-list.ts +13 -0
  24. package/src/entities/image-source.ts +36 -0
  25. package/src/entities/media-entry.ts +104 -0
  26. package/src/entities/media-format.ts +47 -0
  27. package/src/entities/media-source.ts +70 -0
  28. package/src/entities/media-sources.ts +79 -0
  29. package/src/entities/playlist.ts +41 -0
  30. package/src/k-provider/common/base-provider-parser.ts +0 -0
  31. package/src/k-provider/common/base-provider.ts +112 -0
  32. package/src/k-provider/common/base-service-result.ts +56 -0
  33. package/src/k-provider/common/data-loader-manager.ts +115 -0
  34. package/src/k-provider/common/multi-request-builder.ts +111 -0
  35. package/src/k-provider/common/response-types/kaltura-access-control-message.ts +21 -0
  36. package/src/k-provider/common/response-types/kaltura-drm-playback-plugin-data.ts +38 -0
  37. package/src/k-provider/ott/config.ts +22 -0
  38. package/src/k-provider/ott/index.ts +14 -0
  39. package/src/k-provider/ott/loaders/asset-list-loader.ts +68 -0
  40. package/src/k-provider/ott/loaders/asset-loader.ts +69 -0
  41. package/src/k-provider/ott/loaders/data-loader-manager.ts +15 -0
  42. package/src/k-provider/ott/loaders/session-loader.ts +62 -0
  43. package/src/k-provider/ott/provider-parser.ts +285 -0
  44. package/src/k-provider/ott/provider.ts +252 -0
  45. package/src/k-provider/ott/response-types/kaltura-asset.ts +105 -0
  46. package/src/k-provider/ott/response-types/kaltura-bumper-playback-plugin-data.ts +27 -0
  47. package/src/k-provider/ott/response-types/kaltura-playback-context.ts +73 -0
  48. package/src/k-provider/ott/response-types/kaltura-playback-source.ts +62 -0
  49. package/src/k-provider/ott/response-types/kaltura-rule-action.ts +25 -0
  50. package/src/k-provider/ott/services/asset-service.ts +50 -0
  51. package/src/k-provider/ott/services/bookmark/bookmark-service.ts +48 -0
  52. package/src/k-provider/ott/services/bookmark/index.ts +11 -0
  53. package/src/k-provider/ott/services/ott-service.ts +33 -0
  54. package/src/k-provider/ott/services/user-service.ts +31 -0
  55. package/src/k-provider/ovp/config.ts +28 -0
  56. package/src/k-provider/ovp/external-captions-builder.ts +37 -0
  57. package/src/k-provider/ovp/index.ts +13 -0
  58. package/src/k-provider/ovp/loaders/data-loader-manager.ts +17 -0
  59. package/src/k-provider/ovp/loaders/entry-list-loader.ts +69 -0
  60. package/src/k-provider/ovp/loaders/media-entry-loader.ts +84 -0
  61. package/src/k-provider/ovp/loaders/playlist-loader.ts +69 -0
  62. package/src/k-provider/ovp/loaders/session-loader.ts +62 -0
  63. package/src/k-provider/ovp/loaders/ui-config-loader.ts +71 -0
  64. package/src/k-provider/ovp/play-source-url-builder.ts +59 -0
  65. package/src/k-provider/ovp/provider-parser.ts +461 -0
  66. package/src/k-provider/ovp/provider.ts +358 -0
  67. package/src/k-provider/ovp/regex-action-handler.ts +149 -0
  68. package/src/k-provider/ovp/request-params/base-entry-response-profile.ts +28 -0
  69. package/src/k-provider/ovp/response-types/index.ts +21 -0
  70. package/src/k-provider/ovp/response-types/kaltura-access-control-modify-request-host-regex-action.ts +35 -0
  71. package/src/k-provider/ovp/response-types/kaltura-base-entry-list-response.ts +30 -0
  72. package/src/k-provider/ovp/response-types/kaltura-bumper.ts +25 -0
  73. package/src/k-provider/ovp/response-types/kaltura-flavor-asset.ts +108 -0
  74. package/src/k-provider/ovp/response-types/kaltura-media-entries.ts +28 -0
  75. package/src/k-provider/ovp/response-types/kaltura-media-entry.ts +189 -0
  76. package/src/k-provider/ovp/response-types/kaltura-metadata-list-response.ts +22 -0
  77. package/src/k-provider/ovp/response-types/kaltura-metadata.ts +50 -0
  78. package/src/k-provider/ovp/response-types/kaltura-playback-context.ts +95 -0
  79. package/src/k-provider/ovp/response-types/kaltura-playback-source.ts +89 -0
  80. package/src/k-provider/ovp/response-types/kaltura-playlist.ts +33 -0
  81. package/src/k-provider/ovp/response-types/kaltura-rule-action.ts +27 -0
  82. package/src/k-provider/ovp/response-types/kaltura-ui-conf-response.ts +89 -0
  83. package/src/k-provider/ovp/response-types/kaltura-user-entry-list-response.ts +30 -0
  84. package/src/k-provider/ovp/response-types/kaltura-user-entry.ts +57 -0
  85. package/src/k-provider/ovp/services/analytics/analytics-service.ts +58 -0
  86. package/src/k-provider/ovp/services/analytics/index.ts +11 -0
  87. package/src/k-provider/ovp/services/base-entry-service.ts +75 -0
  88. package/src/k-provider/ovp/services/meta-data-service.ts +29 -0
  89. package/src/k-provider/ovp/services/ovp-service.ts +32 -0
  90. package/src/k-provider/ovp/services/playlist-service.ts +95 -0
  91. package/src/k-provider/ovp/services/session-service.ts +27 -0
  92. package/src/k-provider/ovp/services/stats/index.ts +11 -0
  93. package/src/k-provider/ovp/services/stats/stats-service.ts +32 -0
  94. package/src/k-provider/ovp/services/ui-conf-service.ts +32 -0
  95. package/src/types/adapter-data-config.ts +1 -0
  96. package/src/types/caption-type.ts +1 -0
  97. package/src/types/drm-data.ts +5 -0
  98. package/src/types/entry-list.ts +6 -0
  99. package/src/types/env-config.ts +7 -0
  100. package/src/types/external-caption-object.ts +7 -0
  101. package/src/types/filter-options.ts +3 -0
  102. package/src/types/index.ts +34 -0
  103. package/src/types/loader.ts +7 -0
  104. package/src/types/media-config-metadata.ts +13 -0
  105. package/src/types/media-config-session.ts +6 -0
  106. package/src/types/media-config-sources.ts +20 -0
  107. package/src/types/media-config.ts +8 -0
  108. package/src/types/media-entry.ts +16 -0
  109. package/src/types/media-format.ts +5 -0
  110. package/src/types/media-info.ts +21 -0
  111. package/src/types/media-source.ts +12 -0
  112. package/src/types/media-sources.ts +11 -0
  113. package/src/types/network-retry-parameters.ts +5 -0
  114. package/src/types/playback-context.ts +10 -0
  115. package/src/types/playlist-info.ts +4 -0
  116. package/src/types/playlist-item.ts +5 -0
  117. package/src/types/playlist-metadata.ts +4 -0
  118. package/src/types/playlist.ts +10 -0
  119. package/src/types/poster.ts +5 -0
  120. package/src/types/provider-options.ts +17 -0
  121. package/src/types/request-loader.ts +6 -0
  122. package/src/util/clone.ts +23 -0
  123. package/src/util/error/category.ts +11 -0
  124. package/src/util/error/code.ts +77 -0
  125. package/src/util/error/error.ts +47 -0
  126. package/src/util/error/severity.ts +21 -0
  127. package/src/util/logger.ts +108 -0
  128. package/src/util/param.ts +45 -0
  129. package/src/util/request-builder.ts +187 -0
  130. package/src/util/xml-parser.ts +39 -0
  131. package/CHANGELOG.md +0 -959
  132. package/samples/ott/bookmark.html +0 -23
  133. package/samples/ott/provider.html +0 -28
  134. package/samples/ovp/provider.html +0 -30
  135. package/samples/ovp/stats.html +0 -17
@@ -0,0 +1,358 @@
1
+ import getLogger from '../../util/logger';
2
+ import OVPConfiguration from './config';
3
+ import OVPProviderParser from './provider-parser';
4
+ import {KalturaMediaEntry} from './response-types';
5
+ import OVPMediaEntryLoader from './loaders/media-entry-loader';
6
+ import OVPSessionLoader from './loaders/session-loader';
7
+ import OVPDataLoaderManager from './loaders/data-loader-manager';
8
+ import OVPPlaylistLoader from './loaders/playlist-loader';
9
+ import BaseProvider from '../common/base-provider';
10
+ import MediaEntry from '../../entities/media-entry';
11
+ import OVPEntryListLoader from './loaders/entry-list-loader';
12
+ import Error from '../../util/error/error';
13
+ import RegexActionHandler from './regex-action-handler';
14
+ import {
15
+ ILoader,
16
+ OVPProviderMediaInfoObject,
17
+ ProviderEntryListObject,
18
+ ProviderFilterOptionsObject,
19
+ ProviderMediaConfigObject,
20
+ ProviderMediaConfigSourcesObject,
21
+ ProviderOptionsObject, ProviderPlaylistInfoObject,
22
+ ProviderPlaylistObject, RequestLoader
23
+ } from '../../types';
24
+
25
+ export default class OVPProvider extends BaseProvider<OVPProviderMediaInfoObject> {
26
+ private _filterOptionsConfig: ProviderFilterOptionsObject = {redirectFromEntryId: true};
27
+ /**
28
+ * @constructor
29
+ * @param {ProviderOptionsObject} options - provider options
30
+ * @param {string} playerVersion - player version
31
+ */
32
+ constructor(options: ProviderOptionsObject, playerVersion: string) {
33
+ super(options, playerVersion);
34
+ this._logger = getLogger('OVPProvider');
35
+ OVPConfiguration.set(options.env);
36
+ this._setFilterOptionsConfig(options.filterOptions);
37
+ this._networkRetryConfig = Object.assign(this._networkRetryConfig, options.networkRetryParameters);
38
+ }
39
+
40
+ public get env(): any {
41
+ return OVPConfiguration.get();
42
+ }
43
+
44
+ /**
45
+ * Gets the backend media config object.
46
+ * @param {OVPProviderMediaInfoObject} mediaInfo - ovp media info
47
+ * @returns {Promise<ProviderMediaConfigObject>} - The provider media config
48
+ */
49
+ public getMediaConfig(mediaInfo: OVPProviderMediaInfoObject): Promise<ProviderMediaConfigObject> {
50
+ if (mediaInfo.ks) {
51
+ this.ks = mediaInfo.ks;
52
+ this._isAnonymous = false;
53
+ }
54
+ if (this.widgetId !== this.defaultWidgetId) {
55
+ this._isAnonymous = false;
56
+ }
57
+ this._dataLoader = new OVPDataLoaderManager(this.playerVersion, this.partnerId, this.ks, this._networkRetryConfig);
58
+ return new Promise((resolve, reject) => {
59
+ const entryId = mediaInfo.entryId;
60
+ const referenceId = mediaInfo.referenceId;
61
+ if (entryId || referenceId) {
62
+ let ks: string = this.ks;
63
+ if (!ks) {
64
+ ks = '{1:result:ks}';
65
+ this._dataLoader.add(OVPSessionLoader, {widgetId: this.widgetId});
66
+ }
67
+ const redirectFromEntryId = this._getEntryRedirectFilter(mediaInfo);
68
+ this._dataLoader.add(OVPMediaEntryLoader, {entryId, ks, redirectFromEntryId, referenceId});
69
+ return this._dataLoader.fetchData().then(
70
+ response => {
71
+ try {
72
+ const mediaConfig = this._parseDataFromResponse(response);
73
+ RegexActionHandler.handleRegexAction(mediaConfig, response).then(resolve);
74
+ } catch (err) {
75
+ reject(err);
76
+ }
77
+ },
78
+ err => {
79
+ reject(err);
80
+ }
81
+ );
82
+ } else {
83
+ reject(new Error(Error.Severity.CRITICAL, Error.Category.PROVIDER, Error.Code.MISSING_MANDATORY_PARAMS, {message: 'missing entry id'}));
84
+ }
85
+ });
86
+ }
87
+
88
+ public doRequest(loaders: Array<RequestLoader>, ks?: string): Promise<any> {
89
+ const theKs: string = ks || this.ks;
90
+ const dataLoader = new OVPDataLoaderManager(this.playerVersion, this.partnerId, theKs, this._networkRetryConfig);
91
+
92
+ return new Promise((resolve, reject) => {
93
+ if (!theKs) {
94
+ dataLoader.add(OVPSessionLoader, {widgetId: this.widgetId});
95
+ }
96
+ loaders.forEach((loaderRequest: RequestLoader) => {
97
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
98
+ // @ts-ignore
99
+ dataLoader.add(loaderRequest.loader, loaderRequest.params, theKs || '{1:result:ks}');
100
+ });
101
+ return dataLoader.fetchData().then(
102
+ response => {
103
+ try {
104
+ resolve(response);
105
+ } catch (err) {
106
+ reject(err);
107
+ }
108
+ },
109
+ err => {
110
+ reject(err);
111
+ }
112
+ );
113
+ });
114
+ }
115
+
116
+ private _getEntryRedirectFilter(mediaInfo: any): boolean {
117
+ return typeof mediaInfo.redirectFromEntryId === 'boolean'
118
+ ? mediaInfo.redirectFromEntryId
119
+ : typeof this._filterOptionsConfig.redirectFromEntryId === 'boolean'
120
+ ? this._filterOptionsConfig.redirectFromEntryId
121
+ : true;
122
+ }
123
+
124
+ private _setFilterOptionsConfig(options?: ProviderFilterOptionsObject): void {
125
+ if (options && typeof options.redirectFromEntryId === 'boolean') {
126
+ this._filterOptionsConfig.redirectFromEntryId = options.redirectFromEntryId;
127
+ }
128
+ }
129
+
130
+ private _parseDataFromResponse(data: Map<string, ILoader>): ProviderMediaConfigObject {
131
+ this._logger.debug('Data parsing started');
132
+ const mediaConfig: ProviderMediaConfigObject = {
133
+ session: {
134
+ isAnonymous: this._isAnonymous,
135
+ partnerId: this.partnerId
136
+ },
137
+ sources: this._getDefaultSourcesObject(),
138
+ plugins: {}
139
+ } as ProviderMediaConfigObject;
140
+
141
+ if (this.uiConfId) {
142
+ mediaConfig.session.uiConfId = this.uiConfId;
143
+ }
144
+
145
+ if (data) {
146
+ if (data.has(OVPSessionLoader.id)) {
147
+ const sessionLoader = data.get(OVPSessionLoader.id);
148
+ if (sessionLoader && sessionLoader.response) {
149
+ mediaConfig.session.ks = sessionLoader.response;
150
+ if (this.widgetId !== this.defaultWidgetId) {
151
+ this.ks = mediaConfig.session.ks!;
152
+ }
153
+ }
154
+ } else {
155
+ mediaConfig.session.ks = this.ks;
156
+ }
157
+ if (data.has(OVPMediaEntryLoader.id)) {
158
+ const mediaLoader = data.get(OVPMediaEntryLoader.id);
159
+ if (mediaLoader && mediaLoader.response) {
160
+ const response = (mediaLoader as OVPMediaEntryLoader).response;
161
+ if (OVPProviderParser.hasBlockAction(response)) {
162
+ throw new Error(Error.Severity.CRITICAL, Error.Category.SERVICE, Error.Code.BLOCK_ACTION, {
163
+ action: OVPProviderParser.getBlockAction(response),
164
+ messages: OVPProviderParser.getErrorMessages(response)
165
+ });
166
+ }
167
+ const mediaEntry = OVPProviderParser.getMediaEntry(this.isAnonymous ? '' : this.ks, this.partnerId, this.uiConfId, response);
168
+ Object.assign(mediaConfig.sources, this._getSourcesObject(mediaEntry));
169
+ this._verifyMediaStatus(mediaEntry);
170
+ this._verifyHasSources(mediaConfig.sources);
171
+ const bumper = OVPProviderParser.getBumper(response, this.isAnonymous ? '' : this.ks, this.partnerId);
172
+ if (bumper) {
173
+ Object.assign(mediaConfig.plugins, {bumper});
174
+ }
175
+ }
176
+ }
177
+ }
178
+ this._logger.debug('Data parsing finished', mediaConfig);
179
+ return mediaConfig;
180
+ }
181
+
182
+ /**
183
+ * Checks if media is ready for playback (not being imported or converted)
184
+ * @param {MediaEntry} mediaEntry - the media entry info
185
+ * @returns {void}
186
+ */
187
+ private _verifyMediaStatus(mediaEntry: MediaEntry): void {
188
+ if ([KalturaMediaEntry.EntryStatus.IMPORT, KalturaMediaEntry.EntryStatus.PRECONVERT].includes(mediaEntry.status!)) {
189
+ throw new Error(Error.Severity.CRITICAL, Error.Category.SERVICE, Error.Code.MEDIA_STATUS_NOT_READY, {
190
+ messages: `Status of entry id ${mediaEntry.id} is ${mediaEntry.status} and is still being imported or converted`,
191
+ data: {status}
192
+ });
193
+ }
194
+ }
195
+ /**
196
+ * Gets the backend playlist config.
197
+ * @param {ProviderPlaylistInfoObject} playlistInfo - ovp playlist info
198
+ * @returns {Promise<ProviderPlaylistObject>} - The provider playlist config
199
+ */
200
+ public getPlaylistConfig(playlistInfo: ProviderPlaylistInfoObject): Promise<ProviderPlaylistObject> {
201
+ if (playlistInfo.ks) {
202
+ this.ks = playlistInfo.ks;
203
+ this._isAnonymous = false;
204
+ }
205
+ if (this.widgetId !== this.defaultWidgetId) {
206
+ this._isAnonymous = false;
207
+ }
208
+ this._dataLoader = new OVPDataLoaderManager(this.playerVersion, this.partnerId, this.ks, this._networkRetryConfig);
209
+ return new Promise((resolve, reject) => {
210
+ const playlistId = playlistInfo.playlistId;
211
+ if (playlistId) {
212
+ let ks: string = this.ks;
213
+ if (!ks) {
214
+ ks = '{1:result:ks}';
215
+ this._dataLoader.add(OVPSessionLoader, {widgetId: this.widgetId});
216
+ }
217
+ this._dataLoader.add(OVPPlaylistLoader, {playlistId, ks});
218
+ this._dataLoader.fetchData().then(
219
+ response => {
220
+ resolve(this._parsePlaylistDataFromResponse(response));
221
+ },
222
+ err => {
223
+ reject(err);
224
+ }
225
+ );
226
+ } else {
227
+ reject({success: false, data: 'Missing mandatory parameter'});
228
+ }
229
+ });
230
+ }
231
+
232
+ private _parsePlaylistDataFromResponse(data: Map<string, ILoader>): ProviderPlaylistObject {
233
+ this._logger.debug('Data parsing started');
234
+ const playlistConfig: ProviderPlaylistObject = this._getPlaylistObject();
235
+ if (data && data.has(OVPPlaylistLoader.id)) {
236
+ const playlistLoader = data.get(OVPPlaylistLoader.id);
237
+ if (playlistLoader && playlistLoader.response) {
238
+ const playlist = OVPProviderParser.getPlaylist(playlistLoader.response);
239
+ playlistConfig.id = playlist.id!;
240
+ playlistConfig.poster = playlist.poster!;
241
+ playlistConfig.metadata.name = playlist.name!;
242
+ playlistConfig.metadata.description = playlist.description!;
243
+ playlistConfig.playlistLastEntryId = playlist.playlistLastEntryId;
244
+ playlist.items.forEach(i => playlistConfig.items.push({sources: this._getSourcesObject(i)}));
245
+ }
246
+ }
247
+ this._logger.debug('Data parsing finished', playlistConfig);
248
+ return playlistConfig;
249
+ }
250
+
251
+ /**
252
+ * Gets playlist config from entry list.
253
+ * @param {ProviderEntryListObject} entryListInfo - ovp entry list info
254
+ * @returns {Promise<ProviderPlaylistObject>} - The provider playlist config
255
+ */
256
+ public getEntryListConfig(entryListInfo: ProviderEntryListObject): Promise<ProviderPlaylistObject> {
257
+ if (entryListInfo.ks) {
258
+ this.ks = entryListInfo.ks;
259
+ this._isAnonymous = false;
260
+ }
261
+ if (this.widgetId !== this.defaultWidgetId) {
262
+ this._isAnonymous = false;
263
+ }
264
+ this._dataLoader = new OVPDataLoaderManager(this.playerVersion, this.partnerId, this.ks, this._networkRetryConfig);
265
+ return new Promise((resolve, reject) => {
266
+ const entries = entryListInfo.entries;
267
+ if (entries && entries.length) {
268
+ let ks: string = this.ks;
269
+ if (!ks) {
270
+ ks = '{1:result:ks}';
271
+ this._dataLoader.add(OVPSessionLoader, {widgetId: this.widgetId});
272
+ }
273
+ const redirectFromEntryId = this._getEntryRedirectFilter(entryListInfo);
274
+ this._dataLoader.add(OVPEntryListLoader, {entries, ks, redirectFromEntryId});
275
+ this._dataLoader.fetchData(false).then(
276
+ response => {
277
+ resolve(this._parseEntryListDataFromResponse(response));
278
+ },
279
+ err => {
280
+ reject(err);
281
+ }
282
+ );
283
+ } else {
284
+ reject({success: false, data: 'Missing mandatory parameter'});
285
+ }
286
+ });
287
+ }
288
+
289
+ private _parseEntryListDataFromResponse(data: Map<string, ILoader>): ProviderPlaylistObject {
290
+ this._logger.debug('Data parsing started');
291
+ const playlistConfig: ProviderPlaylistObject = this._getPlaylistObject();
292
+ if (data && data.has(OVPEntryListLoader.id)) {
293
+ const playlistLoader = data.get(OVPEntryListLoader.id);
294
+ if (playlistLoader && playlistLoader.response) {
295
+ const entryList = OVPProviderParser.getEntryList(playlistLoader.response);
296
+ entryList.items.forEach(i => playlistConfig.items.push({sources: this._getSourcesObject(i)}));
297
+ }
298
+ }
299
+ this._logger.debug('Data parsing finished', playlistConfig);
300
+ return playlistConfig;
301
+ }
302
+
303
+ private _getPlaylistObject(): ProviderPlaylistObject {
304
+ return {
305
+ id: '',
306
+ metadata: {
307
+ name: '',
308
+ description: ''
309
+ },
310
+ poster: '',
311
+ playlistLastEntryId: '',
312
+ items: []
313
+ };
314
+ }
315
+
316
+ private _getDefaultSourcesObject(): ProviderMediaConfigSourcesObject {
317
+ return {
318
+ hls: [],
319
+ dash: [],
320
+ progressive: [],
321
+ image: [],
322
+ id: '',
323
+ duration: 0,
324
+ type: MediaEntry.Type.UNKNOWN,
325
+ poster: '',
326
+ dvr: false,
327
+ vr: null,
328
+ metadata: {
329
+ name: '',
330
+ description: '',
331
+ tags: ''
332
+ }
333
+ };
334
+ }
335
+
336
+ private _getSourcesObject(mediaEntry: MediaEntry): ProviderMediaConfigSourcesObject {
337
+ const sourcesObject: ProviderMediaConfigSourcesObject = this._getDefaultSourcesObject();
338
+ const mediaSources = mediaEntry.sources.toJSON();
339
+ sourcesObject.hls = mediaSources.hls;
340
+ sourcesObject.dash = mediaSources.dash;
341
+ sourcesObject.progressive = mediaSources.progressive;
342
+ sourcesObject.image = mediaSources.image;
343
+ sourcesObject.id = mediaEntry.id;
344
+ sourcesObject.duration = mediaEntry.duration;
345
+ sourcesObject.type = mediaEntry.type;
346
+ sourcesObject.dvr = !!mediaEntry.dvrStatus;
347
+ sourcesObject.poster = mediaEntry.poster;
348
+ sourcesObject.downloadUrl = mediaEntry.downloadUrl;
349
+ if (mediaEntry.sources.captions) {
350
+ sourcesObject.captions = mediaEntry.sources.captions;
351
+ }
352
+ if (mediaEntry.metadata && typeof mediaEntry.metadata.tags === 'string' && mediaEntry.metadata.tags.split(', ').includes('360')) {
353
+ sourcesObject.vr = {};
354
+ }
355
+ Object.assign(sourcesObject.metadata, mediaEntry.metadata);
356
+ return sourcesObject;
357
+ }
358
+ }
@@ -0,0 +1,149 @@
1
+ import getLogger from '../../util/logger';
2
+ import OVPConfiguration from './config';
3
+ import {KalturaAccessControlModifyRequestHostRegexAction} from './response-types';
4
+ import OVPMediaEntryLoader from './loaders/media-entry-loader';
5
+ import {ILoader, ProviderMediaConfigObject} from '../../types';
6
+
7
+ class RegexActionHandler {
8
+ private static _logger = getLogger('RegexActionHandler');
9
+
10
+ /**
11
+ * Applies the request host regex on the url
12
+ * @function _applyRegexAction
13
+ * @param {KalturaAccessControlModifyRequestHostRegexAction} regexAction - The regex action
14
+ * @param {string} url - The url to modify
15
+ * @returns {string} - The request host regex applied url
16
+ * @static
17
+ * @private
18
+ */
19
+ private static _applyRegexAction(regexAction: KalturaAccessControlModifyRequestHostRegexAction, url: string): string {
20
+ if (regexAction) {
21
+ const regex = new RegExp(regexAction.pattern, 'i');
22
+ if (url.match(regex)) {
23
+ return url.replace(regex, regexAction.replacement + '/');
24
+ }
25
+ }
26
+ return url;
27
+ }
28
+
29
+ /**
30
+ * Ping the ECDN url to check if alive
31
+ * @function _pingECDNUrl
32
+ * @param {KalturaAccessControlModifyRequestHostRegexAction} regexAction - The regex action
33
+ * @param {string} cdnUrl - The CDN url
34
+ * @returns {Promise<boolean>} - Whether the media config sources urls should be modified or not
35
+ * @static
36
+ * @private
37
+ */
38
+ private static async _isECDNUrlAlive(regexAction: KalturaAccessControlModifyRequestHostRegexAction, cdnUrl: string): Promise<boolean> {
39
+ const urlPing = cdnUrl + '/api_v3/service/system/action/ping/format/1';
40
+ const req = new XMLHttpRequest();
41
+ req.open('GET', urlPing);
42
+ req.timeout = regexAction.checkAliveTimeoutMs;
43
+ req.onreadystatechange = (): boolean => {
44
+ if (req.readyState === 4) {
45
+ if (req.status === 200) {
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ return false;
51
+ };
52
+ req.ontimeout = (): boolean => {
53
+ RegexActionHandler._logger.warn(`Got timeout while pinging the ECDN url. the ping url: ${urlPing}`);
54
+ return false;
55
+ };
56
+ req.send();
57
+ return false;
58
+ }
59
+
60
+ /**
61
+ * Handles regex action
62
+ * @function handleRegexAction
63
+ * @param {ProviderMediaConfigObject} mediaConfig - The media config
64
+ * @param {Map<string, Function>} rawResponse - The raw response data from backend
65
+ * @returns {Promise<ProviderMediaConfigObject>} - The media config with old or modified urls
66
+ * @static
67
+ */
68
+ public static async handleRegexAction(mediaConfig: ProviderMediaConfigObject, rawResponse: Map<string, ILoader>): Promise<ProviderMediaConfigObject> {
69
+ const cdnUrl = OVPConfiguration.get().cdnUrl;
70
+ const regexAction = RegexActionHandler._extractRegexActionFromData(rawResponse);
71
+ const regExp = RegexActionHandler._getRegExp(regexAction);
72
+
73
+ if (
74
+ cdnUrl &&
75
+ regexAction &&
76
+ regExp &&
77
+ cdnUrl.match(regExp) &&
78
+ // we need to make the replacement in all cases except for when the checkAliveTimeoutMs > 0 && the ping has failed
79
+ !(
80
+ regexAction.checkAliveTimeoutMs > 0 &&
81
+ !(await RegexActionHandler._isECDNUrlAlive(regexAction, cdnUrl.replace(regExp, regexAction.replacement)))
82
+ )
83
+ ) {
84
+ RegexActionHandler._replaceHostUrls(mediaConfig, regexAction);
85
+ return mediaConfig;
86
+ }
87
+
88
+ RegexActionHandler._logger.debug('exiting handleRegexAction - not applying regex action.');
89
+ return mediaConfig;
90
+ }
91
+
92
+ /**
93
+ * Modify the host urls - injects the configured cdn before the original host, to route requests
94
+ * @function _replaceHostUrls
95
+ * @param {ProviderMediaConfigObject} mediaConfig - The media config
96
+ * @param {KalturaAccessControlModifyRequestHostRegexAction} regexAction - The regex action
97
+ * @returns {void}
98
+ * @static
99
+ * @private
100
+ */
101
+ private static _replaceHostUrls(mediaConfig: ProviderMediaConfigObject, regexAction: KalturaAccessControlModifyRequestHostRegexAction): void {
102
+ RegexActionHandler._logger.debug('Starting to modify urls...');
103
+ const sources = mediaConfig.sources;
104
+ const {hls, dash, progressive, image} = sources;
105
+
106
+ [...hls, ...dash, ...progressive, ...image].forEach(src => (src.url = RegexActionHandler._applyRegexAction(regexAction, src.url)));
107
+
108
+ if (!OVPConfiguration.get().replaceHostOnlyManifestUrls) {
109
+ RegexActionHandler._logger.debug('replaceHostOnlyManifestUrls flag is off - modifying captions and poster URLs');
110
+ if (sources.captions) {
111
+ sources.captions.forEach(src => (src.url = RegexActionHandler._applyRegexAction(regexAction, src.url)));
112
+ }
113
+
114
+ // fix flow - poster can also be an array, but only for ott.
115
+ if (typeof sources.poster === 'string') {
116
+ sources.poster = RegexActionHandler._applyRegexAction(regexAction, sources.poster);
117
+ }
118
+ }
119
+ RegexActionHandler._logger.debug('Finished modifying urls');
120
+ }
121
+
122
+ /**
123
+ * Extracts the regex action from the data response
124
+ * @function _extractRegexActionFromData
125
+ * @param {Map<string, Function>} data - The response data
126
+ * @returns {KalturaAccessControlModifyRequestHostRegexAction} regexAction - The regex action
127
+ * @static
128
+ * @private
129
+ */
130
+ private static _extractRegexActionFromData(data: Map<string, ILoader>): KalturaAccessControlModifyRequestHostRegexAction | undefined {
131
+ return data.get(OVPMediaEntryLoader.id)?.response?.playBackContextResult.getRequestHostRegexAction();
132
+ }
133
+
134
+ /**
135
+ * Extracts the regex action from the data response
136
+ * @function _extractRegexActionFromData
137
+ * @param {KalturaAccessControlModifyRequestHostRegexAction} regexAction - The regex action
138
+ * @returns {RegExp} The regex expression
139
+ * @static
140
+ * @private
141
+ */
142
+ private static _getRegExp(regexAction: KalturaAccessControlModifyRequestHostRegexAction | undefined): RegExp | undefined {
143
+ if (regexAction && regexAction.pattern && regexAction.replacement) {
144
+ return new RegExp(regexAction.pattern, 'i');
145
+ }
146
+ }
147
+ }
148
+
149
+ export default RegexActionHandler;
@@ -0,0 +1,28 @@
1
+ const FIELDS =
2
+ 'id,referenceId,name,description,thumbnailUrl,dataUrl,duration,msDuration,flavorParamsIds,mediaType,type,tags,dvrStatus,externalSourceType,status,createdAt,updatedAt,endDate,plays,views,downloadUrl,creatorId';
3
+ const RESPONSE_PROFILE_TYPE = {
4
+ INCLUDE_FIELDS: 1,
5
+ EXCLUDE_FIELDS: 2
6
+ };
7
+ export class BaseEntryResponseProfile {
8
+ public static Type: {[type: string]: number} = RESPONSE_PROFILE_TYPE;
9
+ /**
10
+ * @member - the response profile type
11
+ * @type {number}
12
+ */
13
+ public type: number;
14
+ /**
15
+ * @member - Comma separated fields list to be included or excluded
16
+ * @type {string}
17
+ */
18
+ public fields: string;
19
+
20
+ /**
21
+ * @constructor
22
+ * @param {Object} responseProfile -
23
+ */
24
+ constructor(responseProfile: any = {}) {
25
+ this.type = responseProfile.type || BaseEntryResponseProfile.Type.INCLUDE_FIELDS;
26
+ this.fields = responseProfile.fields || FIELDS;
27
+ }
28
+ }
@@ -0,0 +1,21 @@
1
+ import BaseServiceResult from '../../common/base-service-result';
2
+
3
+ export {KalturaBaseEntryListResponse} from './kaltura-base-entry-list-response';
4
+ export {KalturaMediaEntry} from './kaltura-media-entry';
5
+ export {KalturaAccessControlModifyRequestHostRegexAction} from './kaltura-access-control-modify-request-host-regex-action';
6
+ export {KalturaBumper} from './kaltura-bumper';
7
+ export {KalturaFlavorAsset} from './kaltura-flavor-asset';
8
+ export {KalturaMediaEntries} from './kaltura-media-entries';
9
+ export {KalturaMetadata} from './kaltura-metadata';
10
+ export {KalturaMetadataListResponse} from './kaltura-metadata-list-response';
11
+ export {KalturaPlaybackContext} from './kaltura-playback-context';
12
+ export {KalturaPlaybackSource} from './kaltura-playback-source';
13
+ export {KalturaPlaylist} from './kaltura-playlist';
14
+ export {KalturaRuleAction} from './kaltura-rule-action';
15
+ export {KalturaUIConfResponse} from './kaltura-ui-conf-response';
16
+ export {KalturaDrmPlaybackPluginData} from '../../common/response-types/kaltura-drm-playback-plugin-data';
17
+ export {KalturaAccessControlMessage} from '../../common/response-types/kaltura-access-control-message';
18
+ export {BaseServiceResult};
19
+ export {KalturaUserEntry} from './kaltura-user-entry'
20
+ export {KalturaUserEntryListResponse} from './kaltura-user-entry-list-response'
21
+
@@ -0,0 +1,35 @@
1
+ import {KalturaRuleAction} from './kaltura-rule-action';
2
+
3
+ export class KalturaAccessControlModifyRequestHostRegexAction extends KalturaRuleAction {
4
+ /**
5
+ * @member - Request host regex pattern
6
+ * @type {string}
7
+ */
8
+ public pattern: string;
9
+ /**
10
+ * @member - Request host regex replacement
11
+ * @type {string}
12
+ */
13
+ public replacement: string;
14
+ /**
15
+ * @member - serverNodeId to generate replacment host from
16
+ * @type {number}
17
+ */
18
+ public replacmenServerNodeId: number;
19
+ /**
20
+ * @member - checkAliveTimeout in milliseconds
21
+ * @type {number}
22
+ */
23
+ public checkAliveTimeoutMs: number;
24
+ /**
25
+ * @constructor
26
+ * @param {Object} data - The response
27
+ */
28
+ constructor(data: any) {
29
+ super(data);
30
+ this.pattern = data.pattern;
31
+ this.replacement = data.replacement;
32
+ this.replacmenServerNodeId = data.replacmenServerNodeId;
33
+ this.checkAliveTimeoutMs = data.checkAliveTimeoutMs;
34
+ }
35
+ }
@@ -0,0 +1,30 @@
1
+ import ServiceResult from '../../common/base-service-result';
2
+ import {KalturaMediaEntry} from './kaltura-media-entry';
3
+
4
+ export class KalturaBaseEntryListResponse extends ServiceResult {
5
+ /**
6
+ * @member - The total count
7
+ * @type {number}
8
+ */
9
+ public totalCount!: number;
10
+ /**
11
+ * @member - The entries
12
+ * @type {Array<KalturaMediaEntry>}
13
+ */
14
+ public entries!: Array<KalturaMediaEntry>;
15
+
16
+ /**
17
+ * @constructor
18
+ * @param {Object} responseObj The json response
19
+ */
20
+ constructor(responseObj: any) {
21
+ super(responseObj);
22
+ if (!this.hasError) {
23
+ this.totalCount = responseObj.totalCount;
24
+ if (this.totalCount > 0) {
25
+ this.entries = [];
26
+ responseObj.objects.map(entry => this.entries.push(new KalturaMediaEntry(entry)));
27
+ }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,25 @@
1
+ import {KalturaPlaybackSource} from './kaltura-playback-source';
2
+
3
+ export class KalturaBumper {
4
+ /**
5
+ * @member - The bumper entry ID
6
+ * @type {string}
7
+ */
8
+ public entryId: string;
9
+ /**
10
+ * @member - The bumper click through url
11
+ * @type {string}
12
+ */
13
+ public clickThroughUrl: string;
14
+ /**
15
+ * @member - The bumper sources
16
+ * @type {Array<KalturaPlaybackSource>}
17
+ */
18
+ public sources: Array<KalturaPlaybackSource>;
19
+
20
+ constructor(data: any) {
21
+ this.entryId = data.entryId;
22
+ this.clickThroughUrl = data.url;
23
+ this.sources = data.sources ? data.sources.map(source => new KalturaPlaybackSource(source)) : [];
24
+ }
25
+ }