@eluvio/elv-client-js 3.1.92 → 3.1.95

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 (35) hide show
  1. package/dist/ElvClient-min.js +15 -11
  2. package/dist/ElvClient-node-min.js +17 -13
  3. package/dist/ElvFrameClient-min.js +13 -9
  4. package/dist/ElvPermissionsClient-min.js +13 -9
  5. package/dist/src/AuthorizationClient.js +2248 -1990
  6. package/dist/src/ContentObjectVerification.js +164 -173
  7. package/dist/src/Crypto.js +376 -324
  8. package/dist/src/ElvClient.js +1214 -938
  9. package/dist/src/ElvWallet.js +119 -95
  10. package/dist/src/EthClient.js +1040 -896
  11. package/dist/src/FrameClient.js +331 -300
  12. package/dist/src/HttpClient.js +153 -147
  13. package/dist/src/Id.js +1 -3
  14. package/dist/src/PermissionsClient.js +1294 -1168
  15. package/dist/src/RemoteSigner.js +260 -200
  16. package/dist/src/UserProfileClient.js +1168 -1014
  17. package/dist/src/Utils.js +382 -178
  18. package/dist/src/client/ABRPublishing.js +895 -856
  19. package/dist/src/client/AccessGroups.js +1102 -959
  20. package/dist/src/client/ContentAccess.js +3737 -3427
  21. package/dist/src/client/ContentManagement.js +2255 -2063
  22. package/dist/src/client/Contracts.js +647 -563
  23. package/dist/src/client/Files.js +1886 -1757
  24. package/dist/src/client/NFT.js +127 -158
  25. package/dist/src/client/NTP.js +478 -422
  26. package/package.json +2 -1
  27. package/src/ElvClient.js +62 -1
  28. package/src/RemoteSigner.js +22 -18
  29. package/src/Utils.js +119 -0
  30. package/src/client/ABRPublishing.js +2 -1
  31. package/src/client/NFT.js +14 -49
  32. package/testScripts/Test.js +0 -19
  33. package/testScripts/VariantABRProfile.js +45 -0
  34. package/utilities/SimpleIngest.js +245 -0
  35. package/package-lock.json +0 -12650
