@eluvio/elv-client-js 4.0.135 → 4.0.137
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 +2 -2
- package/src/ElvClient.js +67 -3
- package/src/FrameClient.js +2 -1
- package/src/client/ABRPublishing.js +215 -83
- package/src/client/ContentManagement.js +7 -6
- package/src/client/LiveConf.js +13 -9
- package/src/client/LiveStream.js +8 -3
- package/src/walletClient/index.js +10 -6
- package/utilities/FrontEndSimpleIngest.js +198 -0
- package/utilities/ProductionMasterCreate.js +9 -2
- package/utilities/SampleIngest.js +225 -0
- package/utilities/SampleIngestWithMaster.js +226 -0
- package/utilities/lib/concerns/ArgLibraryId.js +1 -1
- package/utilities/lib/concerns/ArgTenant.js +23 -0
- package/utilities/lib/concerns/ContentType.js +1 -1
- package/utilities/lib/concerns/Finalize.js +12 -7
- package/utilities/lib/concerns/LRO.js +3 -3
- package/utilities/lib/concerns/Tenant.js +47 -0
|
@@ -186,12 +186,19 @@ class ElvWalletClient {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
try {
|
|
189
|
-
walletClient.
|
|
189
|
+
walletClient.topLevelInfoPromise = client.utils.ResponseToJson(
|
|
190
190
|
client.MakeAuthServiceRequest({
|
|
191
191
|
path: "/as/mw/toplevel",
|
|
192
192
|
queryParams: {env: mode}
|
|
193
193
|
})
|
|
194
|
-
)
|
|
194
|
+
)
|
|
195
|
+
.then(info => {
|
|
196
|
+
walletClient.topLevelInfo = info;
|
|
197
|
+
|
|
198
|
+
if(!skipMarketplaceLoad) {
|
|
199
|
+
walletClient.LoadAvailableMarketplaces();
|
|
200
|
+
}
|
|
201
|
+
});
|
|
195
202
|
} catch(error) {
|
|
196
203
|
// eslint-disable-next-line no-console
|
|
197
204
|
console.error("Unable to load top level info:");
|
|
@@ -199,10 +206,6 @@ class ElvWalletClient {
|
|
|
199
206
|
console.error(error);
|
|
200
207
|
}
|
|
201
208
|
|
|
202
|
-
if(!skipMarketplaceLoad) {
|
|
203
|
-
await walletClient.LoadAvailableMarketplaces();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
209
|
return walletClient;
|
|
207
210
|
}
|
|
208
211
|
|
|
@@ -823,6 +826,7 @@ class ElvWalletClient {
|
|
|
823
826
|
}
|
|
824
827
|
|
|
825
828
|
async LoadMarketplace(marketplaceParams) {
|
|
829
|
+
await this.topLevelInfoPromise;
|
|
826
830
|
const marketplaceInfo = this.MarketplaceInfo({marketplaceParams});
|
|
827
831
|
|
|
828
832
|
const marketplaceId = marketplaceInfo.marketplaceId;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
const { ElvClient } = require("../../src/ElvClient");
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// Simple Media Ingest
|
|
7
|
+
// This script allows for the upload of a single media file from a Front End client with an authorization token
|
|
8
|
+
// It creates a single playable object for each media file uploaded
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const MediaUpload = async () => {
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
// BACK END
|
|
16
|
+
//
|
|
17
|
+
|
|
18
|
+
let backendClient = await ElvClient.FromNetworkName({networkName: "demov3"});
|
|
19
|
+
let wallet = backendClient.GenerateWallet();
|
|
20
|
+
let backendSigner = wallet.AddAccount({
|
|
21
|
+
privateKey: process.env.PRIVATE_KEY
|
|
22
|
+
});
|
|
23
|
+
backendClient.SetSigner({signer: backendSigner});
|
|
24
|
+
// Send these 3 items to the front end: writeToken, authToken, node
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// Constants from tenancy
|
|
29
|
+
const libraryId = "ilibxxxx;
|
|
30
|
+
const mezzType = "iq__xxxx";
|
|
31
|
+
const masterType = "iq__xxx";
|
|
32
|
+
const objectName = "Object Name";
|
|
33
|
+
const filePath = path.resolve(__dirname, 'abr_profile.json');
|
|
34
|
+
const abrProfile = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// Upload by creating a new object
|
|
39
|
+
const newObject = await backendClient.CreateContentObject({
|
|
40
|
+
libraryId,
|
|
41
|
+
options: {
|
|
42
|
+
meta: {
|
|
43
|
+
public: {
|
|
44
|
+
name: objectName,
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
type: mezzType
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
const objectId = newObject.id;
|
|
51
|
+
const writeToken = newObject.write_token;
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
// Upload to an exisiting object
|
|
57
|
+
// const objectId = "iq__2o68yG4v44LwffBuKetPXGX79K9M"
|
|
58
|
+
// const writeToken = (await backendClient.EditContentObject({libraryId, objectId})).write_token;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
// Generate auth token
|
|
64
|
+
const authToken = await backendClient.authClient.AuthorizationToken({libraryId, objectId, update: true});
|
|
65
|
+
const node = await backendClient.WriteTokenNodeUrl({writeToken});
|
|
66
|
+
console.log("Send to front end", "writeToken", writeToken, "authToken", authToken, "node", node);
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
//
|
|
72
|
+
// FRONT END
|
|
73
|
+
//
|
|
74
|
+
|
|
75
|
+
let frontendClient = await ElvClient.FromNetworkName({networkName: "demov3"});
|
|
76
|
+
frontendClient.SetNodes({fabricURIs: [node]});
|
|
77
|
+
frontendClient.SetStaticToken({token: authToken, update: true});
|
|
78
|
+
|
|
79
|
+
// Upload Files
|
|
80
|
+
const filePaths = [
|
|
81
|
+
"file/path/file_name.mp4",
|
|
82
|
+
];
|
|
83
|
+
let fileInfo = [];
|
|
84
|
+
for (let i = 0; i < filePaths.length; i ++) {
|
|
85
|
+
const fd = fs.openSync(filePaths[i]);
|
|
86
|
+
const stats = fs.statSync(filePaths[i]);
|
|
87
|
+
fileInfo.push({
|
|
88
|
+
path: `file_name.mp4`,
|
|
89
|
+
type: "file",
|
|
90
|
+
size: stats.size,
|
|
91
|
+
data: fd
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const callback = (fileUploadStatus) => {
|
|
96
|
+
console.log(fileUploadStatus);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
//
|
|
103
|
+
// BACK END
|
|
104
|
+
//
|
|
105
|
+
|
|
106
|
+
let backendClient2 = await ElvClient.FromNetworkName({networkName: "demov3"});
|
|
107
|
+
let wallet2 = backendClient.GenerateWallet();
|
|
108
|
+
let backendSigner2 = wallet2.AddAccount({
|
|
109
|
+
privateKey: process.env.PRIVATE_KEY
|
|
110
|
+
});
|
|
111
|
+
backendClient2.SetSigner({signer: backendSigner2});
|
|
112
|
+
backendClient2.SetNodes({fabricURIs: [node]});
|
|
113
|
+
|
|
114
|
+
// For debbuging purposes
|
|
115
|
+
// backendClient2.ToggleLogging(true);
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
|
|
119
|
+
// Create Production Master
|
|
120
|
+
const createMasterResponse = await backendClient2.CreateProductionMaster({
|
|
121
|
+
libraryId,
|
|
122
|
+
objectId,
|
|
123
|
+
fileInfo,
|
|
124
|
+
callback,
|
|
125
|
+
encrypt: true,
|
|
126
|
+
type: masterType,
|
|
127
|
+
name: objectName,
|
|
128
|
+
writeToken
|
|
129
|
+
})
|
|
130
|
+
console.log("Master Response", createMasterResponse);
|
|
131
|
+
|
|
132
|
+
// Create ABR Mezzanine
|
|
133
|
+
const createABRMezzResponse = await backendClient2.CreateABRMezzanine({
|
|
134
|
+
libraryId,
|
|
135
|
+
writeToken,
|
|
136
|
+
objectId,
|
|
137
|
+
type: mezzType,
|
|
138
|
+
masterWriteToken: writeToken,
|
|
139
|
+
variant: "default",
|
|
140
|
+
offeringKey: "default",
|
|
141
|
+
abrProfile
|
|
142
|
+
});
|
|
143
|
+
console.log("Create ABR Mezzanine", createABRMezzResponse);
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
// Start ABR Job
|
|
147
|
+
const startJobsResponse = await backendClient2.StartABRMezzanineJobs({
|
|
148
|
+
libraryId,
|
|
149
|
+
objectId,
|
|
150
|
+
offeringKey: "default",
|
|
151
|
+
writeToken
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const lroWriteToken = startJobsResponse.lro_draft.write_token;
|
|
155
|
+
const lroNode = startJobsResponse.lro_draft.node;
|
|
156
|
+
const lroData = startJobsResponse.data;
|
|
157
|
+
|
|
158
|
+
console.log("LRO Write Token", lroWriteToken);
|
|
159
|
+
console.log("LRO Node", lroNode);
|
|
160
|
+
console.log("LRO Data", lroData);
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
// Check ABR Job is Finished
|
|
164
|
+
let done = false;
|
|
165
|
+
while (!done) {
|
|
166
|
+
const lroStatus = await backendClient.LROStatus({ libraryId, objectId, writeToken });
|
|
167
|
+
console.log("LRO Status", lroStatus);
|
|
168
|
+
const lastStatus = lroData.every(lro => lroStatus[lro]?.run_state === "finished")
|
|
169
|
+
console.log(lastStatus);
|
|
170
|
+
if (lastStatus) done = true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
// Finalize Mezzanine Object
|
|
177
|
+
if (done) {
|
|
178
|
+
let finalizeAbrResponse = await backendClient2.FinalizeABRMezzanine({
|
|
179
|
+
libraryId,
|
|
180
|
+
objectId,
|
|
181
|
+
writeToken,
|
|
182
|
+
offeringKey: "default"
|
|
183
|
+
});
|
|
184
|
+
console.log("Finalize ABR", finalizeAbrResponse);
|
|
185
|
+
|
|
186
|
+
let finalizeContentObject = await backendClient2.FinalizeContentObject({
|
|
187
|
+
libraryId,
|
|
188
|
+
objectId,
|
|
189
|
+
writeToken,
|
|
190
|
+
});
|
|
191
|
+
console.log("Finalize Object", finalizeContentObject);
|
|
192
|
+
}
|
|
193
|
+
} catch(e) {
|
|
194
|
+
console.log("ERROR", e);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
MediaUpload();
|
|
@@ -33,6 +33,11 @@ class ProductionMasterCreate extends Utility {
|
|
|
33
33
|
NewOpt("streams", {
|
|
34
34
|
descTemplate: "JSON string (or file path if prefixed with '@') containing stream specifications for variant in new production master",
|
|
35
35
|
type: "string"
|
|
36
|
+
}),
|
|
37
|
+
NewOpt("writeToken", {
|
|
38
|
+
demand: false,
|
|
39
|
+
descTemplate: "Write token of the draft",
|
|
40
|
+
type: "string",
|
|
36
41
|
})
|
|
37
42
|
]
|
|
38
43
|
};
|
|
@@ -77,7 +82,7 @@ class ProductionMasterCreate extends Utility {
|
|
|
77
82
|
const client = await this.concerns.Client.get();
|
|
78
83
|
|
|
79
84
|
const type = await await this.concerns.ArgType.typVersionHash();
|
|
80
|
-
const {libraryId, s3Copy, s3Reference} = this.args;
|
|
85
|
+
const {libraryId, s3Copy, s3Reference, writeToken} = this.args;
|
|
81
86
|
|
|
82
87
|
|
|
83
88
|
const createResponse = await client.CreateProductionMaster({
|
|
@@ -90,7 +95,8 @@ class ProductionMasterCreate extends Utility {
|
|
|
90
95
|
encrypt: !unencrypted,
|
|
91
96
|
access,
|
|
92
97
|
copy: s3Copy && !s3Reference,
|
|
93
|
-
callback: (access ? this.concerns.CloudFile : this.concerns.LocalFile).callback
|
|
98
|
+
callback: (access ? this.concerns.CloudFile : this.concerns.LocalFile).callback,
|
|
99
|
+
writeToken
|
|
94
100
|
});
|
|
95
101
|
|
|
96
102
|
const {errors, warnings, id} = createResponse;
|
|
@@ -149,6 +155,7 @@ class ProductionMasterCreate extends Utility {
|
|
|
149
155
|
libraryId,
|
|
150
156
|
objectId: id,
|
|
151
157
|
versionHash: hash,
|
|
158
|
+
writeToken: write_token,
|
|
152
159
|
metadataSubtree: "/production_master/variants/default/streams"
|
|
153
160
|
}));
|
|
154
161
|
if(!streamsFromServer.hasOwnProperty("audio")) {
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// Create new production master from specified file(s)
|
|
2
|
+
const R = require("ramda");
|
|
3
|
+
|
|
4
|
+
const {ModOpt, NewOpt} = require("./lib/options");
|
|
5
|
+
const Utility = require("./lib/Utility");
|
|
6
|
+
|
|
7
|
+
const ABR = require("@eluvio/elv-abr-profile");
|
|
8
|
+
|
|
9
|
+
const Client = require("./lib/concerns/Client");
|
|
10
|
+
const Finalize = require("./lib/concerns/Finalize");
|
|
11
|
+
const LocalFile = require("./lib/concerns/LocalFile");
|
|
12
|
+
const LRO = require("./lib/concerns/LRO");
|
|
13
|
+
const ArgLibraryId = require("./lib/concerns/ArgLibraryId");
|
|
14
|
+
const ArgTenant = require("./lib/concerns/ArgTenant");
|
|
15
|
+
const {seconds} = require("./lib/helpers");
|
|
16
|
+
const AbrProfile = require("./lib/abr_profiles/abr_profile_clear.json");
|
|
17
|
+
|
|
18
|
+
class SampleIngest extends Utility {
|
|
19
|
+
blueprint() {
|
|
20
|
+
return {
|
|
21
|
+
concerns: [Client, Finalize, LocalFile, ArgLibraryId, ArgTenant, LRO],
|
|
22
|
+
options: [
|
|
23
|
+
ModOpt("libraryId", {demand: true, forX: "new media object"}),
|
|
24
|
+
NewOpt("title", {
|
|
25
|
+
demand: true,
|
|
26
|
+
descTemplate: "Title for new media object",
|
|
27
|
+
type: "string"
|
|
28
|
+
}),
|
|
29
|
+
NewOpt("drm", {
|
|
30
|
+
default: false,
|
|
31
|
+
descTemplate: "Use DRM for playback",
|
|
32
|
+
type: "boolean"
|
|
33
|
+
}),
|
|
34
|
+
ModOpt("files", {forX: "for new media object"})
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async body() {
|
|
40
|
+
const logger = this.logger;
|
|
41
|
+
|
|
42
|
+
let fileHandles = [];
|
|
43
|
+
const fileInfo = this.concerns.LocalFile.fileInfo(fileHandles);
|
|
44
|
+
|
|
45
|
+
// delay getting elvClient until this point so script exits faster
|
|
46
|
+
// if there is a validation error above
|
|
47
|
+
const client = await this.concerns.Client.get();
|
|
48
|
+
|
|
49
|
+
// get type from Tenant
|
|
50
|
+
const tenantInfo = await this.concerns.ArgTenant.tenantInfo();
|
|
51
|
+
|
|
52
|
+
const type = tenantInfo.typeTitle;
|
|
53
|
+
|
|
54
|
+
if(R.isNil(type)) throw Error("Library does not specify content type for sample ingests");
|
|
55
|
+
|
|
56
|
+
const {drm, libraryId, title} = this.args;
|
|
57
|
+
const encrypt = true;
|
|
58
|
+
|
|
59
|
+
const {id, writeToken} = await client.CreateContentObject({
|
|
60
|
+
libraryId,
|
|
61
|
+
options: type ? { type } : {}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
logger.log("Uploading files...");
|
|
65
|
+
|
|
66
|
+
const createMasterResponse = await client.CreateProductionMaster({
|
|
67
|
+
libraryId,
|
|
68
|
+
type,
|
|
69
|
+
name: title,
|
|
70
|
+
description: `Media object created via sample ingest: ${title}`,
|
|
71
|
+
fileInfo,
|
|
72
|
+
encrypt,
|
|
73
|
+
copy: true,
|
|
74
|
+
callback: this.concerns.LocalFile.callback,
|
|
75
|
+
writeToken
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Log object id immediately, in case of error later in script
|
|
79
|
+
// Don't log hash yet, it will change if --streams was provided (or any other revision to object is needed)
|
|
80
|
+
logger.data("object_id", id);
|
|
81
|
+
|
|
82
|
+
// Close file handles (if any)
|
|
83
|
+
this.concerns.LocalFile.closeFileHandles(fileHandles);
|
|
84
|
+
|
|
85
|
+
logger.errorsAndWarnings(createMasterResponse);
|
|
86
|
+
|
|
87
|
+
logger.logList(
|
|
88
|
+
"",
|
|
89
|
+
"Production master default variant created:",
|
|
90
|
+
` Object ID: ${id}`,
|
|
91
|
+
` Write token: ${writeToken}`,
|
|
92
|
+
""
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
if(!R.isNil(createMasterResponse.errors) && !R.isEmpty(createMasterResponse.errors)) throw Error(`Error(s) encountered while inspecting uploaded files: ${createMasterResponse.errors.join("\n")}`);
|
|
96
|
+
|
|
97
|
+
// get production master metadata
|
|
98
|
+
const masterMetadata = (await client.ContentObjectMetadata({
|
|
99
|
+
libraryId,
|
|
100
|
+
objectId: id,
|
|
101
|
+
writeToken,
|
|
102
|
+
metadataSubtree: "/production_master"
|
|
103
|
+
}));
|
|
104
|
+
|
|
105
|
+
const sources = R.prop("sources", masterMetadata);
|
|
106
|
+
const variant = R.path(["variants", "default"], masterMetadata);
|
|
107
|
+
|
|
108
|
+
// add info on source files and variant to data if --json selected
|
|
109
|
+
if(this.args.json) {
|
|
110
|
+
logger.data("media_files", sources);
|
|
111
|
+
logger.data("variant_default", variant);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// generate ABR profile
|
|
115
|
+
const genProfileRetVal = ABR.ABRProfileForVariant(sources, variant, AbrProfile);
|
|
116
|
+
if(!genProfileRetVal.ok) throw Error(`Error(s) encountered while generating ABR profile: ${genProfileRetVal.errors.join("\n")}`);
|
|
117
|
+
|
|
118
|
+
// filter DRM/clear as needed
|
|
119
|
+
const filterProfileRetVal = drm ?
|
|
120
|
+
ABR.ProfileExcludeClear(genProfileRetVal.result) :
|
|
121
|
+
ABR.ProfileExcludeDRM(genProfileRetVal.result);
|
|
122
|
+
if(!filterProfileRetVal.ok) throw Error(`Error(s) encountered while setting playout formats: ${filterProfileRetVal.errors.join("\n")}`);
|
|
123
|
+
|
|
124
|
+
// set up mezzanine offering
|
|
125
|
+
logger.log("Setting up media file conversion...");
|
|
126
|
+
const createMezResponse = await client.CreateABRMezzanine({
|
|
127
|
+
name: title,
|
|
128
|
+
libraryId,
|
|
129
|
+
writeToken,
|
|
130
|
+
type,
|
|
131
|
+
masterWriteToken: writeToken,
|
|
132
|
+
variant: "default",
|
|
133
|
+
offeringKey: "default",
|
|
134
|
+
abrProfile: filterProfileRetVal.result
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
logger.errorsAndWarnings(createMezResponse);
|
|
138
|
+
const createMezErrors = createMezResponse.errors;
|
|
139
|
+
if(!R.isNil(createMezErrors) && !R.isEmpty(createMezErrors)) throw Error(`Error(s) encountered while setting up media file conversion: ${createMezErrors.join("\n")}`);
|
|
140
|
+
|
|
141
|
+
logger.log("Starting conversion to streaming format...");
|
|
142
|
+
|
|
143
|
+
const startJobsResponse = await client.StartABRMezzanineJobs({
|
|
144
|
+
libraryId,
|
|
145
|
+
objectId: id,
|
|
146
|
+
offeringKey: "default",
|
|
147
|
+
writeToken
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
logger.errorsAndWarnings(startJobsResponse);
|
|
151
|
+
const startJobsErrors = createMezResponse.errors;
|
|
152
|
+
if(!R.isNil(startJobsErrors) && !R.isEmpty(startJobsErrors)) throw Error(`Error(s) encountered while starting file conversion: ${startJobsErrors.join("\n")}`);
|
|
153
|
+
|
|
154
|
+
const lroWriteToken = R.path(["lro_draft", "write_token"], startJobsResponse);
|
|
155
|
+
const lroNode = R.path(["lro_draft", "node"], startJobsResponse);
|
|
156
|
+
|
|
157
|
+
logger.data("library_id", libraryId);
|
|
158
|
+
logger.data("object_id", id);
|
|
159
|
+
logger.data("offering_key", "default");
|
|
160
|
+
logger.data("write_token", lroWriteToken);
|
|
161
|
+
logger.data("write_node", lroNode);
|
|
162
|
+
|
|
163
|
+
logger.logList(
|
|
164
|
+
"",
|
|
165
|
+
`Library ID: ${libraryId}`,
|
|
166
|
+
`Object ID: ${id}`,
|
|
167
|
+
"Offering: default",
|
|
168
|
+
`Write Token: ${lroWriteToken}`,
|
|
169
|
+
`Write Node: ${lroNode}`,
|
|
170
|
+
""
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
logger.log("Progress:");
|
|
174
|
+
|
|
175
|
+
const lro = this.concerns.LRO;
|
|
176
|
+
let done = false;
|
|
177
|
+
let lastStatus;
|
|
178
|
+
while(!done) {
|
|
179
|
+
const statusMap = await lro.status({libraryId, objectId: id, writeToken}); // TODO: check how offering key is used, if at all
|
|
180
|
+
const statusSummary = lro.statusSummary(statusMap);
|
|
181
|
+
lastStatus = statusSummary.run_state;
|
|
182
|
+
if(lastStatus !== LRO.STATE_RUNNING) done = true;
|
|
183
|
+
logger.log(`run_state: ${lastStatus}`);
|
|
184
|
+
const eta = statusSummary.estimated_time_left_h_m_s;
|
|
185
|
+
if(eta) logger.log(`estimated time left: ${eta}`);
|
|
186
|
+
await seconds(15);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const finalizeAbrResponse = await client.FinalizeABRMezzanine({
|
|
190
|
+
libraryId,
|
|
191
|
+
objectId: id,
|
|
192
|
+
writeToken,
|
|
193
|
+
offeringKey: "default"
|
|
194
|
+
});
|
|
195
|
+
const latestHash = finalizeAbrResponse.hash;
|
|
196
|
+
|
|
197
|
+
logger.errorsAndWarnings(finalizeAbrResponse);
|
|
198
|
+
const finalizeErrors = finalizeAbrResponse.errors;
|
|
199
|
+
if(!R.isNil(finalizeErrors) && !R.isEmpty(finalizeErrors)) throw Error(`Error(s) encountered while finalizing object: ${finalizeErrors.join("\n")}`);
|
|
200
|
+
|
|
201
|
+
logger.logList(
|
|
202
|
+
"",
|
|
203
|
+
"Playable media object created:",
|
|
204
|
+
` Object ID: ${id}`,
|
|
205
|
+
` Version Hash: ${latestHash}`,
|
|
206
|
+
""
|
|
207
|
+
);
|
|
208
|
+
logger.data("version_hash", latestHash);
|
|
209
|
+
await this.concerns.Finalize.waitForPublish({
|
|
210
|
+
latestHash,
|
|
211
|
+
libraryId,
|
|
212
|
+
objectId: id
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
header() {
|
|
217
|
+
return "Create playable media object via sample ingest";
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if(require.main === module) {
|
|
222
|
+
Utility.cmdLineInvoke(SampleIngest);
|
|
223
|
+
} else {
|
|
224
|
+
module.exports = SampleIngest;
|
|
225
|
+
}
|