@eluvio/elv-client-js 4.2.17 → 4.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ElvClient-min.js +1 -1
- package/dist/ElvClient-node-min.js +1 -1
- package/dist/ElvFrameClient-min.js +1 -1
- package/dist/ElvPermissionsClient-min.js +1 -1
- package/dist/ElvWalletClient-min.js +1 -1
- package/dist/ElvWalletClient-node-min.js +1 -1
- package/dist/src/AuthorizationClient.js +1 -2
- package/dist/src/ContentObjectAudit.js +1 -2
- package/dist/src/ElvClient.js +9 -8
- package/dist/src/FrameClient.js +1 -1
- package/dist/src/HttpClient.js +47 -83
- package/dist/src/abr_profiles/abr_profile_live_drm.js +10 -0
- package/dist/src/client/ContentAccess.js +85 -76
- package/dist/src/client/LiveConf.js +84 -170
- package/dist/src/client/LiveStream.js +2115 -5202
- package/package.json +1 -1
- package/src/AuthorizationClient.js +1 -6
- package/src/client/LiveConf.js +1 -0
- package/src/client/LiveStream.js +43 -22
- package/src/client/NTP.js +71 -0
- package/dist/src/ContentObjectVerification.js +0 -281
- package/dist/src/NetworkUrls.js +0 -8
- package/dist/src/live_recording_config_profiles/live_recording_config_default.js +0 -45
package/package.json
CHANGED
|
@@ -570,18 +570,13 @@ class AuthorizationClient {
|
|
|
570
570
|
const stateChannelApi = "elv_channelContentRequestContext";
|
|
571
571
|
const additionalParams = [JSON.stringify(audienceData)];
|
|
572
572
|
|
|
573
|
-
|
|
573
|
+
token = await this.MakeKMSCall({
|
|
574
574
|
objectId,
|
|
575
575
|
methodName: stateChannelApi,
|
|
576
576
|
paramTypes: ["address", "address", "uint", "uint"],
|
|
577
577
|
params: [this.client.signer.address, Utils.HashToAddress(objectId), value, Date.now()],
|
|
578
578
|
additionalParams
|
|
579
579
|
});
|
|
580
|
-
|
|
581
|
-
const signature = await this.Sign(Ethers.utils.keccak256(Ethers.utils.toUtf8Bytes(payload)));
|
|
582
|
-
const multiSig = Utils.FormatSignature(signature);
|
|
583
|
-
|
|
584
|
-
token = `${payload}.${Utils.B64(multiSig)}`;
|
|
585
580
|
}
|
|
586
581
|
|
|
587
582
|
if(!this.noCache) {
|
package/src/client/LiveConf.js
CHANGED
|
@@ -540,6 +540,7 @@ class LiveConf {
|
|
|
540
540
|
conf.live_recording.recording_config.recording_params.source_timescale = sourceTimescale;
|
|
541
541
|
break;
|
|
542
542
|
case "rtmp":
|
|
543
|
+
case "flv":
|
|
543
544
|
sourceTimescale = 16000;
|
|
544
545
|
conf.live_recording.recording_config.recording_params.source_timescale = sourceTimescale;
|
|
545
546
|
break;
|
package/src/client/LiveStream.js
CHANGED
|
@@ -2265,14 +2265,6 @@ exports.StreamApplyProfile = async function({
|
|
|
2265
2265
|
}));
|
|
2266
2266
|
}
|
|
2267
2267
|
|
|
2268
|
-
// Load the base config profile and merge with overrides
|
|
2269
|
-
const overrides = await this.ContentObjectMetadata({
|
|
2270
|
-
libraryId,
|
|
2271
|
-
objectId,
|
|
2272
|
-
writeToken: streamWriteToken,
|
|
2273
|
-
metadataSubtree: "live_recording_overrides"
|
|
2274
|
-
}) || {};
|
|
2275
|
-
|
|
2276
2268
|
const currentConfig = await this.ContentObjectMetadata({
|
|
2277
2269
|
libraryId,
|
|
2278
2270
|
objectId,
|
|
@@ -2280,8 +2272,9 @@ exports.StreamApplyProfile = async function({
|
|
|
2280
2272
|
metadataSubtree: "live_recording_config"
|
|
2281
2273
|
}) || {};
|
|
2282
2274
|
|
|
2283
|
-
//
|
|
2284
|
-
const
|
|
2275
|
+
// Only preserve stream-identity fields from the current config; all technical settings come from the new profile
|
|
2276
|
+
const preservedConfig = R.pick(["url", "name"], currentConfig);
|
|
2277
|
+
const config = R.mergeDeepRight(preservedConfig, profile);
|
|
2285
2278
|
|
|
2286
2279
|
const currentProfileName = await this.ContentObjectMetadata({
|
|
2287
2280
|
libraryId,
|
|
@@ -2299,6 +2292,34 @@ exports.StreamApplyProfile = async function({
|
|
|
2299
2292
|
liveRecordingConfig: config
|
|
2300
2293
|
});
|
|
2301
2294
|
|
|
2295
|
+
// Clear live_recording and live_recording_overrides so stale settings from the previous profile don't persist
|
|
2296
|
+
await this.ReplaceMetadata({
|
|
2297
|
+
libraryId,
|
|
2298
|
+
objectId,
|
|
2299
|
+
writeToken: streamWriteToken,
|
|
2300
|
+
metadataSubtree: "live_recording",
|
|
2301
|
+
metadata: {}
|
|
2302
|
+
});
|
|
2303
|
+
|
|
2304
|
+
await this.ReplaceMetadata({
|
|
2305
|
+
libraryId,
|
|
2306
|
+
objectId,
|
|
2307
|
+
writeToken: streamWriteToken,
|
|
2308
|
+
metadataSubtree: "live_recording_overrides",
|
|
2309
|
+
metadata: {}
|
|
2310
|
+
});
|
|
2311
|
+
|
|
2312
|
+
// If input_stream_info is available, regenerate live_recording from the new profile now
|
|
2313
|
+
if(config.input_stream_info) {
|
|
2314
|
+
await this.StreamConfig({
|
|
2315
|
+
name: objectId,
|
|
2316
|
+
liveRecordingConfig: config,
|
|
2317
|
+
inputStreamInfo: config.input_stream_info,
|
|
2318
|
+
writeToken: streamWriteToken,
|
|
2319
|
+
finalize: false
|
|
2320
|
+
});
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2302
2323
|
if(!profileSlug) {
|
|
2303
2324
|
profileSlug = slugify(profile.name);
|
|
2304
2325
|
}
|
|
@@ -2578,13 +2599,6 @@ exports.StreamConfig = async function({
|
|
|
2578
2599
|
objectId: objectId,
|
|
2579
2600
|
}
|
|
2580
2601
|
|
|
2581
|
-
const liveRecordingMeta = await this.ContentObjectMetadata({
|
|
2582
|
-
libraryId: libraryId,
|
|
2583
|
-
objectId,
|
|
2584
|
-
writeToken,
|
|
2585
|
-
metadataSubtree: "/live_recording"
|
|
2586
|
-
});
|
|
2587
|
-
|
|
2588
2602
|
let liveRecordingConfigProfile;
|
|
2589
2603
|
if(liveRecordingConfig && Object.keys(liveRecordingConfig || {}).length > 0) {
|
|
2590
2604
|
// Extract values that may have been saved during Create but aren't being repeated in the Config step
|
|
@@ -2612,6 +2626,15 @@ exports.StreamConfig = async function({
|
|
|
2612
2626
|
|
|
2613
2627
|
status.userConfig = liveRecordingConfigProfile;
|
|
2614
2628
|
|
|
2629
|
+
// If the stored probe is from a different protocol than the current URL, discard it and re-probe
|
|
2630
|
+
if(probe && !inputStreamInfo) {
|
|
2631
|
+
const urlProtocol = liveRecordingConfigProfile.url?.split(":")?.[0];
|
|
2632
|
+
const probeProtocol = (probe.format?.filename || "").split(":")?.[0];
|
|
2633
|
+
if(urlProtocol && probeProtocol && urlProtocol !== probeProtocol) {
|
|
2634
|
+
probe = null;
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2615
2638
|
const streamData = {
|
|
2616
2639
|
client: this
|
|
2617
2640
|
};
|
|
@@ -2648,7 +2671,6 @@ exports.StreamConfig = async function({
|
|
|
2648
2671
|
const liveConf = new LiveConf({
|
|
2649
2672
|
url: liveRecordingConfigProfile.url,
|
|
2650
2673
|
probeData: probe,
|
|
2651
|
-
liveRecordingMeta,
|
|
2652
2674
|
nodeId,
|
|
2653
2675
|
nodeUrl: endpoint,
|
|
2654
2676
|
includeAVSegDurations: false,
|
|
@@ -3392,9 +3414,8 @@ exports.OutputsList = async function({libraryId, objectId, includeState=true}) {
|
|
|
3392
3414
|
value.input.status = streamStatus?.state;
|
|
3393
3415
|
}
|
|
3394
3416
|
|
|
3395
|
-
value = await this.OutputsResolveSrtPullUrls({value});
|
|
3396
|
-
|
|
3397
3417
|
if(includeState) {
|
|
3418
|
+
await this.OutputsResolveSrtPullUrls({value});
|
|
3398
3419
|
try {
|
|
3399
3420
|
const nodeId = value.srt_pull?.node_ids?.[0];
|
|
3400
3421
|
const result = await this.OutputsState({outputId: key, objectId, libraryId, nodeId, includeState: true});
|
|
@@ -3464,7 +3485,7 @@ exports.OutputsListItem = async function({libraryId, objectId, outputId, include
|
|
|
3464
3485
|
value.input.status = streamStatus?.state;
|
|
3465
3486
|
}
|
|
3466
3487
|
|
|
3467
|
-
|
|
3488
|
+
await this.OutputsResolveSrtPullUrls({value});
|
|
3468
3489
|
|
|
3469
3490
|
if(includeState) {
|
|
3470
3491
|
try {
|
|
@@ -3567,7 +3588,7 @@ const RouteToOutputNode = async ({client, libraryId, objectId, outputId, nodeId}
|
|
|
3567
3588
|
const fabricUrl = nodes?.[0]?.services?.fabric_api?.urls?.[0];
|
|
3568
3589
|
if(fabricUrl) {
|
|
3569
3590
|
client.SetNodes({fabricURIs: [fabricUrl]});
|
|
3570
|
-
if(config) {
|
|
3591
|
+
if(config) { await client.OutputsResolveSrtPullUrls({value: config}); }
|
|
3571
3592
|
}
|
|
3572
3593
|
}
|
|
3573
3594
|
|
package/src/client/NTP.js
CHANGED
|
@@ -253,6 +253,51 @@ exports.DeleteNTPInstance = async function({tenantId, ntpId}) {
|
|
|
253
253
|
});
|
|
254
254
|
};
|
|
255
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Generate a report for the specified NTP instance.
|
|
258
|
+
*
|
|
259
|
+
* @methodGroup NTP Instances
|
|
260
|
+
* @namedParams
|
|
261
|
+
* @param {string} tenantId - The ID of the tenant in which this NTP instance was created
|
|
262
|
+
* @param {string} ntpId - The ID of the NTP instance
|
|
263
|
+
* @param {string} password - The code associated with the NTP instance
|
|
264
|
+
* @param {string=} email - Email address associated with the code
|
|
265
|
+
*/
|
|
266
|
+
exports.ReportNTPInstance = async function({tenantId, ntpId, password, email}) {
|
|
267
|
+
ValidatePresence("tenantId", tenantId);
|
|
268
|
+
ValidatePresence("ntpId", ntpId);
|
|
269
|
+
|
|
270
|
+
let paramsJSON = [];
|
|
271
|
+
|
|
272
|
+
if (password) {
|
|
273
|
+
paramsJSON.push(`pwd:${password}`);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (email) {
|
|
277
|
+
paramsJSON.push(`eml:${email}`);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const res = await this.authClient.MakeKMSCall({
|
|
281
|
+
tenantId,
|
|
282
|
+
methodName: "elv_updateOTPInstance",
|
|
283
|
+
params: [
|
|
284
|
+
tenantId,
|
|
285
|
+
ntpId,
|
|
286
|
+
"report",
|
|
287
|
+
JSON.stringify(paramsJSON),
|
|
288
|
+
Date.now()
|
|
289
|
+
],
|
|
290
|
+
paramTypes: [
|
|
291
|
+
"string",
|
|
292
|
+
"string",
|
|
293
|
+
"string",
|
|
294
|
+
"string",
|
|
295
|
+
"int"
|
|
296
|
+
]
|
|
297
|
+
});
|
|
298
|
+
return res || {};
|
|
299
|
+
};
|
|
300
|
+
|
|
256
301
|
/**
|
|
257
302
|
* Retrieve info for NTP instances in the specified tenant
|
|
258
303
|
*
|
|
@@ -389,6 +434,32 @@ exports.IssueSignedNTPCode = async function({tenantId, ntpId, email, maxRedempti
|
|
|
389
434
|
return result;
|
|
390
435
|
};
|
|
391
436
|
|
|
437
|
+
/**
|
|
438
|
+
* Check the status of the specified ticket/code without redeeming it.
|
|
439
|
+
*
|
|
440
|
+
* @methodGroup Tickets
|
|
441
|
+
* @namedParams
|
|
442
|
+
* @param {string} tenantId - The ID of the tenant from which the ticket was issued
|
|
443
|
+
* @param {string} ntpId - The ID of the NTP instance from which the ticket was issued
|
|
444
|
+
* @param {string} code - Access code
|
|
445
|
+
* @param {string=} email - Email address associated with the code
|
|
446
|
+
*
|
|
447
|
+
* @return {Promise<Object>} - Status information for the ticket
|
|
448
|
+
*/
|
|
449
|
+
exports.NTPStatus = async function({tenantId, ntpId, code, email}) {
|
|
450
|
+
ValidatePresence("tenantId", tenantId);
|
|
451
|
+
ValidatePresence("ntpId", ntpId);
|
|
452
|
+
ValidatePresence("code", code);
|
|
453
|
+
|
|
454
|
+
const response = await this.HttpClient.Request({
|
|
455
|
+
method: "POST",
|
|
456
|
+
path: UrlJoin("ks", "otp", "ntp", tenantId, ntpId, "status"),
|
|
457
|
+
body: {"_PASSWORD": code, "_EMAIL": email}
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
return await response.json();
|
|
461
|
+
};
|
|
462
|
+
|
|
392
463
|
/**
|
|
393
464
|
* Redeem the specified ticket/code to authorize the client. Must provide either issuer or tenantId and ntpId
|
|
394
465
|
*
|
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
var _regeneratorRuntime = require("@babel/runtime/regenerator");
|
|
2
|
-
var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
|
|
3
|
-
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
4
|
-
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
5
|
-
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
6
|
-
var CBOR = require("cbor");
|
|
7
|
-
var SJCL = require("sjcl");
|
|
8
|
-
var MultiHash = require("multihashes");
|
|
9
|
-
var DeepEqual = require("deep-equal");
|
|
10
|
-
var Utils = require("./Utils");
|
|
11
|
-
var ContentObjectVerification = {
|
|
12
|
-
VerifyContentObject: function VerifyContentObject(_ref) {
|
|
13
|
-
return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
14
|
-
var client, libraryId, objectId, versionHash, response, partHash, qpartsResponse, partVerification, qmdHash, metadataPartHash, metadataPartResponse, metadataVerification, metadata, qstructHash, structPartHash, structPartResponse, structVerification;
|
|
15
|
-
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
16
|
-
while (1) switch (_context.prev = _context.next) {
|
|
17
|
-
case 0:
|
|
18
|
-
client = _ref.client, libraryId = _ref.libraryId, objectId = _ref.objectId, versionHash = _ref.versionHash;
|
|
19
|
-
response = {
|
|
20
|
-
hash: versionHash
|
|
21
|
-
};
|
|
22
|
-
partHash = Utils.DecodeVersionHash(versionHash).partHash;
|
|
23
|
-
_context.next = 5;
|
|
24
|
-
return client.QParts({
|
|
25
|
-
libraryId: libraryId,
|
|
26
|
-
objectId: objectId,
|
|
27
|
-
partHash: partHash,
|
|
28
|
-
format: "arrayBuffer"
|
|
29
|
-
}).then(function (response) {
|
|
30
|
-
return Buffer.from(response);
|
|
31
|
-
});
|
|
32
|
-
case 5:
|
|
33
|
-
qpartsResponse = _context.sent;
|
|
34
|
-
partVerification = ContentObjectVerification._VerifyPart({
|
|
35
|
-
partHash: partHash,
|
|
36
|
-
qpartsResponse: qpartsResponse
|
|
37
|
-
});
|
|
38
|
-
if (partVerification.valid) {
|
|
39
|
-
response.qref = {
|
|
40
|
-
valid: true
|
|
41
|
-
};
|
|
42
|
-
} else {
|
|
43
|
-
response.qref = {
|
|
44
|
-
valid: false,
|
|
45
|
-
error: partVerification.error.message
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
response.qref.hash = partHash;
|
|
49
|
-
if (!response.qref.valid) {
|
|
50
|
-
_context.next = 32;
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
// Validate Metadata
|
|
54
|
-
qmdHash = partVerification.cbor.QmdHash.value;
|
|
55
|
-
metadataPartHash = "hqp_" + MultiHash.toB58String(qmdHash.slice(1, qmdHash.length));
|
|
56
|
-
_context.next = 14;
|
|
57
|
-
return client.QParts({
|
|
58
|
-
libraryId: libraryId,
|
|
59
|
-
objectId: objectId,
|
|
60
|
-
partHash: metadataPartHash,
|
|
61
|
-
format: "arrayBuffer"
|
|
62
|
-
}).then(function (response) {
|
|
63
|
-
return Buffer.from(response);
|
|
64
|
-
});
|
|
65
|
-
case 14:
|
|
66
|
-
metadataPartResponse = _context.sent;
|
|
67
|
-
metadataVerification = ContentObjectVerification._VerifyPart({
|
|
68
|
-
partHash: metadataPartHash,
|
|
69
|
-
qpartsResponse: metadataPartResponse
|
|
70
|
-
});
|
|
71
|
-
if (metadataVerification.valid) {
|
|
72
|
-
response.qmd = {
|
|
73
|
-
valid: true
|
|
74
|
-
};
|
|
75
|
-
} else {
|
|
76
|
-
response.qmd = {
|
|
77
|
-
valid: false,
|
|
78
|
-
error: metadataVerification.error.message
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
response.qmd.hash = metadataPartHash;
|
|
82
|
-
if (!(response.qmd.valid && libraryId)) {
|
|
83
|
-
_context.next = 23;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
_context.next = 21;
|
|
87
|
-
return client.ContentObjectMetadata({
|
|
88
|
-
libraryId: libraryId,
|
|
89
|
-
objectId: objectId,
|
|
90
|
-
versionHash: partHash.replace("hqp_", "hq__")
|
|
91
|
-
});
|
|
92
|
-
case 21:
|
|
93
|
-
metadata = _context.sent;
|
|
94
|
-
response.qmd.check = ContentObjectVerification._VerifyMetadata({
|
|
95
|
-
metadataCbor: metadataVerification.cbor,
|
|
96
|
-
metadata: metadata
|
|
97
|
-
});
|
|
98
|
-
case 23:
|
|
99
|
-
// Validate Qstruct
|
|
100
|
-
qstructHash = partVerification.cbor.QstructHash.value;
|
|
101
|
-
structPartHash = "hqp_" + MultiHash.toB58String(qstructHash.slice(1, qstructHash.length));
|
|
102
|
-
_context.next = 27;
|
|
103
|
-
return client.QParts({
|
|
104
|
-
libraryId: libraryId,
|
|
105
|
-
objectId: objectId,
|
|
106
|
-
partHash: structPartHash,
|
|
107
|
-
format: "arrayBuffer"
|
|
108
|
-
}).then(function (response) {
|
|
109
|
-
return Buffer.from(response);
|
|
110
|
-
});
|
|
111
|
-
case 27:
|
|
112
|
-
structPartResponse = _context.sent;
|
|
113
|
-
structVerification = ContentObjectVerification._VerifyPart({
|
|
114
|
-
partHash: structPartHash,
|
|
115
|
-
qpartsResponse: structPartResponse
|
|
116
|
-
});
|
|
117
|
-
if (structVerification.valid) {
|
|
118
|
-
response.qstruct = {
|
|
119
|
-
valid: true
|
|
120
|
-
};
|
|
121
|
-
} else {
|
|
122
|
-
response.qstruct = {
|
|
123
|
-
valid: false,
|
|
124
|
-
error: structVerification.error.message
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
response.qstruct.hash = structPartHash;
|
|
128
|
-
if (response.qstruct.valid) {
|
|
129
|
-
response.qstruct.parts = ContentObjectVerification._FormatQStruct(structVerification.cbor.Parts);
|
|
130
|
-
}
|
|
131
|
-
case 32:
|
|
132
|
-
response.valid = response.qref.valid && response.qmd.valid && response.qstruct.valid && (!response.qmd.check || response.qmd.check.valid);
|
|
133
|
-
return _context.abrupt("return", response);
|
|
134
|
-
case 34:
|
|
135
|
-
case "end":
|
|
136
|
-
return _context.stop();
|
|
137
|
-
}
|
|
138
|
-
}, _callee);
|
|
139
|
-
}))();
|
|
140
|
-
},
|
|
141
|
-
// Content verification methods //
|
|
142
|
-
_FormatQStruct: function _FormatQStruct(structParts) {
|
|
143
|
-
if (!structParts) {
|
|
144
|
-
return [];
|
|
145
|
-
}
|
|
146
|
-
return structParts.map(function (structPart) {
|
|
147
|
-
return {
|
|
148
|
-
hash: "hqp_" + MultiHash.toB58String(structPart.Hash.value.slice(1, structPart.Hash.length)),
|
|
149
|
-
size: structPart.Size
|
|
150
|
-
};
|
|
151
|
-
});
|
|
152
|
-
},
|
|
153
|
-
_Hash: function _Hash(thing) {
|
|
154
|
-
function fromBits(arr) {
|
|
155
|
-
var out = [],
|
|
156
|
-
bl = SJCL.bitArray.bitLength(arr),
|
|
157
|
-
i,
|
|
158
|
-
tmp;
|
|
159
|
-
for (i = 0; i < bl / 8; i++) {
|
|
160
|
-
if ((i & 3) === 0) {
|
|
161
|
-
tmp = arr[i / 4];
|
|
162
|
-
}
|
|
163
|
-
out.push(tmp >>> 24);
|
|
164
|
-
tmp <<= 8;
|
|
165
|
-
}
|
|
166
|
-
return out;
|
|
167
|
-
}
|
|
168
|
-
function toBits(bytes) {
|
|
169
|
-
var out = [],
|
|
170
|
-
i,
|
|
171
|
-
tmp = 0;
|
|
172
|
-
for (i = 0; i < bytes.length; i++) {
|
|
173
|
-
tmp = tmp << 8 | bytes[i];
|
|
174
|
-
if ((i & 3) === 3) {
|
|
175
|
-
out.push(tmp);
|
|
176
|
-
tmp = 0;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
if (i & 3) {
|
|
180
|
-
out.push(SJCL.bitArray.partial(8 * (i & 3), tmp));
|
|
181
|
-
}
|
|
182
|
-
return out;
|
|
183
|
-
}
|
|
184
|
-
var digest = SJCL.hash.sha256.hash(toBits(thing));
|
|
185
|
-
var bytes = fromBits(digest);
|
|
186
|
-
var out = Buffer.from(bytes, "binary");
|
|
187
|
-
return MultiHash.toB58String(MultiHash.encode(out, "sha2-256"));
|
|
188
|
-
},
|
|
189
|
-
_ParseCBOR: function _ParseCBOR(cborResponse) {
|
|
190
|
-
var buffer = cborResponse.slice(7, cborResponse.length);
|
|
191
|
-
var hex = buffer.toString("hex");
|
|
192
|
-
return CBOR.decodeFirstSync(hex);
|
|
193
|
-
},
|
|
194
|
-
_VerifyPart: function _VerifyPart(_ref2) {
|
|
195
|
-
var partHash = _ref2.partHash,
|
|
196
|
-
qpartsResponse = _ref2.qpartsResponse;
|
|
197
|
-
try {
|
|
198
|
-
if (ContentObjectVerification._Hash(qpartsResponse) !== partHash.replace("hqp_", "")) {
|
|
199
|
-
throw Error("Hashes do not match");
|
|
200
|
-
}
|
|
201
|
-
var cbor = ContentObjectVerification._ParseCBOR(qpartsResponse);
|
|
202
|
-
return {
|
|
203
|
-
valid: true,
|
|
204
|
-
cbor: cbor
|
|
205
|
-
};
|
|
206
|
-
} catch (error) {
|
|
207
|
-
return {
|
|
208
|
-
valid: false,
|
|
209
|
-
error: error
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
_VerifyMetadata: function _VerifyMetadata(_ref3) {
|
|
214
|
-
var metadataCbor = _ref3.metadataCbor,
|
|
215
|
-
metadata = _ref3.metadata;
|
|
216
|
-
if (!metadataCbor) {
|
|
217
|
-
metadataCbor = {};
|
|
218
|
-
}
|
|
219
|
-
if (!metadata) {
|
|
220
|
-
metadata = {};
|
|
221
|
-
}
|
|
222
|
-
var response = {
|
|
223
|
-
valid: true,
|
|
224
|
-
invalidValues: []
|
|
225
|
-
};
|
|
226
|
-
var cborKeys = Object.keys(metadataCbor);
|
|
227
|
-
var metadataKeys = Object.keys(metadata);
|
|
228
|
-
|
|
229
|
-
// Find any difference between top level keys
|
|
230
|
-
var differentKeys = cborKeys.filter(function (x) {
|
|
231
|
-
return !metadataKeys.includes(x);
|
|
232
|
-
}).concat(metadataKeys.filter(function (x) {
|
|
233
|
-
return !cborKeys.includes(x);
|
|
234
|
-
}));
|
|
235
|
-
var _iterator = _createForOfIteratorHelper(differentKeys),
|
|
236
|
-
_step;
|
|
237
|
-
try {
|
|
238
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
239
|
-
var key = _step.value;
|
|
240
|
-
var cborValue = metadataCbor[key];
|
|
241
|
-
var metadataValue = metadata[key];
|
|
242
|
-
response.invalidValues.push({
|
|
243
|
-
key: key,
|
|
244
|
-
cborValue: cborValue,
|
|
245
|
-
metadataValue: metadataValue
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Deep comparison of up to 5 keys
|
|
250
|
-
} catch (err) {
|
|
251
|
-
_iterator.e(err);
|
|
252
|
-
} finally {
|
|
253
|
-
_iterator.f();
|
|
254
|
-
}
|
|
255
|
-
var _iterator2 = _createForOfIteratorHelper(Object.keys(metadataCbor).slice(0, 5)),
|
|
256
|
-
_step2;
|
|
257
|
-
try {
|
|
258
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
259
|
-
var fieldToValidate = _step2.value;
|
|
260
|
-
var _cborValue = metadataCbor[fieldToValidate];
|
|
261
|
-
var _metadataValue = metadata[fieldToValidate];
|
|
262
|
-
if (!DeepEqual(_cborValue, _metadataValue)) {
|
|
263
|
-
response.invalidValues.push({
|
|
264
|
-
key: fieldToValidate,
|
|
265
|
-
cborValue: _cborValue,
|
|
266
|
-
metadataValue: _metadataValue
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
} catch (err) {
|
|
271
|
-
_iterator2.e(err);
|
|
272
|
-
} finally {
|
|
273
|
-
_iterator2.f();
|
|
274
|
-
}
|
|
275
|
-
if (response.invalidValues.length !== 0) {
|
|
276
|
-
response.valid = false;
|
|
277
|
-
}
|
|
278
|
-
return response;
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
module.exports = ContentObjectVerification;
|
package/dist/src/NetworkUrls.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
var networks = {
|
|
2
|
-
"main": "https://main.net955305.contentfabric.io",
|
|
3
|
-
"demo": "https://demov3.net955210.contentfabric.io",
|
|
4
|
-
"demov3": "https://demov3.net955210.contentfabric.io",
|
|
5
|
-
"local": "http://127.0.0.1:8008/config?qspace=dev&self",
|
|
6
|
-
"test": "https://test.net955203.contentfabric.io"
|
|
7
|
-
};
|
|
8
|
-
module.exports = networks;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
var LiveRecordingConfigDefault = {
|
|
2
|
-
drm_type: "clear",
|
|
3
|
-
recording_config: {
|
|
4
|
-
part_ttl: 86400,
|
|
5
|
-
reconnect_timeout: 3600,
|
|
6
|
-
connection_timeout: 3600,
|
|
7
|
-
copy_mpegts: false
|
|
8
|
-
},
|
|
9
|
-
profile: {
|
|
10
|
-
ladder_specs: {
|
|
11
|
-
audio: [{
|
|
12
|
-
bit_rate: 192000,
|
|
13
|
-
channels: 2,
|
|
14
|
-
codecs: "mp4a.40.2"
|
|
15
|
-
}, {
|
|
16
|
-
bit_rate: 384000,
|
|
17
|
-
channels: 6,
|
|
18
|
-
codecs: "mp4a.40.2"
|
|
19
|
-
}],
|
|
20
|
-
video: [{
|
|
21
|
-
bit_rate: 9500000,
|
|
22
|
-
codecs: "avc1.640028,mp4a.40.2",
|
|
23
|
-
height: 1080,
|
|
24
|
-
width: 1920
|
|
25
|
-
}, {
|
|
26
|
-
bit_rate: 4500000,
|
|
27
|
-
codecs: "avc1.640028,mp4a.40.2",
|
|
28
|
-
height: 720,
|
|
29
|
-
width: 1280
|
|
30
|
-
}, {
|
|
31
|
-
bit_rate: 2000000,
|
|
32
|
-
codecs: "avc1.640028,mp4a.40.2",
|
|
33
|
-
height: 540,
|
|
34
|
-
width: 960
|
|
35
|
-
}, {
|
|
36
|
-
bit_rate: 900000,
|
|
37
|
-
codecs: "avc1.640028,mp4a.40.2",
|
|
38
|
-
height: 540,
|
|
39
|
-
width: 960
|
|
40
|
-
}]
|
|
41
|
-
},
|
|
42
|
-
name: "Default"
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
module.exports = LiveRecordingConfigDefault;
|