@pixwel/pixwel-sdk 1.1.7 → 1.1.8

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/src/Ingest.js CHANGED
@@ -6,25 +6,26 @@ import _ from "lodash";
6
6
  */
7
7
  export default class Ingest {
8
8
  /**
9
- * [mapMetaToTags description]
10
- * @param {[type]} info [description]
11
- * @return {[type]} [description]
9
+ * Maps mediainfo metadata into ingest Tag format
10
+ * @param {*} info
11
+ * @param {*} mediaType
12
12
  */
13
- static mapMetaToTags(info, mediaType) {
14
-
15
- let tags = {
16
- Aspect: "",
17
- Standard: "",
18
- Resolution: "",
19
- Codec: "",
20
- "Frame Mode": "",
21
- Text: "",
22
- Usage: "",
13
+ static mapFromMediainfo(info, mediaType) {
14
+ let schema = {
15
+ Aspect: null,
16
+ Standard: null,
17
+ Resolution: null,
18
+ Codec: null,
19
+ "Frame Mode": null,
20
+ Text: null,
21
+ Usage: null,
23
22
  Extra: [],
24
- Framerate: "",
25
- Duration: ""
23
+ Framerate: null,
24
+ Duration: null
26
25
  };
27
26
 
27
+ let tags = {};
28
+
28
29
  if (!info.File) {
29
30
  throw "missing info.File";
30
31
  }
@@ -34,34 +35,34 @@ export default class Ingest {
34
35
  }
35
36
 
36
37
  let general;
37
- if (!Array.isArray(info['File']['track'])) {
38
- general = info['File']['track'];
38
+ if (!Array.isArray(info["File"]["track"])) {
39
+ general = info["File"]["track"];
39
40
  } else {
40
- general = _.find(info['File']['track'], { _type: 'General'});
41
+ general = _.find(info["File"]["track"], { _type: "General" });
41
42
  }
42
-
43
+
43
44
  switch (mediaType) {
44
- case 'video':
45
- mediaType = 'Video';
45
+ case "video":
46
+ mediaType = "Video";
46
47
  break;
47
- case 'image':
48
- mediaType = 'Image';
48
+ case "image":
49
+ mediaType = "Image";
49
50
  break;
50
51
  default:
51
- if (general.Format && general.Format == 'MXF') {
52
- tags.Usage = 'broadcast';
52
+ if (general.Format && general.Format == "MXF") {
53
+ tags.Usage = "broadcast";
53
54
  }
54
55
  return tags;
55
56
  }
56
57
 
57
58
  let mediainfoDefaults = {
58
- Display_aspect_ratio: "",
59
+ DisplayAspectRatio: "",
59
60
  Format: "",
60
61
  Standard: "",
61
62
  Height: "",
62
63
  Width: "",
63
- Frame_rate: "",
64
- Scan_type: ""
64
+ FrameRate: "",
65
+ ScanType: ""
65
66
  };
66
67
 
67
68
  let media = _.find(info["File"]["track"], {
@@ -71,21 +72,41 @@ export default class Ingest {
71
72
 
72
73
  let width = parseInt(media["Width"].replace(" ", "").match(/[0-9 ]+/));
73
74
  let height = parseInt(media["Height"].replace(" ", "").match(/[0-9 ]+/));
74
- tags.Resolution = width && height ? `${width}x${height}` : "";
75
-
76
- tags.Standard = media["Standard"] ? media["Standard"].toLowerCase() : "";
75
+ let Resolution = width && height ? `${width}x${height}` : null;
76
+ if (Resolution) {
77
+ tags.Resolution = Resolution;
78
+ }
77
79
 
78
- let scan = /Progressive/.test(media["Scan_type"]) ? "p" : "i";
79
- let dimension = /3D/.test(name) ? "3D" : "2D";
80
+ let Standard = media["Standard"] ? media["Standard"].toLowerCase() : null;
81
+ if (Standard) {
82
+ tags.Standard = Standard;
83
+ }
80
84
 
81
- let framerate = media["Frame_rate"].split(" ");
82
- if (framerate.length) {
83
- let f = framerate[0];
84
- if (f == "23.976") {
85
- f = "23.98";
86
- }
87
- f = parseFloat(f).toString();
88
- tags.Framerate = f != "NaN" ? f : "";
85
+ let framerate = media["FrameRate"];
86
+ switch (framerate) {
87
+ case "23.976":
88
+ framerate = "23.98";
89
+ break;
90
+ case "24.000":
91
+ framerate = "24";
92
+ break;
93
+ case "25.000":
94
+ framerate = "25";
95
+ break;
96
+ case "29.970":
97
+ framerate = "29.97";
98
+ break;
99
+ case "50.000":
100
+ framerate = "50";
101
+ break;
102
+ case "59.940":
103
+ framerate = "59.94";
104
+ break;
105
+ }
106
+ framerate = parseFloat(framerate).toString();
107
+ framerate = framerate != "NaN" ? framerate : null;
108
+ if (framerate) {
109
+ tags.Framerate = framerate;
89
110
  }
90
111
 
91
112
  if (!tags.Standard) {
@@ -103,16 +124,18 @@ export default class Ingest {
103
124
  }
104
125
  }
105
126
 
106
- tags.Codec = (function(codec) {
107
- switch (codec) {
108
- case "AVC":
109
- return "h264";
110
- case "ProRes":
111
- return "prores";
112
- default:
113
- return "";
114
- }
115
- })(media["Format"]);
127
+ let Codec;
128
+ switch (media["Format"]) {
129
+ case "AVC":
130
+ Codec = "h264";
131
+ break;
132
+ case "ProRes":
133
+ Codec = "prores";
134
+ break;
135
+ }
136
+ if (Codec) {
137
+ tags.Codec = Codec;
138
+ }
116
139
 
117
140
  if (tags.Codec == "h264") {
118
141
  tags.Usage = "online";
@@ -122,68 +145,195 @@ export default class Ingest {
122
145
  tags.Usage = "broadcast";
123
146
  }
124
147
 
125
- if (general && general['Format'] == 'MXF') {
126
- tags.Usage = 'broadcast';
148
+ if (general && general["Format"] == "MXF") {
149
+ tags.Usage = "broadcast";
127
150
  }
128
151
 
129
- tags.Aspect = media["Display_aspect_ratio"] || "";
130
- tags["Frame Mode"] = media["Scan_type"].toLowerCase();
131
-
132
- return tags;
133
- }
134
- static mapFromKnownData(context, order, tags, watermarks = []) {
135
-
136
- if (order.asset) {
137
- context = {
138
- asset: order.asset._id,
139
- project: order.project._id,
140
- assetType: order.assetType,
141
- purpose: "download"
142
- };
152
+ switch (media["DisplayAspectRatio"]) {
153
+ case "1.000":
154
+ tags.Aspect = "1:1";
155
+ break;
156
+ case "1.347":
157
+ tags.Aspect = "4:3";
158
+ break;
159
+ case "1.756":
160
+ tags.Aspect = "16:9";
161
+ break;
162
+ case "1.778":
163
+ tags.Aspect = "16:9";
164
+ break;
165
+ case "1.366":
166
+ tags.Aspect = "4:3";
167
+ break;
168
+ case "0.562":
169
+ tags.Aspect = "9:16";
170
+ break;
143
171
  }
144
172
 
145
- let previewType = (function() {
146
- if (order.isSub() && order.isDub()) return "both";
147
- if (order.isDub()) return "dub";
148
- if (order.isSub()) return "sub";
149
- })();
173
+ let ScanType = media["ScanType"].toLowerCase() || null;
174
+ if (ScanType) {
175
+ tags["Frame Mode"] = ScanType;
176
+ }
150
177
 
151
- let isPreviewEnabled =
152
- (tags.Codec == "prores" &&
153
- tags.Resolution.split("x")[1] == "1080" &&
154
- (tags.Framerate == "23.98" || tags.Framerate == "25") &&
155
- watermarks.length) || null;
178
+ let ingest = {
179
+ selected: {
180
+ download: {
181
+ tags: tags
182
+ }
183
+ }
184
+ };
156
185
 
157
- let watermark = watermarks[0] ? watermarks[0]._id : "";
186
+ return ingest;
187
+ }
188
+ /**
189
+ * Maps parsed filename data to a partial ingest record for later merging
190
+ * @param {*} filename
191
+ * @param {*} allTags
192
+ */
193
+ static mapFromFilename(filename, allTags) {
194
+ let tags = {
195
+ SubDub: {
196
+ sub: null,
197
+ dub: null
198
+ }
199
+ };
200
+ filename.file.tags.forEach(tag => {
201
+ let foundTag = _.find(allTags, { name: tag });
202
+ if (foundTag) {
203
+ if (foundTag.type == 'SubDub') {
204
+ if (foundTag.name == 'sub') {
205
+ tags.SubDub.sub = true;
206
+ }
207
+ if (foundTag.name == 'dub') {
208
+ tags.SubDub.dub = true;
209
+ }
210
+ } else {
211
+ tags[foundTag.type] = foundTag.name;
212
+ }
213
+ }
214
+ });
215
+ tags.Extra = filename.extra;
216
+ let ingest = {
217
+ selected: {
218
+ download: {
219
+ tags: tags
220
+ },
221
+ preview: {
222
+ }
223
+ }
224
+ };
225
+ if (filename.file.tags.includes('sub') && filename.file.tags.includes('dub')) {
226
+ ingest.selected.preview.type = 'both';
227
+ } else if (filename.file.tags.includes('sub')) {
228
+ ingest.selected.preview.type = 'sub';
229
+ } else if (filename.file.tags.includes('dub')) {
230
+ ingest.selected.preview.type = 'dub';
231
+ }
232
+ if (filename.file.language) {
233
+ ingest.selected.preview.language = filename.file.language;
234
+ ingest.selected.download.language = filename.file.language;
235
+ }
236
+ if (filename.file.country) {
237
+ ingest.selected.download.country = filename.file.country;
238
+ }
239
+ return ingest;
240
+ }
241
+ /**
242
+ * Assembles Ingest based on weighted rules
243
+ * @param {*} context
244
+ * @param {*} filename
245
+ * @param {*} mediainfo
246
+ * @param {*} order
247
+ */
248
+ static assemble(original, filename, mediainfo, order, watermarks = []) {
158
249
 
159
- return {
250
+ let defaults = {
160
251
  workRequest: order._id,
161
252
  selected: {
162
253
  download: {
163
254
  enabled: true,
164
- country: order.country,
165
- language: order.language,
166
- tags: tags,
255
+ tags: {
256
+ Extra: []
257
+ },
167
258
  embargo: {
168
259
  enabled: false
169
260
  }
170
261
  },
171
262
  preview: {
172
- enabled: isPreviewEnabled,
173
- language: order.language,
174
- revision: "Final",
175
- type: previewType,
176
- watermark: watermark,
263
+ enabled: false,
264
+ revision: 'Final',
265
+ type: 'none',
177
266
  embargo: {
178
267
  enabled: false
179
268
  }
180
269
  },
181
270
  thumbnail: {
182
- enabled: false
271
+ enabled: false,
272
+ position: 50
183
273
  }
184
- },
185
- context: context
274
+ }
186
275
  };
276
+
277
+ let ingest = _.merge(defaults, original, filename, mediainfo);
278
+
279
+ if (original.asset && original.asset.creative) {
280
+ ingest.selected.preview.revision = 'Unfinished';
281
+ }
282
+
283
+ if (!original.context.asset && filename.asset && filename.asset._id) {
284
+ ingest.selected.asset = filename.asset._id;
285
+ }
286
+
287
+ if (ingest.workRequest) {
288
+ ingest.selected.project = ingest.context.project;
289
+ ingest.selected.asset = ingest.context.asset;
290
+ ingest.selected.assetType = ingest.context.assetType;
291
+ }
292
+
293
+ if (ingest.workRequest) {
294
+ ingest.selected.download.tags.Extra = [];
295
+ }
296
+
297
+ if (original.context.tag) {
298
+ ingest.selected.download.tags.Extra = [original.context.tag];
299
+ }
300
+
301
+ if (order.territory) {
302
+ ingest.selected.download.country = order.territory;
303
+ }
304
+ if (order.language) {
305
+ ingest.selected.preview.language = order.language;
306
+ ingest.selected.download.language = order.language;
307
+ }
308
+ if (order._id) {
309
+ ingest.selected.download.tags.Text = 'txtd';
310
+ }
311
+ if (order.isSub() || order.isDub()) {
312
+ ingest.selected.download.tags.SubDub = {
313
+ sub: order.isSub(),
314
+ dub: order.isDub()
315
+ }
316
+ }
317
+ if (order.isSub()) {
318
+ ingest.selected.preview.type = "sub";
319
+ }
320
+ if (order.isDub()) {
321
+ ingest.selected.preview.type = "dub";
322
+ }
323
+ if (order.isSub() && order.isDub()) {
324
+ ingest.selected.preview.type = "both";
325
+ }
326
+
327
+ ingest.selected.preview.watermark = watermarks[0] ? watermarks[0]._id : "";
328
+
329
+ let tags = ingest.selected.download.tags;
330
+ ingest.selected.preview.enabled =
331
+ !!(tags.Codec == "prores" &&
332
+ tags.Resolution.split("x")[1] == "1080" &&
333
+ (tags.Framerate == "23.98" || tags.Framerate == "25") &&
334
+ watermarks.length) ||
335
+ false;
336
+
337
+ return ingest;
187
338
  }
188
339
  }
189
-
package/src/Order.js CHANGED
@@ -14,18 +14,30 @@ export default class Order {
14
14
  };
15
15
  Object.assign(this, schema, data);
16
16
  }
17
+ /**
18
+ * Determines if an order should be classified as 'dubbed' based on its dng values
19
+ */
17
20
  isDub() {
18
21
  if (!this.dng) {
19
22
  return null;
20
23
  }
24
+ if (this.dng.graphics && this.dng.graphics.includes('Dedicated / Localized')) {
25
+ return false;
26
+ }
21
27
  return _
22
28
  .flattenDeep(Object.entries(this.dng))
23
29
  .includes("Dedicated / Localized");
24
30
  }
31
+ /**
32
+ * Determines in an order should be classified as 'subbed' based on its dng values
33
+ */
25
34
  isSub() {
26
35
  if (!this.dng) {
27
36
  return null;
28
37
  }
29
- return _.flattenDeep(Object.entries(this.dng)).includes("Subtitled");
38
+ if (this.dng === 'Graphics Only') return false;
39
+ return _
40
+ .flattenDeep(Object.entries(this.dng))
41
+ .includes("Subtitled");
30
42
  }
31
43
  }
@@ -1,8 +1,8 @@
1
1
  import Filename from "../src/Filename";
2
2
  let mocks = require("./mocks/mocks");
3
3
 
4
- describe("Filename", function() {
5
- describe("render", function() {
4
+ describe("Filename", () => {
5
+ describe("render", () => {
6
6
  it("renders tags as an underscore-separated string", function() {
7
7
  let asset = {
8
8
  name: "Test Asset A",
@@ -30,7 +30,61 @@ describe("Filename", function() {
30
30
  );
31
31
  });
32
32
 
33
- it("displays resolution for images", function () {
33
+ it("renders language and country", function() {
34
+ let asset = {
35
+ name: "Test Asset A",
36
+ slug: "test-asset-a",
37
+ type: "trailer.intl",
38
+ mediaType: "video",
39
+ project: {
40
+ filePrefix: "TESTPROJECT"
41
+ }
42
+ };
43
+ let options = {
44
+ language: "ENG",
45
+ country: "US",
46
+ tags: {
47
+ Text: "txtd",
48
+ Extra: ["COMING-SOON", "HOJE"],
49
+ Codec: "PRORES",
50
+ Resolution: "640x480",
51
+ Framerate: "23.98",
52
+ "Frame Mode": "progressive"
53
+ }
54
+ };
55
+ expect(Filename.render(mocks.tags, mocks.types, asset, options)).toBe(
56
+ "TESTPROJECT_ITR-TEST-ASSET-A_ENG-US_TXTD_COMING-SOON_HOJE_PRORES_480p2398"
57
+ );
58
+ });
59
+
60
+ it("renders language only for dual-language codes", function () {
61
+ let asset = {
62
+ name: "Test Asset A",
63
+ slug: "test-asset-a",
64
+ type: "trailer.intl",
65
+ mediaType: "video",
66
+ project: {
67
+ filePrefix: "TESTPROJECT"
68
+ }
69
+ };
70
+ let options = {
71
+ language: "PFR-FLE",
72
+ country: "US",
73
+ tags: {
74
+ Text: "txtd",
75
+ Extra: ["COMING-SOON", "HOJE"],
76
+ Codec: "PRORES",
77
+ Resolution: "640x480",
78
+ Framerate: "23.98",
79
+ "Frame Mode": "progressive"
80
+ }
81
+ };
82
+ expect(Filename.render(mocks.tags, mocks.types, asset, options)).toBe(
83
+ "TESTPROJECT_ITR-TEST-ASSET-A_PFR-FLE_TXTD_COMING-SOON_HOJE_PRORES_480p2398"
84
+ );
85
+ });
86
+
87
+ it("displays resolution for images", function() {
34
88
  let asset = {
35
89
  name: "Test Asset A",
36
90
  slug: "test-asset-a",
@@ -44,13 +98,13 @@ describe("Filename", function() {
44
98
  language: "ENG",
45
99
  country: "WW",
46
100
  tags: {
47
- Text: 'txtd',
101
+ Text: "txtd",
48
102
  Resolution: "640x480"
49
103
  }
50
104
  };
51
- expect(Filename.render(mocks.tags, mocks.types, asset, options, 'image')).toBe(
52
- "TESTPROJECT_ITR-TEST-ASSET-A_ENG_TXTD_640x480"
53
- );
105
+ expect(
106
+ Filename.render(mocks.tags, mocks.types, asset, options, "image")
107
+ ).toBe("TESTPROJECT_ITR-TEST-ASSET-A_ENG_TXTD_640x480");
54
108
  });
55
109
 
56
110
  it("renders asset names with contractions correctly", function() {
@@ -122,7 +176,7 @@ describe("Filename", function() {
122
176
  }).toThrow("missing asset.project");
123
177
  });
124
178
 
125
- it("throws exception if missing asset.length (film-clip)", function() {
179
+ xit("throws exception if missing asset.length (film-clip)", function() {
126
180
  let asset = {
127
181
  name: "Test Asset A",
128
182
  slug: "test-asset-a",
@@ -133,7 +187,10 @@ describe("Filename", function() {
133
187
  }
134
188
  };
135
189
  let options = {
136
- language: "ENG"
190
+ language: "ENG",
191
+ tags: {
192
+ Text: "txtd"
193
+ }
137
194
  };
138
195
  expect(() => {
139
196
  Filename.render(mocks.tags, mocks.types, asset, options);
@@ -168,30 +225,6 @@ describe("Filename", function() {
168
225
  // }).toThrow('conflicting options supplied: SubDub and Text');
169
226
  // });
170
227
 
171
- it("throws exception if both SubDub and Text is not supplied", function() {
172
- let asset = {
173
- name: "Test Asset A",
174
- slug: "test-asset-a",
175
- type: "trailer.intl",
176
- mediaType: "video",
177
- project: {
178
- filePrefix: "TESTPROJECT"
179
- }
180
- };
181
- let options = {
182
- language: "ENG",
183
- tags: {
184
- Codec: "prores",
185
- Resolution: "640x480",
186
- Framerate: "23.98",
187
- "Frame Mode": "progressive"
188
- }
189
- };
190
- expect(() => {
191
- Filename.render(mocks.tags, mocks.types, asset, options);
192
- }).toThrow("missing options.tags.Text or options.tags.SubDub");
193
- });
194
-
195
228
  // it("throws exception if mediaType=video is missing Codec", function() {
196
229
  // let asset = {
197
230
  // name: "Test Asset A",
@@ -238,7 +271,7 @@ describe("Filename", function() {
238
271
  }
239
272
  };
240
273
  expect(() => {
241
- Filename.render(mocks.tags, mocks.types, asset, options, 'video');
274
+ Filename.render(mocks.tags, mocks.types, asset, options, "video");
242
275
  }).toThrow("missing options.tags.Resolution");
243
276
  });
244
277
 
@@ -263,7 +296,7 @@ describe("Filename", function() {
263
296
  }
264
297
  };
265
298
  expect(() => {
266
- Filename.render(mocks.tags, mocks.types, asset, options, 'video');
299
+ Filename.render(mocks.tags, mocks.types, asset, options, "video");
267
300
  }).toThrow("missing options.tags.Framerate");
268
301
  });
269
302
 
@@ -288,11 +321,11 @@ describe("Filename", function() {
288
321
  }
289
322
  };
290
323
  expect(() => {
291
- Filename.render(mocks.tags, mocks.types, asset, options, 'video');
324
+ Filename.render(mocks.tags, mocks.types, asset, options, "video");
292
325
  }).toThrow("missing options.tags[Frame Mode]");
293
326
  });
294
327
 
295
- it("throws exception if missing asset.length (featurette)", function() {
328
+ xit("throws exception if missing asset.length (featurette)", function() {
296
329
  let asset = {
297
330
  name: "Test Asset A",
298
331
  slug: "test-asset-a",
@@ -303,7 +336,10 @@ describe("Filename", function() {
303
336
  }
304
337
  };
305
338
  let options = {
306
- language: "ENG"
339
+ language: "ENG",
340
+ tags: {
341
+ Text: "txtd"
342
+ }
307
343
  };
308
344
  expect(() => {
309
345
  Filename.render(mocks.tags, mocks.types, asset, options);