@eluvio/elv-client-js 4.0.114 → 4.0.115

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 (129) hide show
  1. package/dist/ElvClient-min.js +67 -0
  2. package/dist/ElvClient-node-min.js +66 -0
  3. package/dist/ElvFrameClient-min.js +60 -0
  4. package/dist/ElvPermissionsClient-min.js +60 -0
  5. package/dist/ElvWalletClient-min.js +67 -0
  6. package/dist/ElvWalletClient-node-min.js +66 -0
  7. package/dist/src/AuthorizationClient.js +2169 -0
  8. package/dist/src/ContentObjectAudit.js +175 -0
  9. package/dist/src/ContentObjectVerification.js +281 -0
  10. package/dist/src/Crypto.js +412 -0
  11. package/dist/src/ElvClient.js +2044 -0
  12. package/dist/src/ElvWallet.js +245 -0
  13. package/dist/src/EthClient.js +1154 -0
  14. package/dist/src/FrameClient.js +485 -0
  15. package/dist/src/HttpClient.js +315 -0
  16. package/dist/src/Id.js +21 -0
  17. package/dist/src/LogMessage.js +25 -0
  18. package/dist/src/PermissionsClient.js +1544 -0
  19. package/dist/src/RemoteSigner.js +385 -0
  20. package/dist/src/UserProfileClient.js +1450 -0
  21. package/dist/src/Utils.js +894 -0
  22. package/dist/src/Validation.js +121 -0
  23. package/dist/src/abr_profiles/abr_profile_live_drm.js +1661 -0
  24. package/dist/src/abr_profiles/abr_profile_live_to_vod.js +1606 -0
  25. package/dist/src/client/ABRPublishing.js +1018 -0
  26. package/dist/src/client/AccessGroups.js +1503 -0
  27. package/dist/src/client/ContentAccess.js +5195 -0
  28. package/dist/src/client/ContentManagement.js +2680 -0
  29. package/dist/src/client/Contracts.js +1520 -0
  30. package/dist/src/client/Files.js +2181 -0
  31. package/dist/src/client/LiveConf.js +569 -0
  32. package/dist/src/client/LiveStream.js +2640 -0
  33. package/dist/src/client/NFT.js +162 -0
  34. package/dist/src/client/NTP.js +581 -0
  35. package/dist/src/contracts/v2/AccessIndexor.js +831 -0
  36. package/dist/src/contracts/v2/Accessible.js +31 -0
  37. package/dist/src/contracts/v2/BaseAccessControlGroup.js +1263 -0
  38. package/dist/src/contracts/v2/BaseAccessWallet.js +1609 -0
  39. package/dist/src/contracts/v2/BaseAccessWalletFactory.js +93 -0
  40. package/dist/src/contracts/v2/BaseContent.js +1076 -0
  41. package/dist/src/contracts/v2/BaseContentFactory.js +219 -0
  42. package/dist/src/contracts/v2/BaseContentSpace.js +1352 -0
  43. package/dist/src/contracts/v2/BaseContentType.js +364 -0
  44. package/dist/src/contracts/v2/BaseFactory.js +107 -0
  45. package/dist/src/contracts/v2/BaseGroupFactory.js +93 -0
  46. package/dist/src/contracts/v2/BaseLibrary.js +1041 -0
  47. package/dist/src/contracts/v2/BaseLibraryFactory.js +96 -0
  48. package/dist/src/contracts/v2/Certifyer.js +86 -0
  49. package/dist/src/contracts/v2/Container.js +540 -0
  50. package/dist/src/contracts/v2/Content.js +443 -0
  51. package/dist/src/contracts/v2/Editable.js +306 -0
  52. package/dist/src/contracts/v2/ExternalUserWallet.js +379 -0
  53. package/dist/src/contracts/v2/IFactorySpace.js +57 -0
  54. package/dist/src/contracts/v2/IKmsSpace.js +52 -0
  55. package/dist/src/contracts/v2/INodeSpace.js +18 -0
  56. package/dist/src/contracts/v2/IUserSpace.js +18 -0
  57. package/dist/src/contracts/v2/LvRecordableStream.js +1037 -0
  58. package/dist/src/contracts/v2/LvRecording.js +627 -0
  59. package/dist/src/contracts/v2/LvStreamRightsHolder.js +562 -0
  60. package/dist/src/contracts/v2/MetaObject.js +119 -0
  61. package/dist/src/contracts/v2/Node.js +167 -0
  62. package/dist/src/contracts/v2/NodeSpace.js +273 -0
  63. package/dist/src/contracts/v2/Ownable.js +87 -0
  64. package/dist/src/contracts/v2/PaymentService.js +627 -0
  65. package/dist/src/contracts/v2/Precompile.js +15 -0
  66. package/dist/src/contracts/v2/Transactable.js +82 -0
  67. package/dist/src/contracts/v2/UserSpace.js +29 -0
  68. package/dist/src/contracts/v2/Utils.js +18 -0
  69. package/dist/src/contracts/v2/Verifier.js +53 -0
  70. package/dist/src/contracts/v2/strings.js +4 -0
  71. package/dist/src/contracts/v3/AccessIndexor.js +774 -0
  72. package/dist/src/contracts/v3/Accessible.js +232 -0
  73. package/dist/src/contracts/v3/Adminable.js +107 -0
  74. package/dist/src/contracts/v3/AvailsDelivery.js +586 -0
  75. package/dist/src/contracts/v3/BaseAccessControlGroup.js +1603 -0
  76. package/dist/src/contracts/v3/BaseAccessWallet.js +1628 -0
  77. package/dist/src/contracts/v3/BaseAccessWalletFactory.js +112 -0
  78. package/dist/src/contracts/v3/BaseContent.js +1312 -0
  79. package/dist/src/contracts/v3/BaseContentFactory.js +183 -0
  80. package/dist/src/contracts/v3/BaseContentFactoryExt.js +175 -0
  81. package/dist/src/contracts/v3/BaseContentSpace.js +1515 -0
  82. package/dist/src/contracts/v3/BaseContentType.js +527 -0
  83. package/dist/src/contracts/v3/BaseFactory.js +126 -0
  84. package/dist/src/contracts/v3/BaseGroupFactory.js +112 -0
  85. package/dist/src/contracts/v3/BaseLibrary.js +1204 -0
  86. package/dist/src/contracts/v3/BaseLibraryFactory.js +115 -0
  87. package/dist/src/contracts/v3/BaseTenantSpace.js +1587 -0
  88. package/dist/src/contracts/v3/Certifyer.js +86 -0
  89. package/dist/src/contracts/v3/Container.js +739 -0
  90. package/dist/src/contracts/v3/Content.js +438 -0
  91. package/dist/src/contracts/v3/CounterObject.js +243 -0
  92. package/dist/src/contracts/v3/Editable.js +519 -0
  93. package/dist/src/contracts/v3/EncToken.js +4 -0
  94. package/dist/src/contracts/v3/ExternalUserWallet.js +587 -0
  95. package/dist/src/contracts/v3/IAdmin.js +18 -0
  96. package/dist/src/contracts/v3/IFactorySpace.js +57 -0
  97. package/dist/src/contracts/v3/IKmsSpace.js +52 -0
  98. package/dist/src/contracts/v3/INodeSpace.js +18 -0
  99. package/dist/src/contracts/v3/IUserSpace.js +32 -0
  100. package/dist/src/contracts/v3/LvRecordableStream.js +1032 -0
  101. package/dist/src/contracts/v3/LvRecording.js +650 -0
  102. package/dist/src/contracts/v3/LvStreamRightsHolder.js +557 -0
  103. package/dist/src/contracts/v3/MetaObject.js +144 -0
  104. package/dist/src/contracts/v3/Node.js +178 -0
  105. package/dist/src/contracts/v3/NodeSpace.js +284 -0
  106. package/dist/src/contracts/v3/Ownable.js +98 -0
  107. package/dist/src/contracts/v3/PaymentService.js +622 -0
  108. package/dist/src/contracts/v3/Precompile.js +26 -0
  109. package/dist/src/contracts/v3/TenantFuncsBase.js +351 -0
  110. package/dist/src/contracts/v3/Transactable.js +82 -0
  111. package/dist/src/contracts/v3/UserSpace.js +43 -0
  112. package/dist/src/contracts/v3/Utils.js +18 -0
  113. package/dist/src/contracts/v3/Verifier.js +53 -0
  114. package/dist/src/contracts/v3/strings.js +4 -0
  115. package/dist/src/contracts/v3b/BaseAccessControlGroup.js +1704 -0
  116. package/dist/src/events/Topics.js +1793 -0
  117. package/dist/src/index.js +8 -0
  118. package/dist/src/walletClient/ClientMethods.js +3102 -0
  119. package/dist/src/walletClient/Configuration.js +38 -0
  120. package/dist/src/walletClient/Notifications.js +168 -0
  121. package/dist/src/walletClient/Profile.js +332 -0
  122. package/dist/src/walletClient/Utils.js +281 -0
  123. package/dist/src/walletClient/index.js +2106 -0
  124. package/package.json +1 -1
  125. package/src/AuthorizationClient.js +24 -16
  126. package/src/ElvClient.js +19 -0
  127. package/src/client/ContentAccess.js +10 -1
  128. package/src/client/LiveConf.js +10 -8
  129. package/src/client/LiveStream.js +6 -4