@@ -0,0 +1,245 @@
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 {seconds} = require("./lib/helpers");
15
+
16
+ class SimpleIngest extends Utility {
17
+ blueprint() {
18
+ return {
19
+ concerns: [Client, Finalize, LocalFile, ArgLibraryId, LRO],
20
+ options: [
21
+ ModOpt("libraryId", {demand: true, forX: "new media object"}),
22
+ NewOpt("title", {
23
+ demand: true,
24
+ descTemplate: "Title for new media object",
25
+ type: "string"
26
+ }),
27
+ NewOpt("drm", {
28
+ default: false,
29
+ descTemplate: "Use DRM for playback",
30
+ type: "boolean"
31
+ }),
32
+ ModOpt("files", {forX: "for new media object"})
33
+ ]
34
+ };
35
+ }
36
+
37
+ async body() {
38
+ const logger = this.logger;
39
+
40
+ let fileHandles = [];
41
+ const fileInfo = this.concerns.LocalFile.fileInfo(fileHandles);
42
+
43
+ // delay getting elvClient until this point so script exits faster
44
+ // if there is a validation error above
45
+ const client = await this.concerns.Client.get();
46
+
47
+ // get metadata from Library
48
+ const libInfo = await this.concerns.ArgLibraryId.libInfo();
49
+
50
+ const type = R.path(["metadata", "abr", "mez_content_type"], libInfo);
51
+ if(R.isNil(type)) throw Error("Library does not specify content type for simple ingests");
52
+
53
+ const libABRProfile = R.path(["metadata", "abr", "default_profile"], libInfo);
54
+ if(R.isNil(libABRProfile)) throw Error("Library does not specify ABR profile for simple ingests");
55
+
56
+ const {drm, libraryId, title} = this.args;
57
+ const encrypt = true;
58
+
59
+ logger.log("Uploading files...");
60
+
61
+ const createMasterResponse = await client.CreateProductionMaster({
62
+ libraryId,
63
+ type,
64
+ name: title,
65
+ description: `Media object created via simple ingest: ${title}`,
66
+ fileInfo,
67
+ encrypt,
68
+ copy: true,
69
+ callback: this.concerns.LocalFile.callback
70
+ });
71
+
72
+ const {id, hash} = createMasterResponse;
73
+ // Log object id immediately, in case of error later in script
74
+ // Don't log hash yet, it will change if --streams was provided (or any other revision to object is needed)
75
+ logger.data("object_id", id);
76
+
77
+ // Close file handles (if any)
78
+ this.concerns.LocalFile.closeFileHandles(fileHandles);
79
+
80
+ logger.errorsAndWarnings(createMasterResponse);
81
+
82
+ logger.logList(
83
+ "",
84
+ "Production master default variant created:",
85
+ ` Object ID: ${id}`,
86
+ ` Version Hash: ${hash}`,
87
+ ""
88
+ );
89
+
90
+ logger.data("version_hash", hash);
91
+
92
+ if(!R.isNil(createMasterResponse.errors) && !R.isEmpty(createMasterResponse.errors)) throw Error(`Error(s) encountered while inspecting uploaded files: ${createMasterResponse.errors.join("\n")}`);
93
+
94
+ await seconds(2);
95
+
96
+ await this.concerns.Finalize.waitForPublish({
97
+ latestHash: hash,
98
+ libraryId,
99
+ objectId: id
100
+ });
101
+
102
+
103
+ // get production master metadata
104
+ const masterMetadata = (await client.ContentObjectMetadata({
105
+ libraryId,
106
+ objectId: id,
107
+ versionHash: hash,
108
+ metadataSubtree: "/production_master"
109
+ }));
110
+
111
+ const sources = R.prop("sources", masterMetadata);
112
+ const variant = R.path(["variants", "default"], masterMetadata);
113
+
114
+ // add info on source files and variant to data if --json selected
115
+ if(this.args.json) {
116
+ logger.data("media_files", sources);
117
+ logger.data("variant_default", variant);
118
+ }
119
+
120
+ // generate ABR profile
121
+ const genProfileRetVal = ABR.ABRProfileForVariant(sources, variant, libABRProfile);
122
+ if(!genProfileRetVal.ok) throw Error(`Error(s) encountered while generating ABR profile: ${genProfileRetVal.errors.join("\n")}`);
123
+
124
+ // filter DRM/clear as needed
125
+ const filterProfileRetVal = drm ?
126
+ ABR.ProfileExcludeClear(genProfileRetVal.result) :
127
+ ABR.ProfileExcludeDRM(genProfileRetVal.result);
128
+ if(!filterProfileRetVal.ok) throw Error(`Error(s) encountered while setting playout formats: ${filterProfileRetVal.errors.join("\n")}`);
129
+
130
+ // set up mezzanine offering
131
+ logger.log("Setting up media file conversion...");
132
+ const createMezResponse = await client.CreateABRMezzanine({
133
+ name: title,
134
+ libraryId,
135
+ objectId: id,
136
+ type,
137
+ masterVersionHash: hash,
138
+ variant: "default",
139
+ offeringKey: "default",
140
+ abrProfile: filterProfileRetVal.result
141
+ });
142
+
143
+ logger.errorsAndWarnings(createMezResponse);
144
+ const createMezErrors = createMezResponse.errors;
145
+ if(!R.isNil(createMezErrors) && !R.isEmpty(createMezErrors)) throw Error(`Error(s) encountered while setting up media file conversion: ${createMezErrors.join("\n")}`);
146
+
147
+ await this.concerns.Finalize.waitForPublish({
148
+ latestHash: createMezResponse.hash,
149
+ libraryId,
150
+ objectId: id
151
+ });
152
+
153
+
154
+ logger.log("Starting conversion to streaming format...");
155
+
156
+ const startJobsResponse = await client.StartABRMezzanineJobs({
157
+ libraryId,
158
+ objectId: id,
159
+ offeringKey: "default"
160
+ });
161
+
162
+ logger.errorsAndWarnings(startJobsResponse);
163
+ const startJobsErrors = createMezResponse.errors;
164
+ if(!R.isNil(startJobsErrors) && !R.isEmpty(startJobsErrors)) throw Error(`Error(s) encountered while starting file conversion: ${startJobsErrors.join("\n")}`);
165
+
166
+ const lroWriteToken = R.path(["lro_draft", "write_token"], startJobsResponse);
167
+ const lroNode = R.path(["lro_draft", "node"], startJobsResponse);
168
+
169
+ logger.data("library_id", libraryId);
170
+ logger.data("object_id", id);
171
+ logger.data("offering_key", "default");
172
+ logger.data("write_token", lroWriteToken);
173
+ logger.data("write_node", lroNode);
174
+
175
+ logger.logList(
176
+ "",
177
+ `Library ID: ${libraryId}`,
178
+ `Object ID: ${id}`,
179
+ "Offering: default",
180
+ `Write Token: ${lroWriteToken}`,
181
+ `Write Node: ${lroNode}`,
182
+ ""
183
+ );
184
+
185
+ // wait for latest version hash to become visible (if publish not finished, then checking progress can fail
186
+ // as metadata /lro_draft_default will not be found)
187
+
188
+ await this.concerns.Finalize.waitForPublish({
189
+ latestHash: startJobsResponse.hash,
190
+ libraryId,
191
+ objectId: id
192
+ });
193
+
194
+ logger.log("Progress:");
195
+
196
+ const lro = this.concerns.LRO;
197
+ let done = false;
198
+ let lastStatus;
199
+ while(!done) {
200
+ const statusMap = await lro.status({libraryId, objectId: id}); // TODO: check how offering key is used, if at all
201
+ const statusSummary = lro.statusSummary(statusMap);
202
+ lastStatus = statusSummary.run_state;
203
+ if(lastStatus !== LRO.STATE_RUNNING) done = true;
204
+ logger.log(`run_state: ${lastStatus}`);
205
+ const eta = statusSummary.estimated_time_left_h_m_s;
206
+ if(eta) logger.log(`estimated time left: ${eta}`);
207
+ await seconds(15);
208
+ }
209
+
210
+ const finalizeAbrResponse = await client.FinalizeABRMezzanine({
211
+ libraryId,
212
+ objectId: id,
213
+ offeringKey: "default"
214
+ });
215
+ const latestHash = finalizeAbrResponse.hash;
216
+
217
+ logger.errorsAndWarnings(finalizeAbrResponse);
218
+ const finalizeErrors = finalizeAbrResponse.errors;
219
+ if(!R.isNil(finalizeErrors) && !R.isEmpty(finalizeErrors)) throw Error(`Error(s) encountered while finalizing object: ${finalizeErrors.join("\n")}`);
220
+
221
+ logger.logList(
222
+ "",
223
+ "Playable media object created:",
224
+ ` Object ID: ${id}`,
225
+ ` Version Hash: ${latestHash}`,
226
+ ""
227
+ );
228
+ logger.data("version_hash", latestHash);
229
+ await this.concerns.Finalize.waitForPublish({
230
+ latestHash,
231
+ libraryId,
232
+ objectId: id
233
+ });
234
+ }
235
+
236
+ header() {
237
+ return "Create playable media object via simple ingest";
238
+ }
239
+ }
240
+
241
+ if(require.main === module) {
242
+ Utility.cmdLineInvoke(SimpleIngest);
243
+ } else {
244
+ module.exports = SimpleIngest;
245
+ }