Add support for -renderSettings and -outputSettings overrides.
olekristensen opened this issue · 9 comments
Is your feature request related to a problem? Please describe.
If you want to setup nexrender to use customized output module settings and/or render settings they need to be configured manually first.
However, aerender allows us to modify the selected RStemplate and OMtemplate by using the command line options -renderSettings
and -outputSettings
.
This is super useful for nexrender, as it allows us to eg. select Field rendering for broadcast targets programmatically instead of having to manually setup a renderSetting that enables Field rendering.
Other use cases is setting draft render and downscaling in the template.json
Describe the solution you'd like
The template json should support two additional keys, renderSettings and outputSettings that map directly to the aerender flags.
Describe alternatives you've considered
Before we've maintained a repository of After Effects preferences text files, and used them to overwrite AE's preferences before each render. This is error-prone and cumbersome.
Additional context
Documentation from aerender -h
scroll down to the bottom two lines to see how it's presented by Adobe.
aerender version 23.4x53
USAGE:
1] aerender renders After Effects comps. The render may be performed either
by an already running instance of AE or by a newly invoked instance. By
default, aerender will invoke a new instance of AE, even if one is
already running. To change this, see the "-reuse" flag below.
2] aerender takes a series of optional arguments.
Some are single flags, like "-reuse". Some come in flag-argument
pairs, like "-project project_path". And one comes in a triplet,
-mem_usage image_cache_percent max_mem_percent.
3] aerender with 0 arguments, or with any argument equaling "-help"
or "-h", prints this usage message.
4] The arguments are:
"-h" print this usage message
"-help" print this usage message
"-reuse" use this flag if you want to try and reuse
an already running instance of AE to perform the
render. By default, aerender will launch a new
instance of After Effects, even if one is already
running. But, if AE is already running, and the
"-reuse" flag is provided, then aerender will
ask the already running instance of AE to perform
the render. Whenever aerender launches a new
instance of AE, it will tell AE to quit when
rendering is completed; otherwise, it will not
quit AE. Also, the preferences will be written
to file upon quit when the "-reuse" flag is
specified; otherwise it will not be written.
"-project project_path" where project_path is a file path or URI
specifying a project file to open.
If none is provided, aerender will work with the
currently open project.
If no project is open and no project is provided,
an error will result.
"-teamproject project_name" where project_name is a name of a
team project to open.
"-comp comp_name" where comp_name specifies a comp to be rendered.
If the comp is in the render queue already, and
in a queueable state, then (only) the first
queueable instance of that comp on the render
queue will be rendered. If the comp is in the
project but not in the render queue, then it will
be added to the render queue and rendered.
If no -comp argument is provided, aerender will
render the entire render queue as is. In this
case (no -comp), the only other arguments used
will be -project, -log, -v, -mem_usage, and
-close; the -RStemplate, -OMtemplate, -output,
-s, -e, and -i arguments will be ignored.
"-rqindex index_in_render_queue" where index_in_render_queue specifies a
render queue item to be rendered. Options that make
sense when rendering a single render queue item
are available like with the -comp flag.
"-RStemplate render_settings_template" where render_settings_template
is the name of a template to apply to the render
queue item.If the template does not exist it is
an error.
Default is to use the render template already
defined for the item.
"-renderSettings render_settings" where render_settings is a formatted
list of individual render settings to
override in the render queue item, after any
RS templates have been applied. If no render
queue item is specified it is an error. Settings
are in the form "key1: value1; key2: value2"
Keys and values are defined by the After Effects
Guide for Render Settings. See EXAMPLES below.
"-OMtemplate output_module_template" where output_module_template
is the name of a template to apply to the
output module. If the template does not exist
it is an error.
Default is to use the template already defined
for the output module.
"-outputSettings output_settings" where output_setting is a formatted
list of individual output module settings to
override in the render queue item, after any
OM templates have been applied. If no render
queue item is specified it is an error. Settings
are in the form "key1: value1; key2: value2"
Keys and values are defined by the After Effects
Guide for Output Module Settings. See EXAMPLES below.
"-output output_path" where output_path is a file path or URI
specifying the destination render file.
Default is the path already in the project file.
"-log logfile_path" where logfile_path is a file path or URI
specifying the location of the log file.
Default is stdout.
"-s start_frame" where start_frame is the first frame to render.
Default is the start frame in the file.
"-e end_frame" where end_frame is the last frame to render.
Note, this is "inclusive;" the final frame
will be rendered.
Default is the end frame in the file.
"-i increment" where increment is the number of frames to
advance before rendering a new frame. A value
of 1 (the default) results in a normal rendering
of all frames. Higher increments will repeat the
same (frame increment-1) times and then render a
new one, starting the cycle again. Higher values
result in faster renders but choppier motion.
Default is 1.
"-mem_usage image_cache_percent max_mem_percent"
where image_cache_percent specifies the maximum
percent of memory used to cache already rendered
images/footage, and max_mem_percent specifies
the total percent of memory that can be
used by After Effects.
"-mfr mfr_flag max_cpu_percent"
where mfr_flag ("ON"|"OFF") specifies if
Multi-Frame Rendering should be used, and
max_cpu_percent (1-100) specifies the desired maximum
CPU percentage power to use during rendering.
Because Multi-Frame Rendering has the ability
to use 100 percent of your CPU's capability, you may
choose to limit the CPU power so other
applications can be used.
max_cpu_percent will be ignored when the mfr_flag
is set to "OFF".
"-v verbose_flag" where verbose_flag specifies the type of
messages reported. Possible values are ERRORS
(prints only fatal and problem errors) or
ERRORS_AND_PROGRESS (prints progress of rendering
as well).
Default value is ERRORS_AND_PROGRESS.
"-close close_flag" where close_flag specifies whether or not to
close the project when done rendering, and
whether or not to save changes. If close_flag is
DO_NOT_SAVE_CHANGES, project will be closed
without saving changes. If close_flag is
SAVE_CHANGES, project will be closed and changes
will be saved. If close_flag is DO_NOT_CLOSE the
project will be left open; but the project is
left open only if using an already-running
instance of AE, since new invocations of AE must
always close and quit when done.
Default value is DO_NOT_SAVE_CHANGES.
"-sound sound_flag" where sound_flag specifies whether or not to play
a sound when rendering is complete. Possible
values are "ON" or "OFF".
Default value is "OFF".
"-version" displays the version number of aerender to the
console. Does not render.
"-continueOnMissingFootage"
Do not stop rendering on missing footage. Log and
render with placeholder color bars.
5] EXAMPLES:
To render just Comp 1 to a specified file:
aerender -project /Volumes/Stuff/projects/proj1.aep -comp "Comp 1"
-output /Volumes/Stuff/output/proj1/proj1.mov
To render everything in the render queue as is in the project file:
aerender -project /Volumes/Stuff/projects/proj1.aep
To render frames 1-10 using multi-machine render:
aerender -project /Volumes/Stuff/projects/proj1.aep
-comp "Comp 1" -RStemplate "Multi-Machine Settings"
-OMtemplate "Multi-Machine Sequence" -s 1 -e 10
-output /Volumes/Stuff/output/proj1/frames\[####\].psd
To render Comp 1 at Draft quality, Half resolution with top 4 lines cropped:
aerender -project /Volumes/Stuff/projects/proj1.aep -comp "Comp 1"
-renderSettings "Resolution: Half; Quality: Draft"
-outputSettings "Crop: true; Crop Top: 4"
Good point Mr @olekristensen! I totally missed the new options folks from Adobe introduced in the latest versions.
Will work on adding that!
p.s. Finally, they added support for something like this, this is a lifesaver! 🎉
@inlife I could possibly contribute this, I would want to work on it from Monday-tuesday next week... could possibly get it done within a day or so. I would just pass the strings to the command -
I actually added this commit an hour ago. Could you take a look and verify that you were thinking about a similar approach?
Exactly - one consideration I do have in general, is that there is a security impact when strings that are passed directly to the command line are not sanitised. For me it's not a problem, I'm using nexrender programatically, and the template.json is built internally in my render server code, but it does potentially leave the nexrender server vulnerable for shell script injection...
using something like https://www.npmjs.com/package/escape-it could at least help
adding some regex matching to validate options in the params would also be an option.
Those are good points, probably could be added in the future updates
But what are the settings?
The renderSettings and outputSettings are really not documented by Adobe, but they can be retrieved by running the following .jsx script asking for the settings specs as 'JSON' strings (it's not valid json unless you replace the illegal keys -1 with a string representation).
var rqItem1_spec_str = app.project.renderQueue.item(1).getSettings(GetSettingsFormat.SPEC);
var rqItem1_spec_str_json = rqItem1_spec_str.toSource();
alert("Render Settings:\n" + rqItem1_spec_str_json);
var rqItem1_om_spec_str = app.project.renderQueue.item(1).outputModule(1).getSettings(GetSettingsFormat.SPEC);
var rqItem1_om_spec_str_json = rqItem1_om_spec_str.toSource();
alert("Output Module Settings:\n" + rqItem1_om_spec_str_json);
Below are the results:
Render Settings Spec:
({
"3:2 Pulldown": {
type: "int",
enums: { Off: 0, WSSWW: 1, SSWWW: 2, SWWWS: 3, WWWSS: 4, WWSSW: 5 },
"enums-reverse": {
0: "Off",
1: "WSSWW",
2: "SSWWW",
3: "SWWWS",
4: "WWWSS",
5: "WWSSW",
},
range: [0, 5],
},
"Color Depth": {
type: "int",
enums: {
"Current Settings": -1,
"8 bits per channel": 0,
"16 bits per channel": 1,
"32 bits per channel": 2,
},
"enums-reverse": {
"-1": "Current Settings",
0: "8 bits per channel",
1: "16 bits per channel",
2: "32 bits per channel",
},
range: [-1, 2],
},
"Disk Cache": {
type: "int",
enums: { "Read Only": 0, "Current Settings": 2 },
"enums-reverse": { 0: "Read Only", 2: "Current Settings" },
range: [0, 2],
},
Effects: {
type: "int",
enums: { "All Off": 0, "All On": 1, "Current Settings": 2 },
"enums-reverse": { 0: "All Off", 1: "All On", 2: "Current Settings" },
range: [0, 2],
},
"Field Render": {
type: "int",
enums: { Off: 0, "Upper Field First": 1, "Lower Field First": 2 },
"enums-reverse": {
0: "Off",
1: "Upper Field First",
2: "Lower Field First",
},
range: [0, 2],
},
"Frame Blending": {
type: "int",
enums: {
"Off for All Layers": 0,
"On for Checked Layers": 1,
"Current Settings": 2,
},
"enums-reverse": {
0: "Off for All Layers",
1: "On for Checked Layers",
2: "Current Settings",
},
range: [0, 2],
},
"Frame Rate": {
type: "int",
enums: { "Use comp's frame rate": 0, "Use this frame rate": 1 },
"enums-reverse": { 0: "Use comp's frame rate", 1: "Use this frame rate" },
range: [0, 1],
},
"Guide Layers": {
type: "int",
enums: { "All Off": 0, "Current Settings": 2 },
"enums-reverse": { 0: "All Off", 2: "Current Settings" },
range: [0, 2],
},
"Motion Blur": {
type: "int",
enums: {
"Off for All Layers": 0,
"On for Checked Layers": 1,
"Current Settings": 2,
},
"enums-reverse": {
0: "Off for All Layers",
1: "On for Checked Layers",
2: "Current Settings",
},
range: [0, 2],
},
"Proxy Use": {
type: "int",
enums: {
"Use No Proxies": 0,
"Use All Proxies": 1,
"Current Settings": 2,
"Use Comp Proxies Only": 3,
},
"enums-reverse": {
0: "Use No Proxies",
1: "Use All Proxies",
2: "Current Settings",
3: "Use Comp Proxies Only",
},
range: [0, 3],
},
Quality: {
type: "int",
enums: { "Current Settings": -1, Wireframe: 0, Draft: 1, Best: 2 },
"enums-reverse": {
"-1": "Current Settings",
0: "Wireframe",
1: "Draft",
2: "Best",
},
range: [-1, 2],
},
Resolution: {
type: '{"x": <int>, "y": <int>}',
enums: {
"Current Settings": "0,0",
Custom: "x,y",
Custom2: '{"x": <x_val>, "y": <y_val>}',
Custom3: "[<x_val>,<y_val>]",
Full: "1,1",
Half: "2,2",
Quarter: "4,4",
Third: "3,3",
},
"enums-reverse": {
"0,0": "Current Settings",
"x,y": "Custom",
'{"x": <x_val>, "y": <y_val>}': "Custom2",
"[<x_val>,<y_val>]": "Custom3",
"1,1": "Full",
"2,2": "Half",
"4,4": "Quarter",
"3,3": "Third",
},
},
"Skip Existing Files": { type: "bool" },
"Solo Switches": {
type: "int",
enums: { "All Off": 0, "Current Settings": 2 },
"enums-reverse": { 0: "All Off", 2: "Current Settings" },
range: [0, 2],
},
"Time Span": {
type: "int",
enums: { "Length of Comp": 0, "Work Area Only": 1, Custom: 2 },
"enums-reverse": { 0: "Length of Comp", 1: "Work Area Only", 2: "Custom" },
range: [0, 2],
},
"Time Span Duration": { type: "double" },
"Time Span End": { type: "double" },
"Time Span Start": { type: "double" },
"Use comp's frame rate": { type: "double" },
"Use this frame rate": { type: "double" },
});
Output Settings Spec:
({
"Audio Bit Depth": {
type: "int",
enums: { "8 Bit": 1, "16 Bit": 2, "32 Bit": 4 },
"enums-reverse": { 1: "8 Bit", 2: "16 Bit", 4: "32 Bit" },
range: [1, 4],
},
"Audio Channels": {
type: "int",
enums: { Mono: 1, Stereo: 2 },
"enums-reverse": { 1: "Mono", 2: "Stereo" },
range: [1, 2],
},
"Audio Sample Rate": {
type: "int",
enums: {
"16,000 kHz": 16000,
"22,050 kHz": 22050,
"24,000 kHz": 24000,
"32,000 kHz": 32000,
"44,100 kHz": 44100,
"48,000 kHz": 48000,
},
"enums-reverse": {
16000: "16,000 kHz",
22050: "22,050 kHz",
24000: "24,000 kHz",
32000: "32,000 kHz",
44100: "44,100 kHz",
48000: "48,000 kHz",
},
range: [16000, 48000],
},
Channels: {
type: "int",
enums: { RGB: 0, "RGB + Alpha": 1, Alpha: 2 },
"enums-reverse": { 0: "RGB", 1: "RGB + Alpha", 2: "Alpha" },
range: [0, 2],
},
Color: {
type: "int",
enums: { "Straight (Unmatted)": 0, "Premultiplied (Matted)": 1 },
"enums-reverse": { 0: "Straight (Unmatted)", 1: "Premultiplied (Matted)" },
range: [0, 1],
},
Crop: { type: "bool" },
"Crop Bottom": { type: "int" },
"Crop Left": { type: "int" },
"Crop Right": { type: "int" },
"Crop Top": { type: "int" },
Depth: {
type: "int",
enums: {
"Floating Point Gray": -32,
"256 Colors": 8,
"Millions of Colors": 24,
"Millions of Colors+": 32,
"256 Grays": 40,
"Trillions of Colors": 48,
"Trillions of Colors+": 64,
"Floating Point": 96,
"Floating Point+": 128,
},
"enums-reverse": {
"-32": "Floating Point Gray",
8: "256 Colors",
24: "Millions of Colors",
32: "Millions of Colors+",
40: "256 Grays",
48: "Trillions of Colors",
64: "Trillions of Colors+",
96: "Floating Point",
128: "Floating Point+",
},
range: [-32, 128],
},
Format: {
type: "int",
enums: {
AIFF: 0,
"DPX/Cineon Sequence": 1,
"H.264": 2,
"IFF Sequence": 3,
"JPEG Sequence": 4,
MP3: 5,
"OpenEXR Sequence": 6,
"PNG Sequence": 7,
"Photoshop Sequence": 8,
QuickTime: 9,
"Radiance Sequence": 10,
"SGI Sequence": 11,
"TIFF Sequence": 12,
"Targa Sequence": 13,
WAV: 14,
},
"enums-reverse": {
0: "AIFF",
1: "DPX/Cineon Sequence",
2: "H.264",
3: "IFF Sequence",
4: "JPEG Sequence",
5: "MP3",
6: "OpenEXR Sequence",
7: "PNG Sequence",
8: "Photoshop Sequence",
9: "QuickTime",
10: "Radiance Sequence",
11: "SGI Sequence",
12: "TIFF Sequence",
13: "Targa Sequence",
14: "WAV",
},
range: [0, 14],
},
"Include Project Link": { type: "bool" },
"Include Source XMP Metadata": { type: "bool" },
"Lock Aspect Ratio": { type: "bool" },
"Output Audio": {
type: "int",
enums: { Off: 1, On: 2, Auto: 3 },
"enums-reverse": { 1: "Off", 2: "On", 3: "Auto" },
range: [1, 3],
},
"Output File Info": {
type: {
"Full Flat Path": "string",
"Base Path": "string",
"Subfolder Path": "string",
"File Name": "string",
"File Template": "string",
},
},
"Post-Render Action": {
type: "int",
enums: { None: 0, Import: 1, "Import & Replace Usage": 2, "Set Proxy": 3 },
"enums-reverse": {
0: "None",
1: "Import",
2: "Import & Replace Usage",
3: "Set Proxy",
},
range: [0, 3],
},
Resize: { type: "bool" },
"Resize Quality": {
type: "int",
enums: { Low: 0, High: 1 },
"enums-reverse": { 0: "Low", 1: "High" },
range: [0, 1],
},
"Resize to": {
type: '{"x": <int>, "y": <int>}',
enums: {
"Cineon Full \u2022 3656x2664 \u2022 24 fps": "3656,2664",
"Cineon Half \u2022 1828x1332 \u2022 24 fps": "1828,1332",
Custom: "x,y",
Custom2: '{"x": <x_val>, "y": <y_val>}',
Custom3: "[<x_val>,<y_val>]",
"DVCPRO HD \u2022 1280x1080 (1,5) \u2022 29,97 fps": "1280,1080",
"DVCPRO HD \u2022 1440x1080 (1,33) \u2022 25 fps": "1440,1080",
"DVCPRO HD \u2022 960x720 (1,33) \u2022 23,976 fps": "960,720",
"DVCPRO HD \u2022 960x720 (1,33) \u2022 25 fps": "960,720",
"DVCPRO HD \u2022 960x720 (1,33) \u2022 29,97 fps": "960,720",
"Film (2K) \u2022 2048x1556 \u2022 24 fps": "2048,1556",
"Film (4K) \u2022 4096x3112 \u2022 24 fps": "4096,3112",
"HD \u2022 1920x1080 \u2022 24 fps": "1920,1080",
"HD \u2022 1920x1080 \u2022 25 fps": "1920,1080",
"HD \u2022 1920x1080 \u2022 29,97 fps": "1920,1080",
"HDV \u2022 1440x1080 (1,33) \u2022 25 fps": "1440,1080",
"HDV \u2022 1440x1080 (1,33) \u2022 29,97 fps": "1440,1080",
"HDV/HDTV \u2022 1280x720 \u2022 25 fps": "1280,720",
"HDV/HDTV \u2022 1280x720 \u2022 29,97 fps": "1280,720",
"Social Media Landscape \u2022 1280x720 \u2022 30 fps": "1280,720",
"Social Media Landscape HD \u2022 1920x1080 \u2022 30 fps": "1920,1080",
"Social Media Portrait \u2022 720x1280 \u2022 30 fps": "720,1280",
"Social Media Portrait HD \u2022 1080x1920 \u2022 30 fps": "1080,1920",
"Social Media Square \u2022 1080x1080 \u2022 30 fps": "1080,1080",
"UHD (4K) \u2022 3840x2160 \u2022 23,976 fps": "3840,2160",
"UHD (4K) \u2022 3840x2160 \u2022 25 fps": "3840,2160",
"UHD (4K) \u2022 3840x2160 \u2022 29,97 fps": "3840,2160",
"UHD (8K) \u2022 7680x4320 \u2022 23,976 fps": "7680,4320",
},
"enums-reverse": {
"3656,2664": "Cineon Full • 3656x2664 • 24 fps",
"1828,1332": "Cineon Half • 1828x1332 • 24 fps",
"x,y": "Custom",
'{"x": <x_val>, "y": <y_val>}': "Custom2",
"[<x_val>,<y_val>]": "Custom3",
"1280,1080": "DVCPRO HD • 1280x1080 (1,5) • 29,97 fps",
"1440,1080": "HDV • 1440x1080 (1,33) • 29,97 fps",
"960,720": "DVCPRO HD • 960x720 (1,33) • 29,97 fps",
"2048,1556": "Film (2K) • 2048x1556 • 24 fps",
"4096,3112": "Film (4K) • 4096x3112 • 24 fps",
"1920,1080": "Social Media Landscape HD • 1920x1080 • 30 fps",
"1280,720": "Social Media Landscape • 1280x720 • 30 fps",
"720,1280": "Social Media Portrait • 720x1280 • 30 fps",
"1080,1920": "Social Media Portrait HD • 1080x1920 • 30 fps",
"1080,1080": "Social Media Square • 1080x1080 • 30 fps",
"3840,2160": "UHD (4K) • 3840x2160 • 29,97 fps",
"7680,4320": "UHD (8K) • 7680x4320 • 23,976 fps",
},
},
"Starting #": { type: "int" },
"Use Comp Frame Number": { type: "bool" },
"Use Region of Interest": { type: "bool" },
"Video Output": { type: "bool" },
});
@olekristensen this is super helpful, in what context would one run that script above?