@@ -0,0 +1,2640 @@
1
+ var _toConsumableArray = require("@babel/runtime/helpers/toConsumableArray");
2
+ var _defineProperty = require("@babel/runtime/helpers/defineProperty");
3
+ var _regeneratorRuntime = require("@babel/runtime/regenerator");
4
+ var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
5
+ var _this = this;
6
+ /* eslint no-console: 0 */
7
+
8
+ /**
9
+ * Methods for Live Stream creation and management
10
+ *
11
+ * @module ElvClient/LiveStream
12
+ */
13
+
14
+ var _require = require("./LiveConf"),
15
+ LiveConf = _require.LiveConf;
16
+ var path = require("path");
17
+ var fs = require("fs");
18
+ var HttpClient = require("../HttpClient");
19
+ var Fraction = require("fraction.js");
20
+ var _require2 = require("../Validation"),
21
+ ValidateObject = _require2.ValidateObject,
22
+ ValidatePresence = _require2.ValidatePresence;
23
+ var ContentObjectAudit = require("../ContentObjectAudit");
24
+ var MakeTxLessToken = /*#__PURE__*/function () {
25
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
26
+ var client, libraryId, objectId, versionHash, tok;
27
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
28
+ while (1) switch (_context.prev = _context.next) {
29
+ case 0:
30
+ client = _ref.client, libraryId = _ref.libraryId, objectId = _ref.objectId, versionHash = _ref.versionHash;
31
+ _context.next = 3;
32
+ return client.authClient.AuthorizationToken({
33
+ libraryId: libraryId,
34
+ objectId: objectId,
35
+ versionHash: versionHash,
36
+ channelAuth: false,
37
+ noCache: true,
38
+ noAuth: true
39
+ });
40
+ case 3:
41
+ tok = _context.sent;
42
+ return _context.abrupt("return", tok);
43
+ case 5:
44
+ case "end":
45
+ return _context.stop();
46
+ }
47
+ }, _callee);
48
+ }));
49
+ return function MakeTxLessToken(_x) {
50
+ return _ref2.apply(this, arguments);
51
+ };
52
+ }();
53
+ var Sleep = function Sleep(ms) {
54
+ return new Promise(function (resolve) {
55
+ return setTimeout(resolve, ms);
56
+ });
57
+ };
58
+ var CueInfo = /*#__PURE__*/function () {
59
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref3) {
60
+ var eventId, status, cues, lroStatusResponse, eventStart, eventEnd, _i, _Object$values, value, _i2, _Object$values2, event;
61
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
62
+ while (1) switch (_context2.prev = _context2.next) {
63
+ case 0:
64
+ eventId = _ref3.eventId, status = _ref3.status;
65
+ _context2.prev = 1;
66
+ _context2.t0 = _this.utils;
67
+ _context2.next = 5;
68
+ return HttpClient.Fetch(status.lro_status_url);
69
+ case 5:
70
+ _context2.t1 = _context2.sent;
71
+ _context2.next = 8;
72
+ return _context2.t0.ResponseToJson.call(_context2.t0, _context2.t1);
73
+ case 8:
74
+ lroStatusResponse = _context2.sent;
75
+ console.log("lroStatusResponse", lroStatusResponse);
76
+ cues = lroStatusResponse.custom.cues;
77
+ _context2.next = 17;
78
+ break;
79
+ case 13:
80
+ _context2.prev = 13;
81
+ _context2.t2 = _context2["catch"](1);
82
+ console.log("LRO status failed", _context2.t2);
83
+ return _context2.abrupt("return", {
84
+ error: "failed to retrieve status",
85
+ eventId: eventId
86
+ });
87
+ case 17:
88
+ _i = 0, _Object$values = Object.values(cues);
89
+ case 18:
90
+ if (!(_i < _Object$values.length)) {
91
+ _context2.next = 37;
92
+ break;
93
+ }
94
+ value = _Object$values[_i];
95
+ _i2 = 0, _Object$values2 = Object.values(value.descriptors);
96
+ case 21:
97
+ if (!(_i2 < _Object$values2.length)) {
98
+ _context2.next = 34;
99
+ break;
100
+ }
101
+ event = _Object$values2[_i2];
102
+ if (!(event.id == eventId)) {
103
+ _context2.next = 31;
104
+ break;
105
+ }
106
+ _context2.t3 = event.type_id;
107
+ _context2.next = _context2.t3 === 32 ? 27 : _context2.t3 === 16 ? 27 : _context2.t3 === 33 ? 29 : _context2.t3 === 17 ? 29 : 31;
108
+ break;
109
+ case 27:
110
+ eventStart = value.insertion_time;
111
+ return _context2.abrupt("break", 31);
112
+ case 29:
113
+ eventEnd = value.insertion_time;
114
+ return _context2.abrupt("break", 31);
115
+ case 31:
116
+ _i2++;
117
+ _context2.next = 21;
118
+ break;
119
+ case 34:
120
+ _i++;
121
+ _context2.next = 18;
122
+ break;
123
+ case 37:
124
+ return _context2.abrupt("return", {
125
+ eventStart: eventStart,
126
+ eventEnd: eventEnd,
127
+ eventId: eventId
128
+ });
129
+ case 38:
130
+ case "end":
131
+ return _context2.stop();
132
+ }
133
+ }, _callee2, null, [[1, 13]]);
134
+ }));
135
+ return function CueInfo(_x2) {
136
+ return _ref4.apply(this, arguments);
137
+ };
138
+ }();
139
+
140
+ /**
141
+ * Set the offering for the live stream
142
+ *
143
+ * @methodGroup Live Stream
144
+ * @namedParams
145
+ * @param {Object} client - The client object
146
+ * @param {string} libraryId - ID of the library for the new live stream object
147
+ * @param {string} objectId - ID of the new live stream object
148
+ * @param {string=} typeAbrMaster - Content type hash
149
+ * @param {string=} typeLiveStream - Content type hash
150
+ * @param {string} streamUrl - Live source URL
151
+ * @param {object} abrProfile - ABR Profile for the offering
152
+ * @param {number} aBitRate - Audio bitrate
153
+ * @param {number} aChannels - Audio channels
154
+ * @param {number} aSampleRate - Audio sample rate
155
+ * @param {number} aStreamIndex - Audio stream index
156
+ * @param {string} aTimeBase - Audio time base as a fraction, e.g. "1/48000" (usually equal to 1/aSampleRate)
157
+ * @param {string} aChannelLayout - Channel layout, e.g. "stereo"
158
+ * @param {number} vBitRate - Video bitrate
159
+ * @param {number} vHeight - Video height
160
+ * @param {number} vStreamIndex - Video stream index
161
+ * @param {number} vWidth - Video width
162
+ * @param {string} vDisplayAspectRatio - Display aspect ratio as a fraction, e.g. "16/9"
163
+ * @param {string} vFrameRate - Frame rate as an integer, e.g. "30"
164
+ * @param {string} vTimeBase - Time base as a fraction, e.g. "1/30000"
165
+ *
166
+ * @return {Promise<string>} - Final hash of the live stream object
167
+ */
168
+ var StreamGenerateOffering = /*#__PURE__*/function () {
169
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref5) {
170
+ var client, libraryId, objectId, typeAbrMaster, typeLiveStream, streamUrl, abrProfile, aBitRate, aChannels, aSampleRate, aStreamIndex, aTimeBase, aChannelLayout, vBitRate, vHeight, vStreamIndex, vWidth, vDisplayAspectRatio, vFrameRate, vTimeBase, DUMMY_DURATION, aDurationTs, vDurationTs, sourceAudioStream, sourceVideoStream, DUMMY_STREAM, sourceStreams, maxStreamIndex, i, sources, variants, production_master, metadata, editResponse, writeToken, finalizeResponse, masterVersionHash, createResponse, versionHash, finalHash;
171
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
172
+ while (1) switch (_context3.prev = _context3.next) {
173
+ case 0:
174
+ client = _ref5.client, libraryId = _ref5.libraryId, objectId = _ref5.objectId, typeAbrMaster = _ref5.typeAbrMaster, typeLiveStream = _ref5.typeLiveStream, streamUrl = _ref5.streamUrl, abrProfile = _ref5.abrProfile, aBitRate = _ref5.aBitRate, aChannels = _ref5.aChannels, aSampleRate = _ref5.aSampleRate, aStreamIndex = _ref5.aStreamIndex, aTimeBase = _ref5.aTimeBase, aChannelLayout = _ref5.aChannelLayout, vBitRate = _ref5.vBitRate, vHeight = _ref5.vHeight, vStreamIndex = _ref5.vStreamIndex, vWidth = _ref5.vWidth, vDisplayAspectRatio = _ref5.vDisplayAspectRatio, vFrameRate = _ref5.vFrameRate, vTimeBase = _ref5.vTimeBase;
175
+ // compute duration_ts
176
+ DUMMY_DURATION = 1001; // should result in integer duration_ts values for both audio and video
177
+ aDurationTs = Fraction(aTimeBase).inverse().mul(DUMMY_DURATION).valueOf();
178
+ vDurationTs = Fraction(vTimeBase).inverse().mul(DUMMY_DURATION).valueOf(); // construct /production_master/sources/STREAM_URL/streams
179
+ sourceAudioStream = {
180
+ "bit_rate": aBitRate,
181
+ "channel_layout": aChannelLayout,
182
+ "channels": aChannels,
183
+ "codec_name": "aac",
184
+ "duration": DUMMY_DURATION,
185
+ "duration_ts": aDurationTs,
186
+ "frame_count": 0,
187
+ "language": "",
188
+ "max_bit_rate": aBitRate,
189
+ "sample_rate": aSampleRate,
190
+ "start_pts": 0,
191
+ "start_time": 0,
192
+ "time_base": aTimeBase,
193
+ "type": "StreamAudio"
194
+ };
195
+ sourceVideoStream = {
196
+ "bit_rate": vBitRate,
197
+ "codec_name": "h264",
198
+ "display_aspect_ratio": vDisplayAspectRatio,
199
+ "duration": DUMMY_DURATION,
200
+ "duration_ts": vDurationTs,
201
+ "field_order": "progressive",
202
+ "frame_count": 0,
203
+ "frame_rate": vFrameRate,
204
+ "hdr": null,
205
+ "height": vHeight,
206
+ "language": "",
207
+ "max_bit_rate": vBitRate,
208
+ "sample_aspect_ratio": "1",
209
+ "start_pts": 0,
210
+ "start_time": 0,
211
+ "time_base": vTimeBase,
212
+ "type": "StreamVideo",
213
+ "width": vWidth
214
+ }; // placeholder stream to use if [aStreamIndex, vStreamIndex].sort() is not [0,1]
215
+ DUMMY_STREAM = {
216
+ "bit_rate": 0,
217
+ "codec_name": "",
218
+ "duration": DUMMY_DURATION,
219
+ "duration_ts": 2500 * DUMMY_DURATION,
220
+ "frame_count": 1,
221
+ "language": "",
222
+ "max_bit_rate": 0,
223
+ "start_pts": 0,
224
+ "start_time": 0,
225
+ "time_base": "1/2500",
226
+ "type": "StreamData"
227
+ };
228
+ sourceStreams = [];
229
+ maxStreamIndex = Math.max(aStreamIndex, vStreamIndex);
230
+ for (i = 0; i <= maxStreamIndex; i++) {
231
+ if (i === aStreamIndex) {
232
+ sourceStreams.push(sourceAudioStream);
233
+ } else if (i === vStreamIndex) {
234
+ sourceStreams.push(sourceVideoStream);
235
+ } else {
236
+ sourceStreams.push(DUMMY_STREAM);
237
+ }
238
+ }
239
+
240
+ // construct /production_master/sources
241
+ sources = _defineProperty({}, streamUrl, {
242
+ "container_format": {
243
+ "duration": DUMMY_DURATION,
244
+ "filename": streamUrl,
245
+ "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
246
+ "start_time": 0
247
+ },
248
+ "streams": sourceStreams
249
+ }); // construct /production_master/variants
250
+ variants = {
251
+ "default": {
252
+ "streams": {
253
+ "audio": {
254
+ "default_for_media_type": false,
255
+ "label": "",
256
+ "language": "",
257
+ "mapping_info": "",
258
+ "sources": [{
259
+ "files_api_path": streamUrl,
260
+ "stream_index": aStreamIndex
261
+ }]
262
+ },
263
+ "video": {
264
+ "default_for_media_type": false,
265
+ "label": "",
266
+ "language": "",
267
+ "mapping_info": "",
268
+ "sources": [{
269
+ "files_api_path": streamUrl,
270
+ "stream_index": vStreamIndex
271
+ }]
272
+ }
273
+ }
274
+ }
275
+ }; // construct /production_master
276
+ production_master = {
277
+ sources: sources,
278
+ variants: variants
279
+ }; // get existing metadata
280
+ console.log("Retrieving current metadata...");
281
+ _context3.next = 16;
282
+ return client.ContentObjectMetadata({
283
+ libraryId: libraryId,
284
+ objectId: objectId
285
+ });
286
+ case 16:
287
+ metadata = _context3.sent;
288
+ // add /production_master to metadata
289
+ metadata.production_master = production_master;
290
+
291
+ // write back to object
292
+ console.log("Getting write token...");
293
+ _context3.next = 21;
294
+ return client.EditContentObject({
295
+ libraryId: libraryId,
296
+ objectId: objectId,
297
+ options: {
298
+ type: typeAbrMaster
299
+ }
300
+ });
301
+ case 21:
302
+ editResponse = _context3.sent;
303
+ writeToken = editResponse.write_token;
304
+ console.log("New write token: ".concat(writeToken));
305
+ console.log("Writing back metadata with /production_master added...");
306
+ _context3.next = 27;
307
+ return client.ReplaceMetadata({
308
+ libraryId: libraryId,
309
+ metadata: metadata,
310
+ objectId: objectId,
311
+ writeToken: writeToken
312
+ });
313
+ case 27:
314
+ console.log("Finalizing...");
315
+ _context3.next = 30;
316
+ return client.FinalizeContentObject({
317
+ libraryId: libraryId,
318
+ objectId: objectId,
319
+ writeToken: writeToken
320
+ });
321
+ case 30:
322
+ finalizeResponse = _context3.sent;
323
+ masterVersionHash = finalizeResponse.hash;
324
+ console.log("Finalized, new version hash: ".concat(masterVersionHash));
325
+
326
+ // Generate offering
327
+ _context3.next = 35;
328
+ return client.CreateABRMezzanine({
329
+ libraryId: libraryId,
330
+ objectId: objectId,
331
+ masterVersionHash: masterVersionHash,
332
+ variant: "default",
333
+ offeringKey: "default",
334
+ abrProfile: abrProfile
335
+ });
336
+ case 35:
337
+ createResponse = _context3.sent;
338
+ if (createResponse.warnings.length > 0) {
339
+ console.log("WARNINGS:");
340
+ console.log(JSON.stringify(createResponse.warnings, null, 2));
341
+ }
342
+ if (createResponse.errors.length > 0) {
343
+ console.log("ERRORS:");
344
+ console.log(JSON.stringify(createResponse.errors, null, 2));
345
+ }
346
+ versionHash = createResponse.hash;
347
+ console.log("New version hash: ".concat(versionHash));
348
+
349
+ // get new metadata
350
+ console.log("Retrieving revised metadata with offering...");
351
+ _context3.next = 43;
352
+ return client.ContentObjectMetadata({
353
+ libraryId: libraryId,
354
+ versionHash: versionHash
355
+ });
356
+ case 43:
357
+ metadata = _context3.sent;
358
+ console.log("Moving /abr_mezzanine/offerings to /offerings and removing /abr_mezzanine...");
359
+ metadata.offerings = metadata.abr_mezzanine.offerings;
360
+ delete metadata.abr_mezzanine;
361
+
362
+ // add items to media_struct needed to use options.json handler
363
+ metadata.offerings["default"].media_struct.duration_rat = "".concat(DUMMY_DURATION);
364
+
365
+ // write back to object
366
+ console.log("Getting write token...");
367
+ _context3.next = 51;
368
+ return client.EditContentObject({
369
+ libraryId: libraryId,
370
+ objectId: objectId,
371
+ options: {
372
+ type: typeLiveStream
373
+ }
374
+ });
375
+ case 51:
376
+ editResponse = _context3.sent;
377
+ writeToken = editResponse.write_token;
378
+ console.log("New write token: ".concat(writeToken));
379
+ console.log("Writing back metadata with /offerings...");
380
+ _context3.next = 57;
381
+ return client.ReplaceMetadata({
382
+ libraryId: libraryId,
383
+ metadata: metadata,
384
+ objectId: objectId,
385
+ writeToken: writeToken
386
+ });
387
+ case 57:
388
+ console.log("Finalizing...");
389
+ _context3.next = 60;
390
+ return client.FinalizeContentObject({
391
+ libraryId: libraryId,
392
+ objectId: objectId,
393
+ writeToken: writeToken
394
+ });
395
+ case 60:
396
+ finalizeResponse = _context3.sent;
397
+ finalHash = finalizeResponse.hash;
398
+ console.log("Finalized, new version hash: ".concat(finalHash));
399
+ return _context3.abrupt("return", finalHash);
400
+ case 64:
401
+ case "end":
402
+ return _context3.stop();
403
+ }
404
+ }, _callee3);
405
+ }));
406
+ return function StreamGenerateOffering(_x3) {
407
+ return _ref6.apply(this, arguments);
408
+ };
409
+ }();
410
+
411
+ /**
412
+ * Retrieve the status of the current live stream session
413
+ *
414
+ * @methodGroup Live Stream
415
+ * @namedParams
416
+ * @param {string} name - Object ID or name of the live stream object
417
+ * @param {boolean=} stopLro - If specified, will stop LRO
418
+ * @param {boolean=} showParams - If specified, will return recording_params with status
419
+ * States:
420
+ * unconfigured - no live_recording_config
421
+ * uninitialized - no live_recording config generated
422
+ * inactive - live_recording config initialized but no 'edge write token'
423
+ * stopped - edge-write-token but not started
424
+ * starting - LRO running but no source data yet
425
+ * running - stream is running and producing output
426
+ * stalled - LRO running but no source data (so not producing output)
427
+ *
428
+ * @return {Promise<Object>} - The status response for the object, as well as logs, warnings and errors from the master initialization
429
+ */
430
+ exports.StreamStatus = /*#__PURE__*/function () {
431
+ var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref7) {
432
+ var name, _ref7$stopLro, stopLro, _ref7$showParams, showParams, objectId, status, libraryId, mainMeta, fabURI, edgeWriteToken, edgeMeta, recordings, sequence, period, tlro, videoLastFinalizationTimeEpochSec, videoFinalizedParts, sinceLastFinalize, recording_period, insertions, i, insertionTimeSinceEpoch, state, lroStatus, segDurationMeta, playout_urls, playout_options, hls_clear_enabled, hls_aes128_enabled, hls_sample_aes_enabled, networkInfo, token, embed_net, embed_url;
433
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
434
+ while (1) switch (_context4.prev = _context4.next) {
435
+ case 0:
436
+ name = _ref7.name, _ref7$stopLro = _ref7.stopLro, stopLro = _ref7$stopLro === void 0 ? false : _ref7$stopLro, _ref7$showParams = _ref7.showParams, showParams = _ref7$showParams === void 0 ? false : _ref7$showParams;
437
+ objectId = name;
438
+ status = {
439
+ name: name
440
+ };
441
+ _context4.prev = 3;
442
+ _context4.next = 6;
443
+ return this.ContentObjectLibraryId({
444
+ objectId: objectId
445
+ });
446
+ case 6:
447
+ libraryId = _context4.sent;
448
+ status.library_id = libraryId;
449
+ status.object_id = objectId;
450
+ _context4.next = 11;
451
+ return this.ContentObjectMetadata({
452
+ libraryId: libraryId,
453
+ objectId: objectId,
454
+ select: ["live_recording_config", "live_recording"]
455
+ });
456
+ case 11:
457
+ mainMeta = _context4.sent;
458
+ status.reference_url = mainMeta.live_recording_config.reference_url;
459
+ if (!(mainMeta.live_recording_config == undefined || mainMeta.live_recording_config.url == undefined)) {
460
+ _context4.next = 16;
461
+ break;
462
+ }
463
+ status.state = "unconfigured";
464
+ return _context4.abrupt("return", status);
465
+ case 16:
466
+ if (!(mainMeta.live_recording == undefined || mainMeta.live_recording.fabric_config == undefined || mainMeta.live_recording.playout_config == undefined || mainMeta.live_recording.recording_config == undefined)) {
467
+ _context4.next = 19;
468
+ break;
469
+ }
470
+ status.state = "uninitialized";
471
+ return _context4.abrupt("return", status);
472
+ case 19:
473
+ fabURI = mainMeta.live_recording.fabric_config.ingress_node_api;
474
+ if (!(fabURI === undefined)) {
475
+ _context4.next = 24;
476
+ break;
477
+ }
478
+ console.log("bad fabric config - missing ingress node API");
479
+ status.state = "uninitialized";
480
+ return _context4.abrupt("return", status);
481
+ case 24:
482
+ // Support both hostname and URL ingress_node_api
483
+ if (!fabURI.startsWith("http")) {
484
+ // Assume https
485
+ fabURI = "https://" + fabURI;
486
+ }
487
+ status.fabric_api = fabURI;
488
+ status.url = mainMeta.live_recording.recording_config.recording_params.origin_url;
489
+ edgeWriteToken = mainMeta.live_recording.fabric_config.edge_write_token;
490
+ if (edgeWriteToken) {
491
+ _context4.next = 31;
492
+ break;
493
+ }
494
+ status.state = "inactive";
495
+ return _context4.abrupt("return", status);
496
+ case 31:
497
+ this.RecordWriteToken({
498
+ writeToken: edgeWriteToken,
499
+ fabricNodeUrl: fabURI
500
+ });
501
+ status.edge_write_token = edgeWriteToken;
502
+ status.stream_id = edgeWriteToken; // By convention the stream ID is its write token
503
+ _context4.prev = 34;
504
+ _context4.next = 37;
505
+ return this.ContentObjectMetadata({
506
+ libraryId: libraryId,
507
+ objectId: objectId,
508
+ writeToken: edgeWriteToken,
509
+ select: ["live_recording"]
510
+ });
511
+ case 37:
512
+ edgeMeta = _context4.sent;
513
+ _context4.next = 45;
514
+ break;
515
+ case 40:
516
+ _context4.prev = 40;
517
+ _context4.t0 = _context4["catch"](34);
518
+ console.error("Unable to read edge write token metadata. Has token been deleted?", _context4.t0);
519
+ status.state = "inactive";
520
+ return _context4.abrupt("return", status);
521
+ case 45:
522
+ status.edge_meta_size = JSON.stringify(edgeMeta || "").length;
523
+
524
+ // If a stream has never been started return state 'inactive'
525
+ if (!(edgeMeta.live_recording === undefined || edgeMeta.live_recording.recordings === undefined || edgeMeta.live_recording.recordings.recording_sequence === undefined)) {
526
+ _context4.next = 49;
527
+ break;
528
+ }
529
+ status.state = "stopped";
530
+ return _context4.abrupt("return", status);
531
+ case 49:
532
+ recordings = edgeMeta.live_recording.recordings;
533
+ status.recording_period_sequence = recordings.recording_sequence;
534
+ sequence = recordings.recording_sequence;
535
+ period = recordings.live_offering[sequence - 1];
536
+ tlro = period.live_recording_handle;
537
+ status.tlro = tlro;
538
+ videoLastFinalizationTimeEpochSec = -1;
539
+ videoFinalizedParts = 0;
540
+ sinceLastFinalize = -1;
541
+ if (period.finalized_parts_info && period.finalized_parts_info.video && period.finalized_parts_info.video.last_finalization_time) {
542
+ videoLastFinalizationTimeEpochSec = period.finalized_parts_info.video.last_finalization_time / 1000000;
543
+ videoFinalizedParts = period.finalized_parts_info.video.n_parts;
544
+ sinceLastFinalize = Math.floor(new Date().getTime() / 1000) - videoLastFinalizationTimeEpochSec;
545
+ }
546
+ recording_period = {
547
+ activation_time_epoch_sec: period.recording_start_time_epoch_sec,
548
+ start_time_epoch_sec: period.start_time_epoch_sec,
549
+ start_time_text: new Date(period.start_time_epoch_sec * 1000).toLocaleString(),
550
+ end_time_epoch_sec: period.end_time_epoch_sec,
551
+ end_time_text: period.end_time_epoch_sec === 0 ? null : new Date(period.end_time_epoch_sec * 1000).toLocaleString(),
552
+ video_parts: videoFinalizedParts,
553
+ video_last_part_finalized_epoch_sec: videoLastFinalizationTimeEpochSec,
554
+ video_since_last_finalize_sec: sinceLastFinalize
555
+ };
556
+ status.recording_period = recording_period;
557
+ _context4.next = 63;
558
+ return this.FabricUrl({
559
+ libraryId: libraryId,
560
+ objectId: objectId,
561
+ writeToken: edgeWriteToken,
562
+ call: "live/status/" + tlro
563
+ });
564
+ case 63:
565
+ status.lro_status_url = _context4.sent;
566
+ status.insertions = [];
567
+ if (edgeMeta.live_recording.playout_config.interleaves != undefined && edgeMeta.live_recording.playout_config.interleaves[sequence] != undefined) {
568
+ insertions = edgeMeta.live_recording.playout_config.interleaves[sequence];
569
+ for (i = 0; i < insertions.length; i++) {
570
+ insertionTimeSinceEpoch = recording_period.start_time_epoch_sec + insertions[i].insertion_time;
571
+ status.insertions[i] = {
572
+ insertion_time_since_start: insertions[i].insertion_time,
573
+ insertion_time: new Date(insertionTimeSinceEpoch * 1000).toISOString(),
574
+ insertion_time_local: new Date(insertionTimeSinceEpoch * 1000).toLocaleString(),
575
+ target: insertions[i].playout
576
+ };
577
+ }
578
+ }
579
+ if (showParams) {
580
+ status.recording_params = edgeMeta.live_recording.recording_config.recording_params;
581
+ }
582
+ state = "stopped";
583
+ lroStatus = "";
584
+ _context4.prev = 69;
585
+ _context4.t1 = this.utils;
586
+ _context4.next = 73;
587
+ return HttpClient.Fetch(status.lro_status_url);
588
+ case 73:
589
+ _context4.t2 = _context4.sent;
590
+ _context4.next = 76;
591
+ return _context4.t1.ResponseToJson.call(_context4.t1, _context4.t2);
592
+ case 76:
593
+ lroStatus = _context4.sent;
594
+ state = lroStatus.state;
595
+ status.warnings = lroStatus.custom && lroStatus.custom.warnings;
596
+ status.quality = lroStatus.custom && lroStatus.custom.quality;
597
+ if (lroStatus.custom && lroStatus.custom.status) {
598
+ status.recording_status = lroStatus.custom.status;
599
+ }
600
+ _context4.next = 89;
601
+ break;
602
+ case 83:
603
+ _context4.prev = 83;
604
+ _context4.t3 = _context4["catch"](69);
605
+ console.log("LRO Status (failed): ", _context4.t3.response.statusCode);
606
+ status.state = "stopped";
607
+ status.error = _context4.t3.response;
608
+ return _context4.abrupt("return", status);
609
+ case 89:
610
+ segDurationMeta = edgeMeta.live_recording.recording_config.recording_params.xc_params.seg_duration; // Convert LRO 'state' to desired 'state'
611
+ if (state === "running" && videoLastFinalizationTimeEpochSec <= 0) {
612
+ state = "starting";
613
+ } else if (state === "running" && segDurationMeta !== undefined && sinceLastFinalize > parseInt(segDurationMeta) + 5) {
614
+ state = "stalled";
615
+ } else if (state == "terminated") {
616
+ state = "stopped";
617
+ }
618
+ status.state = state;
619
+ if (!((state === "running" || state === "stalled" || state === "starting") && stopLro)) {
620
+ _context4.next = 111;
621
+ break;
622
+ }
623
+ _context4.next = 95;
624
+ return this.FabricUrl({
625
+ libraryId: libraryId,
626
+ objectId: objectId,
627
+ writeToken: edgeWriteToken,
628
+ call: "live/stop/" + tlro
629
+ });
630
+ case 95:
631
+ lroStopUrl = _context4.sent;
632
+ _context4.prev = 96;
633
+ _context4.t4 = this.utils;
634
+ _context4.next = 100;
635
+ return HttpClient.Fetch(lroStopUrl);
636
+ case 100:
637
+ _context4.t5 = _context4.sent;
638
+ _context4.next = 103;
639
+ return _context4.t4.ResponseToJson.call(_context4.t4, _context4.t5);
640
+ case 103:
641
+ console.log("LRO Stop: ", lroStatus.body);
642
+ _context4.next = 109;
643
+ break;
644
+ case 106:
645
+ _context4.prev = 106;
646
+ _context4.t6 = _context4["catch"](96);
647
+ console.log("LRO Stop (failed): ", _context4.t6.response.statusCode);
648
+ case 109:
649
+ state = "stopped";
650
+ status.state = state;
651
+ case 111:
652
+ if (!(state === "running")) {
653
+ _context4.next = 142;
654
+ break;
655
+ }
656
+ playout_urls = {};
657
+ _context4.next = 115;
658
+ return this.PlayoutOptions({
659
+ objectId: objectId,
660
+ linkPath: "public/asset_metadata/sources/default"
661
+ });
662
+ case 115:
663
+ playout_options = _context4.sent;
664
+ hls_clear_enabled = playout_options && playout_options.hls && playout_options.hls.playoutMethods && playout_options.hls.playoutMethods.clear !== undefined;
665
+ if (!hls_clear_enabled) {
666
+ _context4.next = 121;
667
+ break;
668
+ }
669
+ _context4.next = 120;
670
+ return this.FabricUrl({
671
+ libraryId: libraryId,
672
+ objectId: objectId,
673
+ rep: "playout/default/hls-clear/playlist.m3u8"
674
+ });
675
+ case 120:
676
+ playout_urls.hls_clear = _context4.sent;
677
+ case 121:
678
+ hls_aes128_enabled = playout_options && playout_options.hls && playout_options.hls.playoutMethods && playout_options.hls.playoutMethods["aes-128"] !== undefined;
679
+ if (!hls_aes128_enabled) {
680
+ _context4.next = 126;
681
+ break;
682
+ }
683
+ _context4.next = 125;
684
+ return this.FabricUrl({
685
+ libraryId: libraryId,
686
+ objectId: objectId,
687
+ rep: "playout/default/hls-aes128/playlist.m3u8"
688
+ });
689
+ case 125:
690
+ playout_urls.hls_aes128 = _context4.sent;
691
+ case 126:
692
+ hls_sample_aes_enabled = playout_options && playout_options.hls && playout_options.hls.playoutMethods && playout_options.hls.playoutMethods["sample-aes"] !== undefined;
693
+ if (!hls_sample_aes_enabled) {
694
+ _context4.next = 131;
695
+ break;
696
+ }
697
+ _context4.next = 130;
698
+ return this.FabricUrl({
699
+ libraryId: libraryId,
700
+ objectId: objectId,
701
+ rep: "playout/default/hls-sample-aes/playlist.m3u8"
702
+ });
703
+ case 130:
704
+ playout_urls.hls_sample_aes = _context4.sent;
705
+ case 131:
706
+ _context4.next = 133;
707
+ return this.NetworkInfo();
708
+ case 133:
709
+ networkInfo = _context4.sent;
710
+ _context4.next = 136;
711
+ return this.authClient.AuthorizationToken({
712
+ libraryId: libraryId,
713
+ objectId: objectId,
714
+ channelAuth: false,
715
+ noCache: true,
716
+ noAuth: true
717
+ });
718
+ case 136:
719
+ token = _context4.sent;
720
+ embed_net = "main";
721
+ if (networkInfo.name.includes("demo")) {
722
+ embed_net = "demo";
723
+ }
724
+ embed_url = "https://embed.v3.contentfabric.io/?net=".concat(embed_net, "&p&ct=h&oid=").concat(objectId, "&mt=lv&ath=").concat(token);
725
+ playout_urls.embed_url = embed_url;
726
+ status.playout_urls = playout_urls;
727
+ case 142:
728
+ _context4.next = 147;
729
+ break;
730
+ case 144:
731
+ _context4.prev = 144;
732
+ _context4.t7 = _context4["catch"](3);
733
+ console.error(_context4.t7);
734
+ case 147:
735
+ return _context4.abrupt("return", status);
736
+ case 148:
737
+ case "end":
738
+ return _context4.stop();
739
+ }
740
+ }, _callee4, this, [[3, 144], [34, 40], [69, 83], [96, 106]]);
741
+ }));
742
+ return function (_x4) {
743
+ return _ref8.apply(this, arguments);
744
+ };
745
+ }();
746
+
747
+ /**
748
+ * Create a new edge write token
749
+ *
750
+ * @methodGroup Live Stream
751
+ * @namedParams
752
+ * @param {string} name - Object ID or name of the live stream object
753
+ * @param {boolean=} start - If specified, will start the stream after creation
754
+ *
755
+ * @return {Promise<Object>} - The status response for the object
756
+ *
757
+ */
758
+ exports.StreamCreate = /*#__PURE__*/function () {
759
+ var _ref10 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(_ref9) {
760
+ var name, _ref9$start, start, status, objectId, libraryId, liveRecording, fabURI, response, edgeToken, writeToken, objectHash;
761
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
762
+ while (1) switch (_context5.prev = _context5.next) {
763
+ case 0:
764
+ name = _ref9.name, _ref9$start = _ref9.start, start = _ref9$start === void 0 ? false : _ref9$start;
765
+ _context5.next = 3;
766
+ return this.StreamStatus({
767
+ name: name
768
+ });
769
+ case 3:
770
+ status = _context5.sent;
771
+ if (!(status.state != "uninitialized" && status.state !== "inactive" && status.state !== "terminated" && status.state !== "stopped")) {
772
+ _context5.next = 6;
773
+ break;
774
+ }
775
+ return _context5.abrupt("return", {
776
+ state: status.state,
777
+ error: "stream still active - must terminate first"
778
+ });
779
+ case 6:
780
+ objectId = status.object_id;
781
+ console.log("START: ", name, "start", start);
782
+ _context5.next = 10;
783
+ return this.ContentObjectLibraryId({
784
+ objectId: objectId
785
+ });
786
+ case 10:
787
+ libraryId = _context5.sent;
788
+ _context5.next = 13;
789
+ return this.ContentObjectMetadata({
790
+ libraryId: libraryId,
791
+ objectId: objectId,
792
+ metadataSubtree: "/live_recording"
793
+ });
794
+ case 13:
795
+ liveRecording = _context5.sent;
796
+ fabURI = liveRecording.fabric_config.ingress_node_api; // Support both hostname and URL ingress_node_api
797
+ if (!fabURI.startsWith("http")) {
798
+ // Assume https
799
+ fabURI = "https://" + fabURI;
800
+ }
801
+ this.SetNodes({
802
+ fabricURIs: [fabURI]
803
+ });
804
+ console.log("Node URI", fabURI, "ID", liveRecording.fabric_config.ingress_node_id);
805
+ _context5.next = 20;
806
+ return this.EditContentObject({
807
+ libraryId: libraryId,
808
+ objectId: objectId
809
+ });
810
+ case 20:
811
+ response = _context5.sent;
812
+ edgeToken = response.write_token;
813
+ console.log("Edge token:", edgeToken);
814
+
815
+ /*
816
+ * Set the metadata, including the edge token.
817
+ */
818
+ _context5.next = 25;
819
+ return this.EditContentObject({
820
+ libraryId: libraryId,
821
+ objectId: objectId
822
+ });
823
+ case 25:
824
+ response = _context5.sent;
825
+ writeToken = response.write_token;
826
+ this.Log("Merging metadata: ", libraryId, objectId, writeToken);
827
+ _context5.next = 30;
828
+ return this.MergeMetadata({
829
+ libraryId: libraryId,
830
+ objectId: objectId,
831
+ writeToken: writeToken,
832
+ metadata: {
833
+ live_recording: {
834
+ status: {
835
+ edge_write_token: edgeToken,
836
+ state: "active" // indicates there is an active session (set to 'closed' when done)
837
+ },
838
+
839
+ fabric_config: {
840
+ edge_write_token: edgeToken
841
+ }
842
+ }
843
+ }
844
+ });
845
+ case 30:
846
+ this.Log("Finalizing content draft: ", libraryId, objectId, writeToken);
847
+ _context5.next = 33;
848
+ return this.FinalizeContentObject({
849
+ libraryId: libraryId,
850
+ objectId: objectId,
851
+ writeToken: writeToken,
852
+ commitMessage: "Create stream edge write token " + edgeToken
853
+ });
854
+ case 33:
855
+ response = _context5.sent;
856
+ objectHash = response.hash;
857
+ this.Log("Finalized object: ", objectHash);
858
+ status = {
859
+ object_id: objectId,
860
+ hash: objectHash,
861
+ library_id: libraryId,
862
+ stream_id: edgeToken,
863
+ edge_write_token: edgeToken,
864
+ fabric_api: fabURI,
865
+ state: "stopped"
866
+ };
867
+ if (start) {
868
+ status = this.StreamStartOrStopOrReset({
869
+ name: name,
870
+ op: start
871
+ });
872
+ }
873
+ return _context5.abrupt("return", status);
874
+ case 39:
875
+ case "end":
876
+ return _context5.stop();
877
+ }
878
+ }, _callee5, this);
879
+ }));
880
+ return function (_x5) {
881
+ return _ref10.apply(this, arguments);
882
+ };
883
+ }();
884
+
885
+ /**
886
+ * Start, stop or reset a stream within the current session (current edge write token)
887
+ *
888
+ * @methodGroup Live Stream
889
+ * @namedParams
890
+ * @param {string} name - Object ID or name of the live stream object
891
+ * @param {string} op - The operation to perform. Possible values:
892
+ * 'start'
893
+ * 'reset' - Stops current LRO recording and starts a new one. Does
894
+ * not create a new edge write token (just creates a new recording
895
+ * period in the existing edge write token)
896
+ * - 'stop'
897
+ *
898
+ * @return {Promise<Object>} - The status response for the stream
899
+ *
900
+ */
901
+ exports.StreamStartOrStopOrReset = /*#__PURE__*/function () {
902
+ var _ref12 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(_ref11) {
903
+ var name, op, status, _tries, tries;
904
+ return _regeneratorRuntime.wrap(function _callee6$(_context6) {
905
+ while (1) switch (_context6.prev = _context6.next) {
906
+ case 0:
907
+ name = _ref11.name, op = _ref11.op;
908
+ _context6.prev = 1;
909
+ _context6.next = 4;
910
+ return this.StreamStatus({
911
+ name: name
912
+ });
913
+ case 4:
914
+ status = _context6.sent;
915
+ if (!(status.state != "stopped")) {
916
+ _context6.next = 9;
917
+ break;
918
+ }
919
+ if (!(op === "start")) {
920
+ _context6.next = 9;
921
+ break;
922
+ }
923
+ status.error = "Unable to start stream - state: " + status.state;
924
+ return _context6.abrupt("return", status);
925
+ case 9:
926
+ if (!(status.state == "running" || status.state == "starting" || status.state == "stalled")) {
927
+ _context6.next = 31;
928
+ break;
929
+ }
930
+ _context6.prev = 10;
931
+ _context6.next = 13;
932
+ return this.CallBitcodeMethod({
933
+ libraryId: status.library_id,
934
+ objectId: status.object_id,
935
+ writeToken: status.edge_write_token,
936
+ method: "/live/stop/" + status.tlro,
937
+ constant: false
938
+ });
939
+ case 13:
940
+ _context6.next = 17;
941
+ break;
942
+ case 15:
943
+ _context6.prev = 15;
944
+ _context6.t0 = _context6["catch"](10);
945
+ case 17:
946
+ // Wait until LRO is terminated
947
+ _tries = 10;
948
+ case 18:
949
+ if (!(status.state != "stopped" && _tries-- > 0)) {
950
+ _context6.next = 27;
951
+ break;
952
+ }
953
+ console.log("Wait to terminate - ", status.state);
954
+ _context6.next = 22;
955
+ return Sleep(1000);
956
+ case 22:
957
+ _context6.next = 24;
958
+ return this.StreamStatus({
959
+ name: name
960
+ });
961
+ case 24:
962
+ status = _context6.sent;
963
+ _context6.next = 18;
964
+ break;
965
+ case 27:
966
+ console.log("Status after stop - ", status.state);
967
+ if (!(_tries <= 0)) {
968
+ _context6.next = 31;
969
+ break;
970
+ }
971
+ console.log("Failed to stop");
972
+ return _context6.abrupt("return", status);
973
+ case 31:
974
+ if (!(op === "stop")) {
975
+ _context6.next = 33;
976
+ break;
977
+ }
978
+ return _context6.abrupt("return", status);
979
+ case 33:
980
+ console.log("STARTING", "edge_write_token", status.edge_write_token);
981
+ _context6.prev = 34;
982
+ _context6.next = 37;
983
+ return this.CallBitcodeMethod({
984
+ libraryId: status.library_id,
985
+ objectId: status.object_id,
986
+ writeToken: status.edge_write_token,
987
+ method: "/live/start",
988
+ constant: false
989
+ });
990
+ case 37:
991
+ _context6.next = 43;
992
+ break;
993
+ case 39:
994
+ _context6.prev = 39;
995
+ _context6.t1 = _context6["catch"](34);
996
+ console.log("LRO Start (failed): ", _context6.t1);
997
+ return _context6.abrupt("return", {
998
+ state: status.state,
999
+ error: "LRO start failed - must create a stream first"
1000
+ });
1001
+ case 43:
1002
+ // Wait until LRO is 'starting'
1003
+ tries = 10;
1004
+ case 44:
1005
+ if (!(status.state != "starting" && tries-- > 0)) {
1006
+ _context6.next = 53;
1007
+ break;
1008
+ }
1009
+ console.log("Wait to start - ", status.state);
1010
+ _context6.next = 48;
1011
+ return Sleep(1000);
1012
+ case 48:
1013
+ _context6.next = 50;
1014
+ return this.StreamStatus({
1015
+ name: name
1016
+ });
1017
+ case 50:
1018
+ status = _context6.sent;
1019
+ _context6.next = 44;
1020
+ break;
1021
+ case 53:
1022
+ console.log("Status after restart - ", status.state);
1023
+ return _context6.abrupt("return", status);
1024
+ case 57:
1025
+ _context6.prev = 57;
1026
+ _context6.t2 = _context6["catch"](1);
1027
+ console.error(_context6.t2);
1028
+ case 60:
1029
+ case "end":
1030
+ return _context6.stop();
1031
+ }
1032
+ }, _callee6, this, [[1, 57], [10, 15], [34, 39]]);
1033
+ }));
1034
+ return function (_x6) {
1035
+ return _ref12.apply(this, arguments);
1036
+ };
1037
+ }();
1038
+
1039
+ /**
1040
+ * Close the edge write token and make the stream object inactive.
1041
+ *
1042
+ * @methodGroup Live Stream
1043
+ * @namedParams
1044
+ * @param {string} name - Object ID or name of the live stream object
1045
+ *
1046
+ * @return {Promise<Object>} - The finalize response for the stream object
1047
+ */
1048
+ exports.StreamStopSession = /*#__PURE__*/function () {
1049
+ var _ref14 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(_ref13) {
1050
+ var name, objectId, libraryId, mainMeta, fabURI, metaEdgeWriteToken, streamMetadata, status, _yield$this$EditConte, writeToken, newState, stopTime, finalizeMetadata, fin;
1051
+ return _regeneratorRuntime.wrap(function _callee7$(_context7) {
1052
+ while (1) switch (_context7.prev = _context7.next) {
1053
+ case 0:
1054
+ name = _ref13.name;
1055
+ _context7.prev = 1;
1056
+ this.Log("Terminating stream session for: ".concat(name));
1057
+ objectId = name;
1058
+ _context7.next = 6;
1059
+ return this.ContentObjectLibraryId({
1060
+ objectId: objectId
1061
+ });
1062
+ case 6:
1063
+ libraryId = _context7.sent;
1064
+ _context7.next = 9;
1065
+ return this.ContentObjectMetadata({
1066
+ libraryId: libraryId,
1067
+ objectId: objectId
1068
+ });
1069
+ case 9:
1070
+ mainMeta = _context7.sent;
1071
+ fabURI = mainMeta.live_recording.fabric_config.ingress_node_api; // Support both hostname and URL ingress_node_api
1072
+ if (!fabURI.startsWith("http")) {
1073
+ // Assume https
1074
+ fabURI = "https://" + fabURI;
1075
+ }
1076
+ this.SetNodes({
1077
+ fabricURIs: [fabURI]
1078
+ });
1079
+ metaEdgeWriteToken = mainMeta.live_recording.fabric_config.edge_write_token;
1080
+ if (metaEdgeWriteToken) {
1081
+ _context7.next = 16;
1082
+ break;
1083
+ }
1084
+ return _context7.abrupt("return", {
1085
+ state: "inactive",
1086
+ error: "The stream is not active"
1087
+ });
1088
+ case 16:
1089
+ _context7.prev = 16;
1090
+ _context7.next = 19;
1091
+ return this.ContentObjectMetadata({
1092
+ libraryId: libraryId,
1093
+ objectId: objectId,
1094
+ writeToken: metaEdgeWriteToken
1095
+ });
1096
+ case 19:
1097
+ streamMetadata = _context7.sent;
1098
+ _context7.next = 22;
1099
+ return this.StreamStatus({
1100
+ name: name
1101
+ });
1102
+ case 22:
1103
+ status = _context7.sent;
1104
+ if (!(status.state !== "stopped")) {
1105
+ _context7.next = 25;
1106
+ break;
1107
+ }
1108
+ return _context7.abrupt("return", {
1109
+ state: status.state,
1110
+ error: "The stream must be stopped before terminating"
1111
+ });
1112
+ case 25:
1113
+ _context7.next = 27;
1114
+ return this.DeleteWriteToken({
1115
+ libraryId: libraryId,
1116
+ writeToken: metaEdgeWriteToken
1117
+ });
1118
+ case 27:
1119
+ _context7.next = 32;
1120
+ break;
1121
+ case 29:
1122
+ _context7.prev = 29;
1123
+ _context7.t0 = _context7["catch"](16);
1124
+ this.Log("Unable to retrieve metadata for edge write token");
1125
+ case 32:
1126
+ _context7.next = 34;
1127
+ return this.EditContentObject({
1128
+ libraryId: libraryId,
1129
+ objectId: objectId
1130
+ });
1131
+ case 34:
1132
+ _yield$this$EditConte = _context7.sent;
1133
+ writeToken = _yield$this$EditConte.writeToken;
1134
+ // Set stop time and inactive state
1135
+ newState = "inactive";
1136
+ stopTime = Math.floor(new Date().getTime() / 1000);
1137
+ finalizeMetadata = {
1138
+ live_recording: {
1139
+ status: {
1140
+ edge_write_token: "",
1141
+ state: newState,
1142
+ recording_stop_time: stopTime
1143
+ },
1144
+ fabric_config: {
1145
+ edge_write_token: ""
1146
+ }
1147
+ }
1148
+ };
1149
+ _context7.next = 41;
1150
+ return this.MergeMetadata({
1151
+ libraryId: libraryId,
1152
+ objectId: objectId,
1153
+ writeToken: writeToken,
1154
+ metadata: finalizeMetadata
1155
+ });
1156
+ case 41:
1157
+ _context7.next = 43;
1158
+ return this.FinalizeContentObject({
1159
+ libraryId: libraryId,
1160
+ objectId: objectId,
1161
+ writeToken: writeToken,
1162
+ commitMessage: "Deactivate live stream - stop time ".concat(stopTime)
1163
+ });
1164
+ case 43:
1165
+ fin = _context7.sent;
1166
+ return _context7.abrupt("return", {
1167
+ fin: fin,
1168
+ name: name,
1169
+ state: newState
1170
+ });
1171
+ case 47:
1172
+ _context7.prev = 47;
1173
+ _context7.t1 = _context7["catch"](1);
1174
+ console.error(_context7.t1);
1175
+ case 50:
1176
+ case "end":
1177
+ return _context7.stop();
1178
+ }
1179
+ }, _callee7, this, [[1, 47], [16, 29]]);
1180
+ }));
1181
+ return function (_x7) {
1182
+ return _ref14.apply(this, arguments);
1183
+ };
1184
+ }();
1185
+
1186
+ /**
1187
+ * Initialize the stream object
1188
+ *
1189
+ * @methodGroup Live Stream
1190
+ * @namedParams
1191
+ * @param {string} name - Object ID or name of the live stream object
1192
+ * @param {boolean=} drm - If specified, playout will be DRM protected
1193
+ * @param {string=} format - Specify the list of playout formats and DRM to support,
1194
+ comma-separated (hls-clear, hls-aes128, hls-sample-aes,
1195
+ hls-fairplay)
1196
+ *
1197
+ * @return {Promise<Object>} - The name, object ID, and state of the stream
1198
+ */
1199
+ exports.StreamInitialize = /*#__PURE__*/function () {
1200
+ var _ref16 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(_ref15) {
1201
+ var name, _ref15$drm, drm, format, typeAbrMaster, typeLiveStream, tenantContractId, _yield$this$ContentOb, live_stream, title, res;
1202
+ return _regeneratorRuntime.wrap(function _callee8$(_context8) {
1203
+ while (1) switch (_context8.prev = _context8.next) {
1204
+ case 0:
1205
+ name = _ref15.name, _ref15$drm = _ref15.drm, drm = _ref15$drm === void 0 ? false : _ref15$drm, format = _ref15.format;
1206
+ _context8.next = 3;
1207
+ return this.userProfileClient.TenantContractId();
1208
+ case 3:
1209
+ tenantContractId = _context8.sent;
1210
+ _context8.next = 6;
1211
+ return this.ContentObjectMetadata({
1212
+ libraryId: tenantContractId.replace("iten", "ilib"),
1213
+ objectId: tenantContractId.replace("iten", "iq__"),
1214
+ metadataSubtree: "public/content_types",
1215
+ select: ["live_stream", "title"]
1216
+ });
1217
+ case 6:
1218
+ _yield$this$ContentOb = _context8.sent;
1219
+ live_stream = _yield$this$ContentOb.live_stream;
1220
+ title = _yield$this$ContentOb.title;
1221
+ if (live_stream) {
1222
+ typeLiveStream = live_stream;
1223
+ }
1224
+ if (title) {
1225
+ typeAbrMaster = title;
1226
+ }
1227
+ if (!(typeAbrMaster === undefined || typeLiveStream === undefined)) {
1228
+ _context8.next = 14;
1229
+ break;
1230
+ }
1231
+ console.log("ERROR - unable to find content types", "ABR Master", typeAbrMaster, "Live Stream", typeLiveStream);
1232
+ return _context8.abrupt("return", {});
1233
+ case 14:
1234
+ _context8.next = 16;
1235
+ return this.StreamSetOfferingAndDRM({
1236
+ name: name,
1237
+ typeAbrMaster: typeAbrMaster,
1238
+ typeLiveStream: typeLiveStream,
1239
+ drm: drm,
1240
+ format: format
1241
+ });
1242
+ case 16:
1243
+ res = _context8.sent;
1244
+ return _context8.abrupt("return", res);
1245
+ case 18:
1246
+ case "end":
1247
+ return _context8.stop();
1248
+ }
1249
+ }, _callee8, this);
1250
+ }));
1251
+ return function (_x8) {
1252
+ return _ref16.apply(this, arguments);
1253
+ };
1254
+ }();
1255
+
1256
+ /**
1257
+ * Create a dummy VoD offering and initialize DRM keys.
1258
+ *
1259
+ * @methodGroup Live Stream
1260
+ * @namedParams
1261
+ * @param {string} name - Object ID or name of the live stream object
1262
+ * @param {string=} typeAbrMaster - Content type hash
1263
+ * @param {string=} typeLiveStream - Content type hash
1264
+ * @param {boolean=} drm - If specified, DRM will be applied to the stream
1265
+ * @param {string=} format - A list of playout formats and DRM to support, comma-separated
1266
+ * (hls-clear, hls-aes128, hls-sample-aes, hls-fairplay). If specified,
1267
+ * this will take precedence over the drm value
1268
+ *
1269
+ * @return {Promise<Object>} - The name, object ID, and state of the stream
1270
+ */
1271
+ exports.StreamSetOfferingAndDRM = /*#__PURE__*/function () {
1272
+ var _ref18 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(_ref17) {
1273
+ var name, typeAbrMaster, typeLiveStream, _ref17$drm, drm, format, status, objectId, aBitRate, aChannels, aSampleRate, aStreamIndex, aTimeBase, aChannelLayout, vBitRate, vHeight, vStreamIndex, vWidth, vDisplayAspectRatio, vFrameRate, vTimeBase, abrProfileDefault, playoutFormats, abrProfile, formats, i, libraryId, mainMeta, fabURI, streamUrl;
1274
+ return _regeneratorRuntime.wrap(function _callee9$(_context9) {
1275
+ while (1) switch (_context9.prev = _context9.next) {
1276
+ case 0:
1277
+ name = _ref17.name, typeAbrMaster = _ref17.typeAbrMaster, typeLiveStream = _ref17.typeLiveStream, _ref17$drm = _ref17.drm, drm = _ref17$drm === void 0 ? false : _ref17$drm, format = _ref17.format;
1278
+ _context9.next = 3;
1279
+ return this.StreamStatus({
1280
+ name: name
1281
+ });
1282
+ case 3:
1283
+ status = _context9.sent;
1284
+ if (!(status.state != "uninitialized" && status.state != "inactive" && status.state != "stopped")) {
1285
+ _context9.next = 6;
1286
+ break;
1287
+ }
1288
+ return _context9.abrupt("return", {
1289
+ state: status.state,
1290
+ error: "stream still active - must terminate first"
1291
+ });
1292
+ case 6:
1293
+ objectId = status.object_id;
1294
+ console.log("INIT: ", name, objectId);
1295
+ aBitRate = 128000;
1296
+ aChannels = 2;
1297
+ aSampleRate = 48000;
1298
+ aStreamIndex = 1;
1299
+ aTimeBase = "1/48000";
1300
+ aChannelLayout = "stereo";
1301
+ vBitRate = 14000000;
1302
+ vHeight = 720;
1303
+ vStreamIndex = 0;
1304
+ vWidth = 1280;
1305
+ vDisplayAspectRatio = "16/9";
1306
+ vFrameRate = "30000/1001";
1307
+ vTimeBase = "1/30000"; // "1/16000";
1308
+ abrProfileDefault = require("../abr_profiles/abr_profile_live_drm.js");
1309
+ abrProfile = JSON.parse(JSON.stringify(abrProfileDefault));
1310
+ if (!format) {
1311
+ _context9.next = 43;
1312
+ break;
1313
+ }
1314
+ drm = true; // Override DRM parameter
1315
+ playoutFormats = {};
1316
+ formats = format.split(",");
1317
+ i = 0;
1318
+ case 28:
1319
+ if (!(i < formats.length)) {
1320
+ _context9.next = 41;
1321
+ break;
1322
+ }
1323
+ if (!(formats[i] === "hls-clear")) {
1324
+ _context9.next = 33;
1325
+ break;
1326
+ }
1327
+ abrProfile.drm_optional = true;
1328
+ playoutFormats["hls-clear"] = {
1329
+ "drm": null,
1330
+ "protocol": {
1331
+ "type": "ProtoHls"
1332
+ }
1333
+ };
1334
+ return _context9.abrupt("continue", 38);
1335
+ case 33:
1336
+ if (!(formats[i] === "dash-clear")) {
1337
+ _context9.next = 37;
1338
+ break;
1339
+ }
1340
+ abrProfile.drm_optional = true;
1341
+ playoutFormats["dash-clear"] = {
1342
+ "drm": null,
1343
+ "protocol": {
1344
+ "min_buffer_length": 2,
1345
+ "type": "ProtoDash"
1346
+ }
1347
+ };
1348
+ return _context9.abrupt("continue", 38);
1349
+ case 37:
1350
+ playoutFormats[formats[i]] = abrProfile.playout_formats[formats[i]];
1351
+ case 38:
1352
+ i++;
1353
+ _context9.next = 28;
1354
+ break;
1355
+ case 41:
1356
+ _context9.next = 44;
1357
+ break;
1358
+ case 43:
1359
+ if (!drm) {
1360
+ abrProfile.drm_optional = true;
1361
+ playoutFormats = {
1362
+ "hls-clear": {
1363
+ "drm": null,
1364
+ "protocol": {
1365
+ "type": "ProtoHls"
1366
+ }
1367
+ },
1368
+ "dash-clear": {
1369
+ "drm": null,
1370
+ "protocol": {
1371
+ "min_buffer_length": 2,
1372
+ "type": "ProtoDash"
1373
+ }
1374
+ }
1375
+ };
1376
+ } else {
1377
+ playoutFormats = Object.assign({}, abrProfile.playout_formats);
1378
+ }
1379
+ case 44:
1380
+ abrProfile.playout_formats = playoutFormats;
1381
+ _context9.next = 47;
1382
+ return this.ContentObjectLibraryId({
1383
+ objectId: objectId
1384
+ });
1385
+ case 47:
1386
+ libraryId = _context9.sent;
1387
+ _context9.prev = 48;
1388
+ _context9.next = 51;
1389
+ return this.ContentObjectMetadata({
1390
+ libraryId: libraryId,
1391
+ objectId: objectId
1392
+ });
1393
+ case 51:
1394
+ mainMeta = _context9.sent;
1395
+ fabURI = mainMeta.live_recording.fabric_config.ingress_node_api; // Support both hostname and URL ingress_node_api
1396
+ if (!fabURI.startsWith("http")) {
1397
+ // Assume https
1398
+ fabURI = "https://" + fabURI;
1399
+ }
1400
+ this.SetNodes({
1401
+ fabricURIs: [fabURI]
1402
+ });
1403
+ streamUrl = mainMeta.live_recording.recording_config.recording_params.origin_url;
1404
+ _context9.next = 58;
1405
+ return StreamGenerateOffering({
1406
+ client: this,
1407
+ libraryId: libraryId,
1408
+ objectId: objectId,
1409
+ typeAbrMaster: typeAbrMaster,
1410
+ typeLiveStream: typeLiveStream,
1411
+ streamUrl: streamUrl,
1412
+ abrProfile: abrProfile,
1413
+ aBitRate: aBitRate,
1414
+ aChannels: aChannels,
1415
+ aSampleRate: aSampleRate,
1416
+ aStreamIndex: aStreamIndex,
1417
+ aTimeBase: aTimeBase,
1418
+ aChannelLayout: aChannelLayout,
1419
+ vBitRate: vBitRate,
1420
+ vHeight: vHeight,
1421
+ vStreamIndex: vStreamIndex,
1422
+ vWidth: vWidth,
1423
+ vDisplayAspectRatio: vDisplayAspectRatio,
1424
+ vFrameRate: vFrameRate,
1425
+ vTimeBase: vTimeBase
1426
+ });
1427
+ case 58:
1428
+ console.log("Finished generating offering");
1429
+ return _context9.abrupt("return", {
1430
+ name: name,
1431
+ object_id: objectId,
1432
+ state: "initialized"
1433
+ });
1434
+ case 62:
1435
+ _context9.prev = 62;
1436
+ _context9.t0 = _context9["catch"](48);
1437
+ console.error(_context9.t0);
1438
+ case 65:
1439
+ case "end":
1440
+ return _context9.stop();
1441
+ }
1442
+ }, _callee9, this, [[48, 62]]);
1443
+ }));
1444
+ return function (_x9) {
1445
+ return _ref18.apply(this, arguments);
1446
+ };
1447
+ }();
1448
+
1449
+ /**
1450
+ * Add a content insertion entry
1451
+ *
1452
+ * @methodGroup Live Stream
1453
+ * @namedParams
1454
+ * @param {string} name - Object ID or name of the live stream object
1455
+ * @param {number} insertionTime - Time in seconds (float)
1456
+ * @param {boolean=} sinceStart - If specified, time specified will be elapsed seconds
1457
+ * since stream start, otherwise, time will be elapsed since epoch
1458
+ * @param {number=} duration - Time in seconds (float). Default: 20.0
1459
+ * @param {string} targetHash - The target content object hash (playable)
1460
+ * @param {boolean=} remove - If specified, will remove the inseration at the exact 'time' (instead of adding)
1461
+ *
1462
+ * @return {Promise<Object>} - Insertions, as well as any errors from bad insertions
1463
+ */
1464
+ exports.StreamInsertion = /*#__PURE__*/function () {
1465
+ var _ref20 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10(_ref19) {
1466
+ var name, insertionTime, _ref19$sinceStart, sinceStart, duration, targetHash, _ref19$remove, remove, offeringMeta, insertionInfo, audioAbrDuration, videoAbrDuration, objectId, libraryId, mainMeta, fabURI, edgeWriteToken, edgeMeta, recordings, sequence, streamStartTime, period, playoutConfig, insertions, res, errs, currentTime, insertionDone, newInsertion, i;
1467
+ return _regeneratorRuntime.wrap(function _callee10$(_context10) {
1468
+ while (1) switch (_context10.prev = _context10.next) {
1469
+ case 0:
1470
+ name = _ref19.name, insertionTime = _ref19.insertionTime, _ref19$sinceStart = _ref19.sinceStart, sinceStart = _ref19$sinceStart === void 0 ? false : _ref19$sinceStart, duration = _ref19.duration, targetHash = _ref19.targetHash, _ref19$remove = _ref19.remove, remove = _ref19$remove === void 0 ? false : _ref19$remove;
1471
+ _context10.next = 3;
1472
+ return this.ContentObjectMetadata({
1473
+ versionHash: targetHash,
1474
+ metadataSubtree: "/offerings/default"
1475
+ });
1476
+ case 3:
1477
+ offeringMeta = _context10.sent;
1478
+ insertionInfo = {
1479
+ duration_sec: 0 // Minimum of video and audio duration
1480
+ };
1481
+
1482
+ ["video", "audio"].forEach(function (mt) {
1483
+ var stream = offeringMeta.media_struct.streams[mt];
1484
+ insertionInfo[mt] = {
1485
+ seg_duration_sec: stream.optimum_seg_dur["float"],
1486
+ duration_sec: stream.duration["float"],
1487
+ frame_rate_rat: stream.rate
1488
+ };
1489
+ if (insertionInfo.duration_sec === 0 || stream.duration["float"] < insertionInfo.duration_sec) {
1490
+ insertionInfo.duration_sec = stream.duration["float"];
1491
+ }
1492
+ });
1493
+ audioAbrDuration = insertionInfo.audio.seg_duration_sec;
1494
+ videoAbrDuration = insertionInfo.video.seg_duration_sec;
1495
+ if (!(audioAbrDuration === 0 || videoAbrDuration === 0)) {
1496
+ _context10.next = 10;
1497
+ break;
1498
+ }
1499
+ throw new Error("Bad segment duration hash:", targetHash);
1500
+ case 10:
1501
+ if (!(duration === undefined)) {
1502
+ _context10.next = 14;
1503
+ break;
1504
+ }
1505
+ duration = insertionInfo.duration_sec; // Use full duration of the insertion
1506
+ _context10.next = 16;
1507
+ break;
1508
+ case 14:
1509
+ if (!(duration > insertionInfo.duration_sec)) {
1510
+ _context10.next = 16;
1511
+ break;
1512
+ }
1513
+ throw new Error("Bad duration - larger than insertion object duration", insertionInfo.duration_sec);
1514
+ case 16:
1515
+ objectId = name;
1516
+ _context10.next = 19;
1517
+ return this.ContentObjectLibraryId({
1518
+ objectId: objectId
1519
+ });
1520
+ case 19:
1521
+ libraryId = _context10.sent;
1522
+ _context10.next = 22;
1523
+ return this.ContentObjectMetadata({
1524
+ libraryId: libraryId,
1525
+ objectId: objectId
1526
+ });
1527
+ case 22:
1528
+ mainMeta = _context10.sent;
1529
+ fabURI = mainMeta.live_recording.fabric_config.ingress_node_api; // Support both hostname and URL ingress_node_api
1530
+ if (!fabURI.startsWith("http")) {
1531
+ // Assume https
1532
+ fabURI = "https://" + fabURI;
1533
+ }
1534
+ this.SetNodes({
1535
+ fabricURIs: [fabURI]
1536
+ });
1537
+ edgeWriteToken = mainMeta.live_recording.fabric_config.edge_write_token;
1538
+ _context10.next = 29;
1539
+ return this.ContentObjectMetadata({
1540
+ libraryId: libraryId,
1541
+ objectId: objectId,
1542
+ writeToken: edgeWriteToken
1543
+ });
1544
+ case 29:
1545
+ edgeMeta = _context10.sent;
1546
+ // Find stream start time (from the most recent recording section)
1547
+ recordings = edgeMeta.live_recording.recordings;
1548
+ sequence = 1;
1549
+ streamStartTime = 0;
1550
+ if (recordings != undefined && recordings.recording_sequence != undefined) {
1551
+ // We have at least one recording - check if still active
1552
+ sequence = recordings.recording_sequence;
1553
+ period = recordings.live_offering[sequence - 1];
1554
+ if (period.end_time_epoch_sec > 0) {
1555
+ // The last period is closed - apply insertions to the next period
1556
+ sequence++;
1557
+ } else {
1558
+ // The period is active
1559
+ streamStartTime = period.start_time_epoch_sec;
1560
+ }
1561
+ }
1562
+ if (!(streamStartTime === 0)) {
1563
+ _context10.next = 37;
1564
+ break;
1565
+ }
1566
+ if (!(sinceStart === false)) {
1567
+ _context10.next = 37;
1568
+ break;
1569
+ }
1570
+ throw new Error("Stream not running - must use 'time since start'");
1571
+ case 37:
1572
+ // Find the current period playout configuration
1573
+ if (edgeMeta.live_recording.playout_config.interleaves === undefined) {
1574
+ edgeMeta.live_recording.playout_config.interleaves = {};
1575
+ }
1576
+ if (edgeMeta.live_recording.playout_config.interleaves[sequence] === undefined) {
1577
+ edgeMeta.live_recording.playout_config.interleaves[sequence] = [];
1578
+ }
1579
+ playoutConfig = edgeMeta.live_recording.playout_config;
1580
+ insertions = playoutConfig.interleaves[sequence];
1581
+ res = {};
1582
+ if (!sinceStart) {
1583
+ insertionTime = insertionTime - streamStartTime;
1584
+ }
1585
+
1586
+ // Assume insertions are sorted by insertion time
1587
+ errs = [];
1588
+ currentTime = -1;
1589
+ insertionDone = false;
1590
+ newInsertion = {
1591
+ insertion_time: insertionTime,
1592
+ duration: duration,
1593
+ audio_abr_duration: audioAbrDuration,
1594
+ video_abr_duration: videoAbrDuration,
1595
+ playout: "/qfab/" + targetHash + "/rep/playout" // TO FIX - should be a link
1596
+ };
1597
+ i = 0;
1598
+ case 48:
1599
+ if (!(i < insertions.length)) {
1600
+ _context10.next = 63;
1601
+ break;
1602
+ }
1603
+ if (insertions[i].insertion_time <= currentTime) {
1604
+ // Bad insertion - must be later than current time
1605
+ append(errs, "Bad insertion - time:", insertions[i].insertion_time);
1606
+ }
1607
+ if (!remove) {
1608
+ _context10.next = 56;
1609
+ break;
1610
+ }
1611
+ if (!(insertions[i].insertion_time === insertionTime)) {
1612
+ _context10.next = 54;
1613
+ break;
1614
+ }
1615
+ insertions.splice(i, 1);
1616
+ return _context10.abrupt("break", 63);
1617
+ case 54:
1618
+ _context10.next = 60;
1619
+ break;
1620
+ case 56:
1621
+ if (!(insertions[i].insertion_time > insertionTime)) {
1622
+ _context10.next = 60;
1623
+ break;
1624
+ }
1625
+ if (i > 0) {
1626
+ insertions = [].concat(_toConsumableArray(insertions.splice(0, i)), [newInsertion], _toConsumableArray(insertions.splice(i)));
1627
+ } else {
1628
+ insertions = [newInsertion].concat(_toConsumableArray(insertions.splice(i)));
1629
+ }
1630
+ insertionDone = true;
1631
+ return _context10.abrupt("break", 63);
1632
+ case 60:
1633
+ i++;
1634
+ _context10.next = 48;
1635
+ break;
1636
+ case 63:
1637
+ if (!remove && !insertionDone) {
1638
+ // Add to the end of the insertions list
1639
+ console.log("Add insertion at the end");
1640
+ insertions = [].concat(_toConsumableArray(insertions), [newInsertion]);
1641
+ }
1642
+ playoutConfig.interleaves[sequence] = insertions;
1643
+
1644
+ // Store the new insertions in the write token
1645
+ _context10.next = 67;
1646
+ return this.ReplaceMetadata({
1647
+ libraryId: libraryId,
1648
+ objectId: objectId,
1649
+ writeToken: edgeWriteToken,
1650
+ metadataSubtree: "/live_recording/playout_config",
1651
+ metadata: edgeMeta.live_recording.playout_config
1652
+ });
1653
+ case 67:
1654
+ res.errors = errs;
1655
+ res.insertions = insertions;
1656
+ return _context10.abrupt("return", res);
1657
+ case 70:
1658
+ case "end":
1659
+ return _context10.stop();
1660
+ }
1661
+ }, _callee10, this);
1662
+ }));
1663
+ return function (_x10) {
1664
+ return _ref20.apply(this, arguments);
1665
+ };
1666
+ }();
1667
+
1668
+ /**
1669
+ * Configure the stream based on built-in logic and optional custom settings.
1670
+ *
1671
+ * Custom settings format:
1672
+ * {
1673
+ * "audio" {
1674
+ * "1" : { // This is the stream index
1675
+ * "tags" : "language: english",
1676
+ * "codec" : "aac",
1677
+ * "bitrate": 204000,
1678
+ * "record": true,
1679
+ * "recording_bitrate" : 192000,
1680
+ * "recording_channels" : 2,
1681
+ * "playout": bool
1682
+ * "playout_label": "English (Stereo)"
1683
+ * },
1684
+ * "3": {
1685
+ * ...
1686
+ * }
1687
+ * }
1688
+ * }
1689
+ *
1690
+ * @methodGroup Live Stream
1691
+ * @namedParams
1692
+ * @param {string} name - Object ID or name of the live stream object
1693
+ * @param {Object=} customSettings - Additional options to customize configuration settings
1694
+ * @param {Object=} probeMetadata - Metadata for the probe. If not specified, a new probe will be configured
1695
+ * @return {Promise<Object>} - The status response for the stream
1696
+ *
1697
+ */
1698
+ exports.StreamConfig = /*#__PURE__*/function () {
1699
+ var _ref22 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11(_ref21) {
1700
+ var name, _ref21$customSettings, customSettings, probeMetadata, objectId, status, libraryId, probe, mainMeta, userConfig, parsedName, hostName, streamUrl, nodes, node, endpoint, probeUrl, lc, liveRecordingConfig, e, writeToken;
1701
+ return _regeneratorRuntime.wrap(function _callee11$(_context11) {
1702
+ while (1) switch (_context11.prev = _context11.next) {
1703
+ case 0:
1704
+ name = _ref21.name, _ref21$customSettings = _ref21.customSettings, customSettings = _ref21$customSettings === void 0 ? {} : _ref21$customSettings, probeMetadata = _ref21.probeMetadata;
1705
+ objectId = name;
1706
+ status = {
1707
+ name: name
1708
+ };
1709
+ _context11.next = 5;
1710
+ return this.ContentObjectLibraryId({
1711
+ objectId: objectId
1712
+ });
1713
+ case 5:
1714
+ libraryId = _context11.sent;
1715
+ status.library_id = libraryId;
1716
+ status.object_id = objectId;
1717
+ probe = probeMetadata;
1718
+ _context11.next = 11;
1719
+ return this.ContentObjectMetadata({
1720
+ libraryId: libraryId,
1721
+ objectId: objectId
1722
+ });
1723
+ case 11:
1724
+ mainMeta = _context11.sent;
1725
+ userConfig = mainMeta.live_recording_config;
1726
+ status.user_config = userConfig;
1727
+
1728
+ // Get node URI from user config
1729
+ parsedName = userConfig.url.replace("udp://", "https://").replace("rtmp://", "https://").replace("srt://", "https://");
1730
+ hostName = new URL(parsedName).hostname;
1731
+ streamUrl = new URL(userConfig.url);
1732
+ this.Log("Retrieving nodes - matching: ".concat(hostName));
1733
+ _context11.next = 20;
1734
+ return this.SpaceNodes({
1735
+ matchEndpoint: hostName
1736
+ });
1737
+ case 20:
1738
+ nodes = _context11.sent;
1739
+ if (!(nodes.length < 1)) {
1740
+ _context11.next = 24;
1741
+ break;
1742
+ }
1743
+ status.error = "No node matching stream URL " + streamUrl.href;
1744
+ return _context11.abrupt("return", status);
1745
+ case 24:
1746
+ node = {
1747
+ endpoints: nodes[0].services.fabric_api.urls,
1748
+ id: nodes[0].id
1749
+ };
1750
+ status.node = node;
1751
+ endpoint = node.endpoints[0];
1752
+ if (probe) {
1753
+ _context11.next = 53;
1754
+ break;
1755
+ }
1756
+ this.SetNodes({
1757
+ fabricURIs: [endpoint]
1758
+ });
1759
+
1760
+ // Probe the stream
1761
+ probe = {};
1762
+ _context11.prev = 30;
1763
+ _context11.next = 33;
1764
+ return this.Rep({
1765
+ libraryId: libraryId,
1766
+ objectId: objectId,
1767
+ rep: "probe"
1768
+ });
1769
+ case 33:
1770
+ probeUrl = _context11.sent;
1771
+ _context11.t0 = this.utils;
1772
+ _context11.next = 37;
1773
+ return HttpClient.Fetch(probeUrl, {
1774
+ body: JSON.stringify({
1775
+ "filename": streamUrl.href,
1776
+ "listen": true
1777
+ }),
1778
+ method: "POST"
1779
+ });
1780
+ case 37:
1781
+ _context11.t1 = _context11.sent;
1782
+ _context11.next = 40;
1783
+ return _context11.t0.ResponseToJson.call(_context11.t0, _context11.t1);
1784
+ case 40:
1785
+ probe = _context11.sent;
1786
+ if (!probe.errors) {
1787
+ _context11.next = 43;
1788
+ break;
1789
+ }
1790
+ throw probe.errors[0];
1791
+ case 43:
1792
+ _context11.next = 52;
1793
+ break;
1794
+ case 45:
1795
+ _context11.prev = 45;
1796
+ _context11.t2 = _context11["catch"](30);
1797
+ if (!(_context11.t2.code === "ETIMEDOUT")) {
1798
+ _context11.next = 51;
1799
+ break;
1800
+ }
1801
+ throw "Stream probe time out - make sure the stream source is available";
1802
+ case 51:
1803
+ throw _context11.t2;
1804
+ case 52:
1805
+ probe.format.filename = streamUrl.href;
1806
+ case 53:
1807
+ // Create live recording config
1808
+ lc = new LiveConf(probe, node.id, endpoint, false, false, true);
1809
+ liveRecordingConfig = lc.generateLiveConf({
1810
+ customSettings: customSettings
1811
+ }); // Store live recording config into the stream object
1812
+ _context11.next = 57;
1813
+ return this.EditContentObject({
1814
+ libraryId: libraryId,
1815
+ objectId: objectId
1816
+ });
1817
+ case 57:
1818
+ e = _context11.sent;
1819
+ writeToken = e.write_token;
1820
+ _context11.next = 61;
1821
+ return this.ReplaceMetadata({
1822
+ libraryId: libraryId,
1823
+ objectId: objectId,
1824
+ writeToken: writeToken,
1825
+ metadataSubtree: "live_recording",
1826
+ metadata: liveRecordingConfig.live_recording
1827
+ });
1828
+ case 61:
1829
+ _context11.next = 63;
1830
+ return this.ReplaceMetadata({
1831
+ libraryId: libraryId,
1832
+ objectId: objectId,
1833
+ writeToken: writeToken,
1834
+ metadataSubtree: "live_recording_config/probe_info",
1835
+ metadata: probe
1836
+ });
1837
+ case 63:
1838
+ _context11.next = 65;
1839
+ return this.FinalizeContentObject({
1840
+ libraryId: libraryId,
1841
+ objectId: objectId,
1842
+ writeToken: writeToken,
1843
+ commitMessage: "Apply live stream configuration"
1844
+ });
1845
+ case 65:
1846
+ status.fin = _context11.sent;
1847
+ return _context11.abrupt("return", status);
1848
+ case 67:
1849
+ case "end":
1850
+ return _context11.stop();
1851
+ }
1852
+ }, _callee11, this, [[30, 45]]);
1853
+ }));
1854
+ return function (_x11) {
1855
+ return _ref22.apply(this, arguments);
1856
+ };
1857
+ }();
1858
+
1859
+ /**
1860
+ * List the pre-allocated URLs for a site
1861
+ *
1862
+ * @methodGroup Live Stream
1863
+ * @namedParams
1864
+ * @param {string=} siteId - ID of the live stream site object
1865
+ *
1866
+ * @return {Promise<Object>} - The list of stream URLs
1867
+ */
1868
+ exports.StreamListUrls = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
1869
+ var _this2 = this;
1870
+ var _ref24,
1871
+ siteId,
1872
+ STATUS_MAP,
1873
+ tenantContractId,
1874
+ streamMetadata,
1875
+ activeUrlMap,
1876
+ streamUrlStatus,
1877
+ streamUrls,
1878
+ _args13 = arguments;
1879
+ return _regeneratorRuntime.wrap(function _callee13$(_context13) {
1880
+ while (1) switch (_context13.prev = _context13.next) {
1881
+ case 0:
1882
+ _ref24 = _args13.length > 0 && _args13[0] !== undefined ? _args13[0] : {}, siteId = _ref24.siteId;
1883
+ _context13.prev = 1;
1884
+ STATUS_MAP = {
1885
+ UNCONFIGURED: "unconfigured",
1886
+ UNINITIALIZED: "uninitialized",
1887
+ INACTIVE: "inactive",
1888
+ STOPPED: "stopped",
1889
+ STARTING: "starting",
1890
+ RUNNING: "running",
1891
+ STALLED: "stalled"
1892
+ };
1893
+ if (siteId) {
1894
+ _context13.next = 12;
1895
+ break;
1896
+ }
1897
+ _context13.next = 6;
1898
+ return this.userProfileClient.TenantContractId();
1899
+ case 6:
1900
+ tenantContractId = _context13.sent;
1901
+ if (tenantContractId) {
1902
+ _context13.next = 9;
1903
+ break;
1904
+ }
1905
+ throw Error("No tenant contract ID configured");
1906
+ case 9:
1907
+ _context13.next = 11;
1908
+ return this.ContentObjectMetadata({
1909
+ libraryId: tenantContractId.replace("iten", "ilib"),
1910
+ objectId: tenantContractId.replace("iten", "iq__"),
1911
+ metadataSubtree: "public/sites/live_streams"
1912
+ });
1913
+ case 11:
1914
+ siteId = _context13.sent;
1915
+ case 12:
1916
+ _context13.t0 = this;
1917
+ _context13.next = 15;
1918
+ return this.ContentObjectLibraryId({
1919
+ objectId: siteId
1920
+ });
1921
+ case 15:
1922
+ _context13.t1 = _context13.sent;
1923
+ _context13.t2 = siteId;
1924
+ _context13.t3 = {
1925
+ libraryId: _context13.t1,
1926
+ objectId: _context13.t2,
1927
+ metadataSubtree: "public/asset_metadata/live_streams",
1928
+ resolveLinks: true,
1929
+ resolveIgnoreErrors: true,
1930
+ resolveIncludeSource: true
1931
+ };
1932
+ _context13.next = 20;
1933
+ return _context13.t0.ContentObjectMetadata.call(_context13.t0, _context13.t3);
1934
+ case 20:
1935
+ streamMetadata = _context13.sent;
1936
+ activeUrlMap = {};
1937
+ _context13.next = 24;
1938
+ return this.utils.LimitedMap(10, Object.keys(streamMetadata || {}), /*#__PURE__*/function () {
1939
+ var _ref25 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12(slug) {
1940
+ var stream, versionHash, objectId, libraryId, status, streamMeta, url, isActive;
1941
+ return _regeneratorRuntime.wrap(function _callee12$(_context12) {
1942
+ while (1) switch (_context12.prev = _context12.next) {
1943
+ case 0:
1944
+ stream = streamMetadata[slug];
1945
+ if (stream && stream["."] && stream["."].source) {
1946
+ versionHash = stream["."].source;
1947
+ }
1948
+ if (!versionHash) {
1949
+ _context12.next = 16;
1950
+ break;
1951
+ }
1952
+ objectId = _this2.utils.DecodeVersionHash(versionHash).objectId;
1953
+ _context12.next = 6;
1954
+ return _this2.ContentObjectLibraryId({
1955
+ objectId: objectId
1956
+ });
1957
+ case 6:
1958
+ libraryId = _context12.sent;
1959
+ _context12.next = 9;
1960
+ return _this2.StreamStatus({
1961
+ name: objectId
1962
+ });
1963
+ case 9:
1964
+ status = _context12.sent;
1965
+ _context12.next = 12;
1966
+ return _this2.ContentObjectMetadata({
1967
+ objectId: objectId,
1968
+ libraryId: libraryId,
1969
+ select: ["live_recording_config/reference_url",
1970
+ // live_recording_config/url is the old path
1971
+ "live_recording_config/url"]
1972
+ });
1973
+ case 12:
1974
+ streamMeta = _context12.sent;
1975
+ url = streamMeta.live_recording_config.reference_url || streamMeta.live_recording_config.url;
1976
+ isActive = [STATUS_MAP.STARTING, STATUS_MAP.RUNNING, STATUS_MAP.STALLED, STATUS_MAP.STOPPED].includes(status.state);
1977
+ if (url && isActive) {
1978
+ activeUrlMap[url] = true;
1979
+ }
1980
+ case 16:
1981
+ case "end":
1982
+ return _context12.stop();
1983
+ }
1984
+ }, _callee12);
1985
+ }));
1986
+ return function (_x12) {
1987
+ return _ref25.apply(this, arguments);
1988
+ };
1989
+ }());
1990
+ case 24:
1991
+ streamUrlStatus = {};
1992
+ _context13.t4 = this;
1993
+ _context13.next = 28;
1994
+ return this.ContentObjectLibraryId({
1995
+ objectId: siteId
1996
+ });
1997
+ case 28:
1998
+ _context13.t5 = _context13.sent;
1999
+ _context13.t6 = siteId;
2000
+ _context13.t7 = {
2001
+ libraryId: _context13.t5,
2002
+ objectId: _context13.t6,
2003
+ metadataSubtree: "/live_stream_urls",
2004
+ resolveLinks: true,
2005
+ resolveIgnoreErrors: true
2006
+ };
2007
+ _context13.next = 33;
2008
+ return _context13.t4.ContentObjectMetadata.call(_context13.t4, _context13.t7);
2009
+ case 33:
2010
+ streamUrls = _context13.sent;
2011
+ if (streamUrls) {
2012
+ _context13.next = 36;
2013
+ break;
2014
+ }
2015
+ throw Error("No pre-allocated URLs configured");
2016
+ case 36:
2017
+ Object.keys(streamUrls || {}).forEach(function (protocol) {
2018
+ streamUrlStatus[protocol] = streamUrls[protocol].map(function (url) {
2019
+ return {
2020
+ url: url,
2021
+ active: activeUrlMap[url] || false
2022
+ };
2023
+ });
2024
+ });
2025
+ return _context13.abrupt("return", streamUrlStatus);
2026
+ case 40:
2027
+ _context13.prev = 40;
2028
+ _context13.t8 = _context13["catch"](1);
2029
+ console.error(_context13.t8);
2030
+ case 43:
2031
+ case "end":
2032
+ return _context13.stop();
2033
+ }
2034
+ }, _callee13, this, [[1, 40]]);
2035
+ }));
2036
+
2037
+ /**
2038
+ * Copy a portion of a live stream recording into a standard VoD object using the zero-copy content fabric API
2039
+ *
2040
+ * Limitations:
2041
+ * - currently requires the target object to be pre-created and have content encryption keys (CAPS)
2042
+ * - for audio and video to be sync'd, the live stream needs to have the beginning of the desired recording period
2043
+ * - for an event stream, make sure the TTL is long enough to allow running the live-to-vod command before the beginning of the recording expires
2044
+ * - for 24/7 streams, make sure to reset the stream before the desired recording (as to create a new recording period) and have the TTL long enough
2045
+ * to allow running the live-to-vod command before the beginning of the recording expires.
2046
+ * - startTime and endTime are not currently implemented by this method
2047
+ *
2048
+ *
2049
+ * @methodGroup Live Stream
2050
+ * @namedParams
2051
+ * @param {string} name - Object ID or name of the live stream
2052
+ * @param {string} targetObjectId - Object ID of the target VOD object
2053
+ * @param {string=} eventId -
2054
+ * @param {boolean=} finalize - If enabled, target object will be finalized after copy to vod operations
2055
+ * @param {number=} recordingPeriod - Determines which recording period to copy, which are 0-based. -1 copies the current (or last) period
2056
+ *
2057
+ * @return {Promise<Object>} - The status response for the stream
2058
+ */
2059
+
2060
+ /*
2061
+ Example fabric API flow:
2062
+
2063
+ https://host-76-74-34-194.contentfabric.io/qlibs/ilib24CtWSJeVt9DiAzym8jB6THE9e7H/q/$QWT/call/media/live_to_vod/init -d @r1 -H "Authorization: Bearer $TOK"
2064
+
2065
+ {
2066
+ "live_qhash": "hq__5Zk1jSN8vNLUAXjQwMJV8F8J8ESXNvmVKkhaXySmGc1BXnJPG2FvvaXee4CXqvFHuGuU3fqLJc",
2067
+ "start_time": "",
2068
+ "end_time": "",
2069
+ "recording_period": -1,
2070
+ "streams": ["video", "audio"],
2071
+ "variant_key": "default"
2072
+ }
2073
+
2074
+ https://host-76-74-34-194.contentfabric.io/qlibs/ilib24CtWSJeVt9DiAzym8jB6THE9e7H/q/$QWT/call/media/abr_mezzanine/init -H "Authorization: Bearer $TOK" -d @r2
2075
+
2076
+ {
2077
+
2078
+ "abr_profile": { ... },
2079
+ "offering_key": "default",
2080
+ "prod_master_hash": "tqw__HSQHBt7vYxWfCMPH5yXwKTfhdPcQ4Lcs9WUMUbTtnMbTZPTLo4BfJWPMGpoy1Dpv1wWQVtUtAtAr429TnVs",
2081
+ "variant_key": "default",
2082
+ "keep_other_streams": false
2083
+ }
2084
+
2085
+ https://host-76-74-34-194.contentfabric.io/qlibs/ilib24CtWSJeVt9DiAzym8jB6THE9e7H/q/$QWT/call/media/live_to_vod/copy -d '{"variant_key":"","offering_key":""}' -H "Authorization: Bearer $TOK"
2086
+
2087
+
2088
+ https://host-76-74-34-194.contentfabric.io/qlibs/ilib24CtWSJeVt9DiAzym8jB6THE9e7H/q/$QWT/call/media/abr_mezzanine/offerings/default/finalize -d '{}' -H "Authorization: Bearer $TOK"
2089
+
2090
+ */
2091
+
2092
+ exports.StreamCopyToVod = /*#__PURE__*/function () {
2093
+ var _ref27 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee14(_ref26) {
2094
+ var name, targetObjectId, eventId, _ref26$streams, streams, _ref26$finalize, finalize, _ref26$recordingPerio, recordingPeriod, _ref26$startTime, startTime, _ref26$endTime, endTime, objectId, abrProfile, status, libraryId, targetLibraryId, kmsAddress, kmsCapId, kmsCap, liveHash, event, _yield$this$EditConte2, writeToken, abrMezInitBody, finalizeResponse;
2095
+ return _regeneratorRuntime.wrap(function _callee14$(_context14) {
2096
+ while (1) switch (_context14.prev = _context14.next) {
2097
+ case 0:
2098
+ name = _ref26.name, targetObjectId = _ref26.targetObjectId, eventId = _ref26.eventId, _ref26$streams = _ref26.streams, streams = _ref26$streams === void 0 ? null : _ref26$streams, _ref26$finalize = _ref26.finalize, finalize = _ref26$finalize === void 0 ? true : _ref26$finalize, _ref26$recordingPerio = _ref26.recordingPeriod, recordingPeriod = _ref26$recordingPerio === void 0 ? -1 : _ref26$recordingPerio, _ref26$startTime = _ref26.startTime, startTime = _ref26$startTime === void 0 ? "" : _ref26$startTime, _ref26$endTime = _ref26.endTime, endTime = _ref26$endTime === void 0 ? "" : _ref26$endTime;
2099
+ objectId = name;
2100
+ abrProfile = require("../abr_profiles/abr_profile_live_to_vod.js");
2101
+ _context14.next = 5;
2102
+ return this.StreamStatus({
2103
+ name: name
2104
+ });
2105
+ case 5:
2106
+ status = _context14.sent;
2107
+ libraryId = status.library_id;
2108
+ this.Log("Copying stream ".concat(name, " to target ").concat(targetObjectId));
2109
+ ValidateObject(targetObjectId);
2110
+ _context14.next = 11;
2111
+ return this.ContentObjectLibraryId({
2112
+ objectId: targetObjectId
2113
+ });
2114
+ case 11:
2115
+ targetLibraryId = _context14.sent;
2116
+ _context14.next = 14;
2117
+ return this.authClient.KMSAddress({
2118
+ objectId: targetObjectId
2119
+ });
2120
+ case 14:
2121
+ kmsAddress = _context14.sent;
2122
+ kmsCapId = "eluv.caps.ikms".concat(this.utils.AddressToHash(kmsAddress));
2123
+ _context14.next = 18;
2124
+ return this.ContentObjectMetadata({
2125
+ libraryId: targetLibraryId,
2126
+ objectId: targetObjectId,
2127
+ metadataSubtree: kmsCapId
2128
+ });
2129
+ case 18:
2130
+ kmsCap = _context14.sent;
2131
+ if (kmsCap) {
2132
+ _context14.next = 21;
2133
+ break;
2134
+ }
2135
+ throw Error("No content encryption key set for object ".concat(targetObjectId));
2136
+ case 21:
2137
+ _context14.prev = 21;
2138
+ status.live_object_id = objectId;
2139
+ _context14.next = 25;
2140
+ return this.LatestVersionHash({
2141
+ objectId: objectId,
2142
+ libraryId: libraryId
2143
+ });
2144
+ case 25:
2145
+ liveHash = _context14.sent;
2146
+ status.live_hash = liveHash;
2147
+ if (!eventId) {
2148
+ _context14.next = 32;
2149
+ break;
2150
+ }
2151
+ _context14.next = 30;
2152
+ return this.CueInfo({
2153
+ eventId: eventId,
2154
+ status: status
2155
+ });
2156
+ case 30:
2157
+ event = _context14.sent;
2158
+ if (event.eventStart && event.eventEnd) {
2159
+ startTime = event.eventStart;
2160
+ endTime = event.eventEnd;
2161
+ }
2162
+ case 32:
2163
+ _context14.next = 34;
2164
+ return this.EditContentObject({
2165
+ objectId: targetObjectId,
2166
+ libraryId: targetLibraryId
2167
+ });
2168
+ case 34:
2169
+ _yield$this$EditConte2 = _context14.sent;
2170
+ writeToken = _yield$this$EditConte2.writeToken;
2171
+ status.target_object_id = targetObjectId;
2172
+ status.target_library_id = targetLibraryId;
2173
+ status.target_write_token = writeToken;
2174
+ this.Log("Process live source (takes around 20 sec per hour of content)");
2175
+ _context14.next = 42;
2176
+ return this.CallBitcodeMethod({
2177
+ libraryId: targetLibraryId,
2178
+ objectId: targetObjectId,
2179
+ writeToken: writeToken,
2180
+ method: "/media/live_to_vod/init",
2181
+ body: {
2182
+ "live_qhash": liveHash,
2183
+ "start_time": startTime,
2184
+ // eg. "2023-10-03T02:09:02.00Z",
2185
+ "end_time": endTime,
2186
+ // eg. "2023-10-03T02:15:00.00Z",
2187
+ "streams": streams,
2188
+ "recording_period": recordingPeriod,
2189
+ "variant_key": "default"
2190
+ },
2191
+ constant: false,
2192
+ format: "text"
2193
+ });
2194
+ case 42:
2195
+ abrMezInitBody = {
2196
+ abr_profile: abrProfile,
2197
+ "offering_key": "default",
2198
+ "prod_master_hash": writeToken,
2199
+ "variant_key": "default",
2200
+ "keep_other_streams": false
2201
+ };
2202
+ _context14.next = 45;
2203
+ return this.CallBitcodeMethod({
2204
+ libraryId: targetLibraryId,
2205
+ objectId: targetObjectId,
2206
+ writeToken: writeToken,
2207
+ method: "/media/abr_mezzanine/init",
2208
+ body: abrMezInitBody,
2209
+ constant: false,
2210
+ format: "text"
2211
+ });
2212
+ case 45:
2213
+ _context14.prev = 45;
2214
+ _context14.next = 48;
2215
+ return this.CallBitcodeMethod({
2216
+ libraryId: targetLibraryId,
2217
+ objectId: targetObjectId,
2218
+ writeToken: writeToken,
2219
+ method: "/media/live_to_vod/copy",
2220
+ body: {},
2221
+ constant: false,
2222
+ format: "text"
2223
+ });
2224
+ case 48:
2225
+ _context14.next = 54;
2226
+ break;
2227
+ case 50:
2228
+ _context14.prev = 50;
2229
+ _context14.t0 = _context14["catch"](45);
2230
+ console.error("Unable to call /media/live_to_vod/copy", _context14.t0);
2231
+ throw _context14.t0;
2232
+ case 54:
2233
+ _context14.next = 56;
2234
+ return this.CallBitcodeMethod({
2235
+ libraryId: targetLibraryId,
2236
+ objectId: targetObjectId,
2237
+ writeToken: writeToken,
2238
+ method: "/media/abr_mezzanine/offerings/default/finalize",
2239
+ body: abrMezInitBody,
2240
+ constant: false,
2241
+ format: "text"
2242
+ });
2243
+ case 56:
2244
+ if (!finalize) {
2245
+ _context14.next = 61;
2246
+ break;
2247
+ }
2248
+ _context14.next = 59;
2249
+ return this.FinalizeContentObject({
2250
+ libraryId: targetLibraryId,
2251
+ objectId: targetObjectId,
2252
+ writeToken: writeToken,
2253
+ commitMessage: "Live Stream to VoD"
2254
+ });
2255
+ case 59:
2256
+ finalizeResponse = _context14.sent;
2257
+ status.target_hash = finalizeResponse.hash;
2258
+ case 61:
2259
+ // Clean up unnecessary status items
2260
+ delete status.playout_urls;
2261
+ delete status.lro_status_url;
2262
+ delete status.recording_period;
2263
+ delete status.recording_period_sequence;
2264
+ delete status.edge_meta_size;
2265
+ delete status.insertions;
2266
+ return _context14.abrupt("return", status);
2267
+ case 70:
2268
+ _context14.prev = 70;
2269
+ _context14.t1 = _context14["catch"](21);
2270
+ this.Log(_context14.t1, true);
2271
+ throw _context14.t1;
2272
+ case 74:
2273
+ case "end":
2274
+ return _context14.stop();
2275
+ }
2276
+ }, _callee14, this, [[21, 70], [45, 50]]);
2277
+ }));
2278
+ return function (_x13) {
2279
+ return _ref27.apply(this, arguments);
2280
+ };
2281
+ }();
2282
+
2283
+ /**
2284
+ * Remove a watermark for a live stream
2285
+ *
2286
+ * @methodGroup Live Stream
2287
+ * @namedParams
2288
+ * @param {string=} libraryId - Library ID of the live stream
2289
+ * @param {string} objectId - Object ID of the live stream
2290
+ * @param {string=} writeToken - Write token of the draft
2291
+ * @param {Array<string>} types - Specify which type of watermark to remove. Possible values:
2292
+ * - "image"
2293
+ * - "text"
2294
+ * - "forensic"
2295
+ * @param {boolean=} finalize - If enabled, target object will be finalized after removing watermark
2296
+ *
2297
+ * @return {Promise<Object>} - The finalize response
2298
+ */
2299
+ exports.StreamRemoveWatermark = /*#__PURE__*/function () {
2300
+ var _ref29 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15(_ref28) {
2301
+ var libraryId, objectId, writeToken, types, _ref28$finalize, finalize, _yield$this$EditConte3, edgeWriteToken, metadataPath, objectMetadata, finalizeResponse;
2302
+ return _regeneratorRuntime.wrap(function _callee15$(_context15) {
2303
+ while (1) switch (_context15.prev = _context15.next) {
2304
+ case 0:
2305
+ libraryId = _ref28.libraryId, objectId = _ref28.objectId, writeToken = _ref28.writeToken, types = _ref28.types, _ref28$finalize = _ref28.finalize, finalize = _ref28$finalize === void 0 ? true : _ref28$finalize;
2306
+ ValidateObject(objectId);
2307
+ if (libraryId) {
2308
+ _context15.next = 6;
2309
+ break;
2310
+ }
2311
+ _context15.next = 5;
2312
+ return this.ContentObjectLibraryId({
2313
+ objectId: objectId
2314
+ });
2315
+ case 5:
2316
+ libraryId = _context15.sent;
2317
+ case 6:
2318
+ if (writeToken) {
2319
+ _context15.next = 11;
2320
+ break;
2321
+ }
2322
+ _context15.next = 9;
2323
+ return this.EditContentObject({
2324
+ objectId: objectId,
2325
+ libraryId: libraryId
2326
+ });
2327
+ case 9:
2328
+ _yield$this$EditConte3 = _context15.sent;
2329
+ writeToken = _yield$this$EditConte3.writeToken;
2330
+ case 11:
2331
+ this.Log("Removing watermark types: ".concat(types.join(", "), " ").concat(libraryId, " ").concat(objectId));
2332
+ _context15.next = 14;
2333
+ return this.ContentObjectMetadata({
2334
+ objectId: objectId,
2335
+ libraryId: libraryId,
2336
+ metadataSubtree: "/live_recording/fabric_config/edge_write_token"
2337
+ });
2338
+ case 14:
2339
+ edgeWriteToken = _context15.sent;
2340
+ metadataPath = "live_recording/playout_config";
2341
+ _context15.next = 18;
2342
+ return this.ContentObjectMetadata({
2343
+ libraryId: libraryId,
2344
+ objectId: objectId,
2345
+ writeToken: writeToken,
2346
+ metadataSubtree: metadataPath,
2347
+ resolveLinks: false
2348
+ });
2349
+ case 18:
2350
+ objectMetadata = _context15.sent;
2351
+ if (objectMetadata) {
2352
+ _context15.next = 21;
2353
+ break;
2354
+ }
2355
+ throw Error("Stream object must be configured before removing a watermark");
2356
+ case 21:
2357
+ types.forEach(function (type) {
2358
+ if (type === "text") {
2359
+ delete objectMetadata.simple_watermark;
2360
+ } else if (type === "image") {
2361
+ delete objectMetadata.image_watermark;
2362
+ } else if (type === "forensic") {
2363
+ delete objectMetadata.forensic_watermark;
2364
+ }
2365
+ });
2366
+ _context15.next = 24;
2367
+ return this.ReplaceMetadata({
2368
+ libraryId: libraryId,
2369
+ objectId: objectId,
2370
+ writeToken: writeToken,
2371
+ metadataSubtree: metadataPath,
2372
+ metadata: objectMetadata
2373
+ });
2374
+ case 24:
2375
+ if (!edgeWriteToken) {
2376
+ _context15.next = 27;
2377
+ break;
2378
+ }
2379
+ _context15.next = 27;
2380
+ return this.ReplaceMetadata({
2381
+ libraryId: libraryId,
2382
+ objectId: objectId,
2383
+ writeToken: edgeWriteToken,
2384
+ metadataSubtree: metadataPath,
2385
+ metadata: objectMetadata
2386
+ });
2387
+ case 27:
2388
+ if (!finalize) {
2389
+ _context15.next = 32;
2390
+ break;
2391
+ }
2392
+ _context15.next = 30;
2393
+ return this.FinalizeContentObject({
2394
+ libraryId: libraryId,
2395
+ objectId: objectId,
2396
+ writeToken: writeToken,
2397
+ commitMessage: "Watermark removed"
2398
+ });
2399
+ case 30:
2400
+ finalizeResponse = _context15.sent;
2401
+ return _context15.abrupt("return", finalizeResponse);
2402
+ case 32:
2403
+ case "end":
2404
+ return _context15.stop();
2405
+ }
2406
+ }, _callee15, this);
2407
+ }));
2408
+ return function (_x14) {
2409
+ return _ref29.apply(this, arguments);
2410
+ };
2411
+ }();
2412
+
2413
+ /**
2414
+ * Create a watermark for a live stream
2415
+ *
2416
+ * @methodGroup Live Stream
2417
+ * @namedParams
2418
+ * @param {string=} libraryId - Library ID of the live stream
2419
+ * @param {string} objectId - Object ID of the live stream
2420
+ * @param {string=} writeToken - Write token of the draft
2421
+ * @param {Object} simpleWatermark - Text watermark
2422
+ * @param {Object} imageWatermark - Image watermark
2423
+ * @param {Object} forensicWatermark - Forensic watermark
2424
+ * @param {boolean=} finalize - If enabled, target object will be finalized after adding watermark
2425
+ * Watermark examples:
2426
+ *
2427
+ * Simple Watermark:
2428
+ {
2429
+ "font_color": "",
2430
+ "font_relative_height": 0,
2431
+ "shadow": false,
2432
+ "template": "",
2433
+ "timecode": "",
2434
+ "timecode_rate": 0,
2435
+ "x": "",
2436
+ "y": ""
2437
+ }
2438
+ *
2439
+ * Image watermark:
2440
+ {
2441
+ "image": "",
2442
+ "align_h": "",
2443
+ "align_v": "",
2444
+ "target_video_height": 0,
2445
+ "wm_enabled": false
2446
+ }
2447
+ *
2448
+ * Forensic watermark:
2449
+ {
2450
+ "algo": 6,
2451
+ "forensic_duration": 0,
2452
+ "forensic_start": "",
2453
+ "image_a": <path_to_image>,
2454
+ "image_b": <path_to_image>,
2455
+ "is_stub": true,
2456
+ "payload_bit_nb": 23,
2457
+ "wm_enabled": true
2458
+ }
2459
+ *
2460
+ *
2461
+ * @return {Promise<Object>} - The finalize response
2462
+ */
2463
+ exports.StreamAddWatermark = /*#__PURE__*/function () {
2464
+ var _ref31 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16(_ref30) {
2465
+ var libraryId, objectId, writeToken, simpleWatermark, imageWatermark, forensicWatermark, _ref30$finalize, finalize, _yield$this$EditConte4, edgeWriteToken, watermarkType, metadataPath, objectMetadata, watermarkArgCount, response, finalizeResponse;
2466
+ return _regeneratorRuntime.wrap(function _callee16$(_context16) {
2467
+ while (1) switch (_context16.prev = _context16.next) {
2468
+ case 0:
2469
+ libraryId = _ref30.libraryId, objectId = _ref30.objectId, writeToken = _ref30.writeToken, simpleWatermark = _ref30.simpleWatermark, imageWatermark = _ref30.imageWatermark, forensicWatermark = _ref30.forensicWatermark, _ref30$finalize = _ref30.finalize, finalize = _ref30$finalize === void 0 ? true : _ref30$finalize;
2470
+ ValidateObject(objectId);
2471
+ if (libraryId) {
2472
+ _context16.next = 6;
2473
+ break;
2474
+ }
2475
+ _context16.next = 5;
2476
+ return this.ContentObjectLibraryId({
2477
+ objectId: objectId
2478
+ });
2479
+ case 5:
2480
+ libraryId = _context16.sent;
2481
+ case 6:
2482
+ if (writeToken) {
2483
+ _context16.next = 11;
2484
+ break;
2485
+ }
2486
+ _context16.next = 9;
2487
+ return this.EditContentObject({
2488
+ objectId: objectId,
2489
+ libraryId: libraryId
2490
+ });
2491
+ case 9:
2492
+ _yield$this$EditConte4 = _context16.sent;
2493
+ writeToken = _yield$this$EditConte4.writeToken;
2494
+ case 11:
2495
+ _context16.next = 13;
2496
+ return this.ContentObjectMetadata({
2497
+ objectId: objectId,
2498
+ libraryId: libraryId,
2499
+ metadataSubtree: "/live_recording/fabric_config/edge_write_token"
2500
+ });
2501
+ case 13:
2502
+ edgeWriteToken = _context16.sent;
2503
+ watermarkType = imageWatermark ? "image" : forensicWatermark ? "forensic" : "text";
2504
+ metadataPath = "live_recording/playout_config";
2505
+ this.Log("Adding watermarking type: ".concat(watermarkType, " ").concat(libraryId, " ").concat(objectId));
2506
+ _context16.next = 19;
2507
+ return this.ContentObjectMetadata({
2508
+ libraryId: libraryId,
2509
+ objectId: objectId,
2510
+ writeToken: writeToken,
2511
+ metadataSubtree: metadataPath,
2512
+ resolveLinks: false
2513
+ });
2514
+ case 19:
2515
+ objectMetadata = _context16.sent;
2516
+ if (objectMetadata) {
2517
+ _context16.next = 22;
2518
+ break;
2519
+ }
2520
+ throw Error("Stream object must be configured before adding a watermark");
2521
+ case 22:
2522
+ watermarkArgCount = [simpleWatermark, imageWatermark, forensicWatermark].filter(function (i) {
2523
+ return !!i;
2524
+ }).length;
2525
+ console.log("watermark arg count", watermarkArgCount);
2526
+ if (!(watermarkArgCount === 0)) {
2527
+ _context16.next = 28;
2528
+ break;
2529
+ }
2530
+ throw Error("No watermark was provided");
2531
+ case 28:
2532
+ if (!(watermarkArgCount > 1)) {
2533
+ _context16.next = 30;
2534
+ break;
2535
+ }
2536
+ throw Error("Only one watermark is allowed");
2537
+ case 30:
2538
+ if (simpleWatermark) {
2539
+ objectMetadata.simple_watermark = simpleWatermark;
2540
+ } else if (imageWatermark) {
2541
+ objectMetadata.image_watermark = imageWatermark;
2542
+ } else if (forensicWatermark) {
2543
+ objectMetadata.forensic_watermark = forensicWatermark;
2544
+ }
2545
+ _context16.next = 33;
2546
+ return this.ReplaceMetadata({
2547
+ libraryId: libraryId,
2548
+ objectId: objectId,
2549
+ writeToken: writeToken,
2550
+ metadataSubtree: metadataPath,
2551
+ metadata: objectMetadata
2552
+ });
2553
+ case 33:
2554
+ if (!edgeWriteToken) {
2555
+ _context16.next = 36;
2556
+ break;
2557
+ }
2558
+ _context16.next = 36;
2559
+ return this.ReplaceMetadata({
2560
+ libraryId: libraryId,
2561
+ objectId: objectId,
2562
+ writeToken: edgeWriteToken,
2563
+ metadataSubtree: metadataPath,
2564
+ metadata: objectMetadata
2565
+ });
2566
+ case 36:
2567
+ response = {
2568
+ "imageWatermark": objectMetadata.image_watermark,
2569
+ "textWatermark": objectMetadata.simple_watermark,
2570
+ "forensicWatermark": objectMetadata.forensic_watermark
2571
+ };
2572
+ if (!finalize) {
2573
+ _context16.next = 42;
2574
+ break;
2575
+ }
2576
+ _context16.next = 40;
2577
+ return this.FinalizeContentObject({
2578
+ libraryId: libraryId,
2579
+ objectId: objectId,
2580
+ writeToken: writeToken,
2581
+ commitMessage: "Watermark set"
2582
+ });
2583
+ case 40:
2584
+ finalizeResponse = _context16.sent;
2585
+ response.hash = finalizeResponse.hash;
2586
+ case 42:
2587
+ return _context16.abrupt("return", response);
2588
+ case 43:
2589
+ case "end":
2590
+ return _context16.stop();
2591
+ }
2592
+ }, _callee16, this);
2593
+ }));
2594
+ return function (_x15) {
2595
+ return _ref31.apply(this, arguments);
2596
+ };
2597
+ }();
2598
+
2599
+ /**
2600
+ * Audit the specified live stream against several content fabric nodes
2601
+ *
2602
+ * @methodGroup Live Stream
2603
+ * @namedParams
2604
+ * @param {string=} objectId - Object ID of the live stream
2605
+ * @param {string=} versionHash - Version hash of the live stream -- if not specified, latest version is returned
2606
+ * @param {string=} salt - base64-encoded byte sequence for salting the audit hash
2607
+ * @param {Array<number>=} samples - list of percentages (0.0 - <1.0) used for sampling the content part list, up to 3
2608
+ * @param {string=} authorizationToken - Additional authorization token for this request
2609
+ *
2610
+ * @returns {Promise<Object>} - Response describing audit results
2611
+ */
2612
+ exports.AuditStream = /*#__PURE__*/function () {
2613
+ var _ref33 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17(_ref32) {
2614
+ var objectId, versionHash, salt, samples, authorizationToken;
2615
+ return _regeneratorRuntime.wrap(function _callee17$(_context17) {
2616
+ while (1) switch (_context17.prev = _context17.next) {
2617
+ case 0:
2618
+ objectId = _ref32.objectId, versionHash = _ref32.versionHash, salt = _ref32.salt, samples = _ref32.samples, authorizationToken = _ref32.authorizationToken;
2619
+ _context17.next = 3;
2620
+ return ContentObjectAudit.AuditContentObject({
2621
+ client: this,
2622
+ objectId: objectId,
2623
+ versionHash: versionHash,
2624
+ salt: salt,
2625
+ samples: samples,
2626
+ live: true,
2627
+ authorizationToken: authorizationToken
2628
+ });
2629
+ case 3:
2630
+ return _context17.abrupt("return", _context17.sent);
2631
+ case 4:
2632
+ case "end":
2633
+ return _context17.stop();
2634
+ }
2635
+ }, _callee17, this);
2636
+ }));
2637
+ return function (_x16) {
2638
+ return _ref33.apply(this, arguments);
2639
+ };
2640
+ }();