@eluvio/elv-client-js 4.2.31 → 4.2.32
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/package.json +1 -1
- package/src/FrameClient.js +1 -0
- package/src/client/LiveStream.js +111 -0
package/package.json
CHANGED
package/src/FrameClient.js
CHANGED
package/src/client/LiveStream.js
CHANGED
|
@@ -1286,6 +1286,117 @@ exports.StreamStartRecording = async function({name, start=false}) {
|
|
|
1286
1286
|
return status;
|
|
1287
1287
|
};
|
|
1288
1288
|
|
|
1289
|
+
/**
|
|
1290
|
+
* Stop the current live recording and start a new one with a new edge write token.
|
|
1291
|
+
* The main object is finalized only once.
|
|
1292
|
+
*
|
|
1293
|
+
* @methodGroup Live Stream
|
|
1294
|
+
* @namedParams
|
|
1295
|
+
* @param {string} name - Object ID or name of the live stream object
|
|
1296
|
+
*
|
|
1297
|
+
* @return {Promise<Object>} - The status response for the new recording session
|
|
1298
|
+
*/
|
|
1299
|
+
exports.StreamRestartRecording = async function({name}) {
|
|
1300
|
+
let status = await this.StreamStatus({name});
|
|
1301
|
+
const oldEdgeWriteToken = status?.edgeWriteToken;
|
|
1302
|
+
|
|
1303
|
+
if(!oldEdgeWriteToken) {
|
|
1304
|
+
throw new Error("Unable to restart stream - no active recording session");
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if(["running", "starting", "stalled"].includes(status.state)) {
|
|
1308
|
+
status = await this.StreamStartOrStopOrReset({name, op: "stop"});
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
const IsStopped = currentStatus =>
|
|
1312
|
+
currentStatus?.state === "stopped" &&
|
|
1313
|
+
!currentStatus.error &&
|
|
1314
|
+
currentStatus.edgeWriteToken === oldEdgeWriteToken;
|
|
1315
|
+
|
|
1316
|
+
if(!IsStopped(status)) {
|
|
1317
|
+
throw new Error(`Unable to restart stream - current LRO did not stop definitively (state: ${status?.state || "unknown"})`);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
const {libraryId, objectId, fabricApi} = status;
|
|
1321
|
+
if(!fabricApi) {
|
|
1322
|
+
throw new Error("Unable to restart stream - ingress node API is unavailable");
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
this.SetNodes({fabricURIs: [fabricApi]});
|
|
1326
|
+
|
|
1327
|
+
let mainWriteToken;
|
|
1328
|
+
let newEdgeWriteToken;
|
|
1329
|
+
let mainObjectFinalizeStarted = false;
|
|
1330
|
+
|
|
1331
|
+
try {
|
|
1332
|
+
({writeToken: mainWriteToken} = await this.EditContentObject({
|
|
1333
|
+
libraryId,
|
|
1334
|
+
objectId
|
|
1335
|
+
}));
|
|
1336
|
+
|
|
1337
|
+
({writeToken: newEdgeWriteToken} = await this.EditContentObject({
|
|
1338
|
+
libraryId,
|
|
1339
|
+
objectId
|
|
1340
|
+
}));
|
|
1341
|
+
|
|
1342
|
+
await this.MergeMetadata({
|
|
1343
|
+
libraryId,
|
|
1344
|
+
objectId,
|
|
1345
|
+
writeToken: mainWriteToken,
|
|
1346
|
+
metadata: {
|
|
1347
|
+
live_recording: {
|
|
1348
|
+
status: {
|
|
1349
|
+
edge_write_token: newEdgeWriteToken,
|
|
1350
|
+
state: "active"
|
|
1351
|
+
},
|
|
1352
|
+
fabric_config: {
|
|
1353
|
+
edge_write_token: newEdgeWriteToken
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
// Verify the old LRO is definitively stopped before publishing and deleting the old token.
|
|
1360
|
+
status = await this.StreamStatus({name});
|
|
1361
|
+
if(!IsStopped(status)) {
|
|
1362
|
+
throw new Error(`Unable to restart stream - current LRO stop could not be confirmed (state: ${status?.state || "unknown"})`);
|
|
1363
|
+
}
|
|
1364
|
+
mainObjectFinalizeStarted = true;
|
|
1365
|
+
const finalizeResponse = await this.FinalizeContentObject({
|
|
1366
|
+
libraryId,
|
|
1367
|
+
objectId,
|
|
1368
|
+
writeToken: mainWriteToken,
|
|
1369
|
+
commitMessage: `Restart stream with edge write token ${newEdgeWriteToken}`
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1372
|
+
try {
|
|
1373
|
+
await this.DeleteWriteToken({writeToken: oldEdgeWriteToken});
|
|
1374
|
+
} catch(error) {
|
|
1375
|
+
this.Log(`Unable to delete old edge write token ${oldEdgeWriteToken}: ${error.message}`, true);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
const restartedStatus = await this.StreamStartOrStopOrReset({name, op: "start"});
|
|
1379
|
+
return {
|
|
1380
|
+
...restartedStatus,
|
|
1381
|
+
hash: finalizeResponse.hash
|
|
1382
|
+
};
|
|
1383
|
+
} catch(error) {
|
|
1384
|
+
// Before main-object finalization begins, both new drafts are safe to discard and the old
|
|
1385
|
+
// stopped recording remains referenced by the published object.
|
|
1386
|
+
if(!mainObjectFinalizeStarted) {
|
|
1387
|
+
for(const writeToken of [newEdgeWriteToken, mainWriteToken].filter(Boolean)) {
|
|
1388
|
+
try {
|
|
1389
|
+
await this.DeleteWriteToken({writeToken});
|
|
1390
|
+
} catch(cleanupError) {
|
|
1391
|
+
this.Log(`Unable to clean up restart write token ${writeToken}: ${cleanupError.message}`, true);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
throw error;
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1289
1400
|
/**
|
|
1290
1401
|
* Start, stop or reset a stream within the current session (current edge write token)
|
|
1291
1402
|
*
|