@nexrender/core 1.32.3 → 1.36.0
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/readme.md +7 -0
- package/src/assets/commandLineRenderer-2022.jsx +1130 -0
- package/src/assets/{commandLineRenderer.jsx → commandLineRenderer-default.jsx} +12 -12
- package/src/helpers/autofind.js +1 -0
- package/src/helpers/patch.js +11 -3
- package/src/index.js +2 -1
- package/src/tasks/actions.js +7 -3
- package/src/tasks/cleanup.js +1 -3
- package/src/tasks/download.js +6 -10
- package/src/tasks/render.js +3 -3
- package/src/tasks/script.js +11 -9
- package/src/tasks/setup.js +0 -1
- package/test/mytest.js +1 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module.exports = /*syntax:js*/ `// Command line renderer for After Effects. (nexrender-patch-v1.0.
|
|
1
|
+
module.exports = /*syntax:js*/ `// Command line renderer for After Effects. (nexrender-patch-v1.0.3)
|
|
2
2
|
|
|
3
3
|
// This function constructs an AECommandLineRenderer object.
|
|
4
4
|
// One and only one of these will be created to perform rendering tasks
|
|
@@ -120,7 +120,7 @@ function AECommandLineRenderer() {
|
|
|
120
120
|
// Report an error. This writes errors to the log file, if present.
|
|
121
121
|
// This is called from the context of the application, so we
|
|
122
122
|
// need to precede variable names with gAECommandLineRenderer
|
|
123
|
-
//
|
|
123
|
+
//
|
|
124
124
|
function checkParentDied() {
|
|
125
125
|
var result = false;
|
|
126
126
|
if (gAECommandLineRenderer.log_file instanceof Socket) {
|
|
@@ -143,13 +143,13 @@ function AECommandLineRenderer() {
|
|
|
143
143
|
checkParentDied();
|
|
144
144
|
if (severity_string == "PROBLEM" || severity_string == "FATAL") {
|
|
145
145
|
// These two errors cause us to change the exit code.
|
|
146
|
-
// We don't write an error or throw here, because we got here as part of a thrown
|
|
146
|
+
// We don't write an error or throw here, because we got here as part of a thrown
|
|
147
147
|
// error already, and the message will be printed as part of the catch.
|
|
148
148
|
gAECommandLineRenderer.SetExitCode(gAECommandLineRenderer.EXIT_AE_RUNTIME);
|
|
149
149
|
} else {
|
|
150
150
|
// PROBLEM and FATAL will throw exceptions, and so will be logged to the file
|
|
151
151
|
// when we catch the exception.
|
|
152
|
-
// All other errors (NAKED, INFO, WARNING, PROGRESS, and DEBUG) will not
|
|
152
|
+
// All other errors (NAKED, INFO, WARNING, PROGRESS, and DEBUG) will not
|
|
153
153
|
// throw exceptions. So we log them to the file right here:
|
|
154
154
|
if (gAECommandLineRenderer.is_verbose_mode) {
|
|
155
155
|
if (gAECommandLineRenderer.log_file != null) {
|
|
@@ -177,7 +177,7 @@ function AECommandLineRenderer() {
|
|
|
177
177
|
|
|
178
178
|
// Report an error. This establishes exitCodes for reporting errors from AfterFX.
|
|
179
179
|
function my_SetExitCode(code) {
|
|
180
|
-
// Some codes are set differently depending on whether we have a custom user
|
|
180
|
+
// Some codes are set differently depending on whether we have a custom user
|
|
181
181
|
// log file. Check for these and use the alternate if appropriate.
|
|
182
182
|
var real_code = code;
|
|
183
183
|
if (gAECommandLineRenderer.has_user_log_file) {
|
|
@@ -203,7 +203,7 @@ function AECommandLineRenderer() {
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
// Arguments may be enclosed in quotes. This
|
|
206
|
+
// Arguments may be enclosed in quotes. This
|
|
207
207
|
// will remove them and return the result.
|
|
208
208
|
function my_StripAnyEnclosingQuotes(inString) {
|
|
209
209
|
var result = inString;
|
|
@@ -514,7 +514,7 @@ function AECommandLineRenderer() {
|
|
|
514
514
|
try {
|
|
515
515
|
// While rendering we'll report errors to the log file.
|
|
516
516
|
if (app.onError == this.onError) {
|
|
517
|
-
// If the previous error handler is just this one, don't store it.
|
|
517
|
+
// If the previous error handler is just this one, don't store it.
|
|
518
518
|
// That can happen in extreme cases where this script does not get a
|
|
519
519
|
// chance to clean up and put back the oldErrorHandler when it's done.
|
|
520
520
|
this.oldErrorHandler = null;
|
|
@@ -719,10 +719,10 @@ function AECommandLineRenderer() {
|
|
|
719
719
|
}
|
|
720
720
|
} else {
|
|
721
721
|
// Render times are stored as timeSpanStart and timeSpanDuration.
|
|
722
|
-
// Setting only the timeSpanStart will not change the timeSpanDuration and
|
|
723
|
-
// so will move the end time, but we want the end time unchanged if
|
|
722
|
+
// Setting only the timeSpanStart will not change the timeSpanDuration and
|
|
723
|
+
// so will move the end time, but we want the end time unchanged if
|
|
724
724
|
// it was not specified.
|
|
725
|
-
// So we must calculate both start_time and end_time,
|
|
725
|
+
// So we must calculate both start_time and end_time,
|
|
726
726
|
// then set both timeSpanStart and timeSpanDuration.
|
|
727
727
|
// Note: frameDuration is stored in the comp.
|
|
728
728
|
var start_time = rqi.timeSpanStart;
|
|
@@ -760,12 +760,12 @@ function AECommandLineRenderer() {
|
|
|
760
760
|
// Increment as defined here is one greater then the
|
|
761
761
|
// the render queue item's skipFrames.
|
|
762
762
|
// skipFrames 0 is the same as increment of 1.
|
|
763
|
-
//
|
|
763
|
+
//
|
|
764
764
|
rqi.skipFrames = (this.in_increment - 1);
|
|
765
765
|
}
|
|
766
766
|
}
|
|
767
767
|
|
|
768
|
-
// If we are in verbose mode, set the log type to ERRORS_AND_PER_FRAME_INFO
|
|
768
|
+
// If we are in verbose mode, set the log type to ERRORS_AND_PER_FRAME_INFO
|
|
769
769
|
// for all RQ items we are about to render.
|
|
770
770
|
if (this.is_verbose_mode) {
|
|
771
771
|
this.SetLogPerFrameInfoInRQ();
|
package/src/helpers/autofind.js
CHANGED
|
@@ -12,6 +12,7 @@ const defaultPaths = {
|
|
|
12
12
|
'/Applications/Adobe After Effects CC 2019',
|
|
13
13
|
'/Applications/Adobe After Effects 2020',
|
|
14
14
|
'/Applications/Adobe After Effects 2021',
|
|
15
|
+
'/Applications/Adobe After Effects 2022',
|
|
15
16
|
'/Applications/Adobe After Effects CC 2021',
|
|
16
17
|
'/Applications/Adobe After Effects CC 2022',
|
|
17
18
|
],
|
package/src/helpers/patch.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const mkdirp = require('mkdirp')
|
|
4
|
-
const
|
|
4
|
+
const patchedDefault = require('../assets/commandLineRenderer-default.jsx')
|
|
5
|
+
const patched2022 = require('../assets/commandLineRenderer-2022.jsx')
|
|
5
6
|
|
|
6
7
|
const writeTo = (data, dst) => fs.writeFileSync(dst, data)
|
|
7
8
|
const copyTo = (src, dst) => fs.writeFileSync(dst, fs.readFileSync(src))
|
|
@@ -14,6 +15,13 @@ module.exports = (settings) => {
|
|
|
14
15
|
const targetScript = 'commandLineRenderer.jsx';
|
|
15
16
|
|
|
16
17
|
const afterEffects = path.dirname(settings.binary)
|
|
18
|
+
const afterEffectsYearMatch = afterEffects.match(/(20[0-9]{2})/);
|
|
19
|
+
|
|
20
|
+
let patched = patchedDefault;
|
|
21
|
+
if (afterEffectsYearMatch && afterEffectsYearMatch[0] >= "2022") {
|
|
22
|
+
patched = patched2022;
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
const originalFile = path.join(afterEffects, 'Scripts', 'Startup', targetScript)
|
|
18
26
|
const backupFile = path.join(afterEffects, 'Backup.Scripts', 'Startup', targetScript)
|
|
19
27
|
|
|
@@ -25,8 +33,8 @@ module.exports = (settings) => {
|
|
|
25
33
|
if (data.indexOf('nexrender-patch') !== -1) {
|
|
26
34
|
settings.logger.log('command line patch already is in place')
|
|
27
35
|
|
|
28
|
-
const patchedMatch = patched.match(/nexrender-patch-v([0-9
|
|
29
|
-
const existingMatch = data.match(/nexrender-patch-v([0-9
|
|
36
|
+
const patchedMatch = patched.match(/nexrender-patch-v([0-9.]+)/)
|
|
37
|
+
const existingMatch = data.match(/nexrender-patch-v([0-9.]+)/)
|
|
30
38
|
|
|
31
39
|
if (patchedMatch[1] !== existingMatch[1]) {
|
|
32
40
|
try {
|
package/src/index.js
CHANGED
|
@@ -48,7 +48,7 @@ const init = (settings) => {
|
|
|
48
48
|
const binaryUser = settings.binary && fs.existsSync(settings.binary) ? settings.binary : null;
|
|
49
49
|
|
|
50
50
|
if (!binaryUser && !binaryAuto) {
|
|
51
|
-
throw new Error('you should provide a proper path to After Effects\'
|
|
51
|
+
throw new Error('you should provide a proper path to After Effects\' "aerender" binary')
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
if (binaryAuto && !binaryUser) {
|
|
@@ -67,6 +67,7 @@ const init = (settings) => {
|
|
|
67
67
|
|
|
68
68
|
debug: false,
|
|
69
69
|
multiFrames: false,
|
|
70
|
+
multiFramesCPU: 90,
|
|
70
71
|
maxMemoryPercent: undefined,
|
|
71
72
|
imageCachePercent: undefined,
|
|
72
73
|
wslMap: undefined,
|
package/src/tasks/actions.js
CHANGED
|
@@ -21,9 +21,13 @@ module.exports = actionType => (job, settings) => {
|
|
|
21
21
|
settings.logger.log(`[${job.uid}] applying ${actionType} actions...`);
|
|
22
22
|
|
|
23
23
|
return PromiseSerial((job.actions[actionType] || []).map(action => () => {
|
|
24
|
-
|
|
25
|
-
return
|
|
26
|
-
}
|
|
24
|
+
if(settings.actions && settings.actions[action.module]){
|
|
25
|
+
return settings.actions[action.module](job, settings, action, actionType);
|
|
26
|
+
}else{
|
|
27
|
+
return requireg(action.module)(job, settings, action, actionType).catch(err => {
|
|
28
|
+
return Promise.reject(new Error(`Error loading ${actionType} module ${action.module}: ${err}`));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
27
31
|
})).then(() => {
|
|
28
32
|
return Promise.resolve(job)
|
|
29
33
|
});
|
package/src/tasks/cleanup.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
1
|
const rimraf = require('rimraf')
|
|
4
2
|
|
|
5
3
|
/**
|
|
@@ -11,7 +9,7 @@ module.exports = function(job, settings) {
|
|
|
11
9
|
return Promise.resolve(job)
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
return new Promise((resolve
|
|
12
|
+
return new Promise((resolve) => {
|
|
15
13
|
settings.logger.log(`[${job.uid}] cleaning up...`);
|
|
16
14
|
|
|
17
15
|
rimraf(job.workpath, {glob: false}, (err) => {
|
package/src/tasks/download.js
CHANGED
|
@@ -13,8 +13,9 @@ const requireg = require('requireg')
|
|
|
13
13
|
const download = (job, settings, asset) => {
|
|
14
14
|
if (asset.type == 'data') return Promise.resolve();
|
|
15
15
|
|
|
16
|
+
// eslint-disable-next-line
|
|
16
17
|
const uri = global.URL ? new URL(asset.src) : url.parse(asset.src)
|
|
17
|
-
const protocol = uri.protocol.replace(
|
|
18
|
+
const protocol = uri.protocol.replace(/:$/, '');
|
|
18
19
|
let destName = '';
|
|
19
20
|
|
|
20
21
|
/* if asset doesnt have a file name, make up a random one */
|
|
@@ -23,7 +24,7 @@ const download = (job, settings, asset) => {
|
|
|
23
24
|
} else {
|
|
24
25
|
destName = path.basename(asset.src)
|
|
25
26
|
destName = destName.indexOf('?') !== -1 ? destName.slice(0, destName.indexOf('?')) : destName;
|
|
26
|
-
/* ^ remove possible query search string params ^
|
|
27
|
+
/* ^ remove possible query search string params ^ */
|
|
27
28
|
|
|
28
29
|
/* prevent same name file collisions */
|
|
29
30
|
if (fs.existsSync(path.join(job.workpath, destName))) {
|
|
@@ -61,7 +62,6 @@ const download = (job, settings, asset) => {
|
|
|
61
62
|
reject(err)
|
|
62
63
|
}
|
|
63
64
|
});
|
|
64
|
-
break;
|
|
65
65
|
|
|
66
66
|
case 'http':
|
|
67
67
|
case 'https':
|
|
@@ -77,14 +77,13 @@ const download = (job, settings, asset) => {
|
|
|
77
77
|
|
|
78
78
|
asset.extension = fileExt
|
|
79
79
|
const destHasExtension = path.extname(asset.dest) ? true : false
|
|
80
|
-
//don't do this if asset.dest already has extension else it gives you example.jpg.jpg like file in case of assets and aep/aepx file
|
|
80
|
+
//don't do this if asset.dest already has extension else it gives you example.jpg.jpg like file in case of assets and aep/aepx file
|
|
81
81
|
if (asset.extension && !destHasExtension) {
|
|
82
82
|
asset.dest += `.${fileExt}`
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
const stream = fs.createWriteStream(asset.dest)
|
|
87
|
-
let timer
|
|
88
87
|
|
|
89
88
|
return new Promise((resolve, reject) => {
|
|
90
89
|
const errorHandler = (error) => {
|
|
@@ -100,7 +99,6 @@ const download = (job, settings, asset) => {
|
|
|
100
99
|
.on('finish', resolve)
|
|
101
100
|
})
|
|
102
101
|
});
|
|
103
|
-
break;
|
|
104
102
|
|
|
105
103
|
case 'file':
|
|
106
104
|
const filepath = uri2path(expandEnvironmentVariables(asset.src))
|
|
@@ -125,7 +123,6 @@ const download = (job, settings, asset) => {
|
|
|
125
123
|
wr.end()
|
|
126
124
|
throw error
|
|
127
125
|
})
|
|
128
|
-
break;
|
|
129
126
|
|
|
130
127
|
/* custom/external handlers */
|
|
131
128
|
default:
|
|
@@ -134,13 +131,12 @@ const download = (job, settings, asset) => {
|
|
|
134
131
|
return requireg('@nexrender/provider-' + protocol).download(job, settings, asset.src, asset.dest, asset.params || {});
|
|
135
132
|
} catch (e) {
|
|
136
133
|
if (e.message.indexOf('Could not require module') !== -1) {
|
|
137
|
-
return Promise.reject(new Error(`Couldn
|
|
134
|
+
return Promise.reject(new Error(`Couldn't find module @nexrender/provider-${protocol}, Unknown protocol provided.`))
|
|
138
135
|
}
|
|
139
136
|
|
|
140
137
|
throw e;
|
|
141
138
|
}
|
|
142
139
|
|
|
143
|
-
break;
|
|
144
140
|
}
|
|
145
141
|
}
|
|
146
142
|
|
|
@@ -156,5 +152,5 @@ module.exports = function(job, settings) {
|
|
|
156
152
|
job.assets.map(asset => download(job, settings, asset))
|
|
157
153
|
)
|
|
158
154
|
|
|
159
|
-
return Promise.all(promises).then(
|
|
155
|
+
return Promise.all(promises).then(() => job);
|
|
160
156
|
}
|
package/src/tasks/render.js
CHANGED
|
@@ -29,7 +29,7 @@ module.exports = (job, settings) => {
|
|
|
29
29
|
let outputFile = expandEnvironmentVariables(job.output)
|
|
30
30
|
let projectFile = expandEnvironmentVariables(job.template.dest)
|
|
31
31
|
|
|
32
|
-
outputFileAE = checkForWSL(outputFile, settings)
|
|
32
|
+
const outputFileAE = checkForWSL(outputFile, settings)
|
|
33
33
|
projectFile = checkForWSL(projectFile, settings)
|
|
34
34
|
let jobScriptFile = checkForWSL(job.scriptfile, settings)
|
|
35
35
|
|
|
@@ -53,7 +53,7 @@ module.exports = (job, settings) => {
|
|
|
53
53
|
|
|
54
54
|
option(params, '-r', jobScriptFile);
|
|
55
55
|
|
|
56
|
-
if (!settings.skipRender && settings.multiFrames) params.push('-
|
|
56
|
+
if (!settings.skipRender && settings.multiFrames) params.push('-mfr', 'ON', settings.multiFramesCPU);
|
|
57
57
|
if (settings.reuse) params.push('-reuse');
|
|
58
58
|
if (job.template.continueOnMissing) params.push('-continueOnMissingFootage')
|
|
59
59
|
|
|
@@ -62,7 +62,7 @@ module.exports = (job, settings) => {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
if (settings['aeParams']) {
|
|
65
|
-
for (param of settings['aeParams']) {
|
|
65
|
+
for (const param of settings['aeParams']) {
|
|
66
66
|
let ps = param.split(" ");
|
|
67
67
|
|
|
68
68
|
if (ps.length > 0) {
|
package/src/tasks/script.js
CHANGED
|
@@ -8,7 +8,7 @@ const { checkForWSL } = require('../helpers/path')
|
|
|
8
8
|
const escape = str => {
|
|
9
9
|
str = JSON.stringify(str)
|
|
10
10
|
str = str.substring(1, str.length-1)
|
|
11
|
-
str = `'${str.replace(
|
|
11
|
+
str = `'${str.replace(/'/g, '\\\'')}'`
|
|
12
12
|
return str
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -50,9 +50,9 @@ const wrapData = ({ property, value, expression, ...asset }) => (`(function() {
|
|
|
50
50
|
})();\n`)
|
|
51
51
|
|
|
52
52
|
// @deprecated in favor of wrapEnhancedScript (implementation below)
|
|
53
|
-
const wrapScript = ({ dest }) => (`(function() {
|
|
54
|
-
|
|
55
|
-
})();\n`)
|
|
53
|
+
// const wrapScript = ({ dest }) => (`(function() {
|
|
54
|
+
// ${fs.readFileSync(dest, 'utf8')}
|
|
55
|
+
// })();\n`)
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
/*
|
|
@@ -72,7 +72,8 @@ const wrapScript = ({ dest }) => (`(function() {
|
|
|
72
72
|
|
|
73
73
|
@return string (String) The compiled script with parameter injection outside its original scope to avoid user-defined defaults collision.
|
|
74
74
|
*/
|
|
75
|
-
const wrapEnhancedScript = ({ dest, src, parameters = [], keyword, defaults, ...asset }, jobID, settings) => {
|
|
75
|
+
const wrapEnhancedScript = ({ dest, src, parameters = [], keyword, defaults, /* ...asset */ }, jobID, settings) => {
|
|
76
|
+
let arg, fullMatch;
|
|
76
77
|
|
|
77
78
|
function EnhancedScript (
|
|
78
79
|
dest,
|
|
@@ -238,7 +239,8 @@ const wrapEnhancedScript = ({ dest, src, parameters = [], keyword, defaults, ..
|
|
|
238
239
|
this.getLogger().log("We found a self-invoking method with arguments!");
|
|
239
240
|
this.getLogger().log(JSON.stringify(methodArgs));
|
|
240
241
|
const foundArgument = methodArgs.filter( argMatch => {
|
|
241
|
-
|
|
242
|
+
fullMatch = argMatch[0]
|
|
243
|
+
arg = argMatch[2]
|
|
242
244
|
|
|
243
245
|
return parameter.arguments && parameter.arguments.find(o => o.key == arg);
|
|
244
246
|
});
|
|
@@ -315,7 +317,7 @@ const wrapEnhancedScript = ({ dest, src, parameters = [], keyword, defaults, ..
|
|
|
315
317
|
if (nxMatches && nxMatches.length > 0 ) {
|
|
316
318
|
|
|
317
319
|
nxMatches.forEach( match => {
|
|
318
|
-
const
|
|
320
|
+
const keyword = match[2];
|
|
319
321
|
|
|
320
322
|
var nxMatch = {
|
|
321
323
|
key: keyword.replace(/\s/g, ''),
|
|
@@ -357,7 +359,7 @@ const wrapEnhancedScript = ({ dest, src, parameters = [], keyword, defaults, ..
|
|
|
357
359
|
|
|
358
360
|
return `
|
|
359
361
|
"parameters" : [
|
|
360
|
-
${missingParams.map((k
|
|
362
|
+
${missingParams.map((k) => template(k.key)).join("\n")}
|
|
361
363
|
]
|
|
362
364
|
`
|
|
363
365
|
}
|
|
@@ -406,7 +408,7 @@ const wrapEnhancedScript = ({ dest, src, parameters = [], keyword, defaults, ..
|
|
|
406
408
|
EnhancedScript.prototype.buildParameterConfigurator = function () {
|
|
407
409
|
|
|
408
410
|
const defaultGlobalValue = this.getStringifiedDefaultValue( this.defaults.global );
|
|
409
|
-
const defaultFnValue = this.getDefaultValue( this.defaults.function );
|
|
411
|
+
// const defaultFnValue = this.getDefaultValue( this.defaults.function );
|
|
410
412
|
const createParameterConfigurator = () => `
|
|
411
413
|
function ParameterConfigurator () {
|
|
412
414
|
this.params = [];
|
package/src/tasks/setup.js
CHANGED
package/test/mytest.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
module.exports = (job, settings) => {
|
|
1
|
+
module.exports = (job, /* settings */) => {
|
|
2
2
|
console.log('custom module hello world!')
|
|
3
3
|
return Promise.resolve(job)
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
const url = require('url');
|
|
7
|
-
|
|
8
6
|
console.log(new URL('d:/Documents/resource.txt'))
|
|
9
7
|
console.log(new URL('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D'))
|