AfterEffect(AE)插件是Adobe公司开发的特效制作软件,稳定快速的功能和特效,在视频制作领域使用非常广泛,本文向大家介绍如何在项目里进行命令行渲染功能。源代码如下所示:
// Command line renderer for After Effects.
// This function constructs an AECommandLineRenderer object.
// One and only one of these will be created to perform rendering tasks
// at the end of this file.
//
// The constructor has 3 sections:
// [1] define all the variable-type attributes used by this class;
// [2] define all the functions used by this class;
// [3] assign all the functions to be method-type attributes.
//
function AECommandLineRenderer()
{
// [1] define all the variable-type attributes used by this class
//
// Input before parsing
//
this.inArgs = null;
//
// Input after parsing
//
this.in_project_path = null;
this.in_teamproject_name = null;
this.in_comp_name = null;
this.in_rq_index = null;
this.in_RStemplate = null;
this.in_OMtemplate = null;
this.in_output_path = null;
this.in_logfile_path = null;
this.in_start_frame = null;
this.in_end_frame = null;
this.in_increment = null;
this.in_image_cache_percent = null;
this.in_max_mem_percent = null;
this.in_verbose_flag = null;
this.in_close_flag = null;
this.in_sound_flag = null;
this.in_port_address = null;
this.in_stop_on_missing_frame = true;
//
// Exit codes:
//
this.EXIT_OK = 0;
this.EXIT_FAILURE_CODE_FROM_APP = 1;
this.EXIT_SHOW_USAGE = 2;
this.EXIT_SYNTAX_ERROR = 3;
this.EXIT_SYNTAX_ERROR_USER_LOG = 4;
this.EXIT_OTHER_SCRIPTING_ERROR = 5;
this.EXIT_OTHER_SCRIPTING_ERROR_USER_LOG = 6;
this.EXIT_AERENDER_RUNTIME = 7;
this.EXIT_AERENDER_RUNTIME_USER_LOG = 8;
this.EXIT_AE_RUNTIME = 9;
this.EXIT_AE_RUNTIME_USER_LOG = 10;
this.EXIT_CANNOT_OPEN_SOCKET = 11;
this.EXIT_CODE_NO_LONGER_IN_USE = 12;
//
// Exit code message prefixes:
//
this.EXIT_MSG_PREFIX = new Array(
"", // EXIT_OK
"ERROR: ", // EXIT_FAILURE_CODE_FROM_APP
"USAGE: ", // EXIT_SHOW_USAGE
"SYNTAX ERROR: ", // EXIT_SYNTAX_ERROR
"SYNTAX ERROR: ", // EXIT_SYNTAX_ERROR_USER_LOG
"ERROR: ", // EXIT_OTHER_SCRIPTING_ERROR
"ERROR: ", // EXIT_OTHER_SCRIPTING_ERROR_USER_LOG
"ERROR: ", // EXIT_AERENDER_ERROR
"ERROR: ", // EXIT_AERENDER_ERROR_USER_LOG
"ERROR: ", // EXIT_AE_RUNTIME
"ERROR: ", // EXIT_AE_RUNTIME_USER_LOG
"ERROR: ", // EXIT_CANNOT_OPEN_SOCKET
"", // EXIT_CODE_NO_LONGER_IN_USE
);
//
// Messages:
//
this.MSG_NONE = "";
this.MSG_NOT_HANDLED_HERE = "reported by another script or AE runtime.";
this.MSG_SHOW_USAGE = "";
this.MSG_TRIED_TO_PARSE_UNDEFINED = "aerender tried to parse an undefined argument.";
this.MSG_UNDEFINED_VALUE_FOR_FLAG = "no value given for flag: ";
this.MSG_BAD_FLAG = "Illegal argument flag: ";
this.MSG_NO_PROJECT = "No project provided and no project open.";
this.MSG_BAD_VERBOSE_FLAG = "Bad value for -verbose.";
this.MSG_BAD_CLOSE_FLAG = "Bad value for -close.";
this.MSG_BAD_SOUND_FLAG = "Bad value for -sound.";
this.MSG_BAD_INCREMENT = "Bad value for -increment. Must be between 1 and 100, inclusive.";
this.MSG_COMP_NOT_FOUND = "No comp was found with the given name.";
this.MSG_RQINDEX_NOT_FOUND = "No render queue item was found with the given index.";
this.MSG_AE_RUNTIME = "Runtime error in After Effects.";
this.MSG_ADDING_TO_RQ = "PROGRESS: Adding specified comp to Render Queue";
this.MSG_NEEDS_OUTPUT = "Specified render queue item needs output file but none provided.";
this.MSG_RS_TEMPLATE_NOT_FOUND = "No render settings template was found with the given name.";
this.MSG_OM_TEMPLATE_NOT_FOUND = "No output module template was found with the given name.";
this.MSG_CAN_NOT_OPEN_SOCKET = "Can not open socket.";
this.MSG_NO_COMP_YES_TEMPLATE = "WARNING: -RStemplate argument ignored since no -comp or -rqindex provided.";
this.MSG_NO_COMP_YES_OMTEMPLATE = "WARNING: -OMtemplate argument ignored since no -comp or -rqindex provided.";
this.MSG_NO_COMP_YES_OUTPUT = "WARNING: -output argument ignored since no -comp or -rqindex provided.";
this.MSG_NO_COMP_YES_START_OR_END = "WARNING: -s and/or -e arguments ignored since no -comp or -rqindex provided.";
this.MSG_NO_COMP_YES_INCREMENT = "WARNING: -i argument ignored since no -comp or -rqindex provided.";
this.MSG_SKIPPING_WILL_CONTINUE = "INFO: Skipping render queue item with correct comp name but marked to continue from a partly complete render.";
this.MSG_RENDER_ABORTED = "INFO: Render aborted.";
// These three don't get the prefix printed since they are not exit messages
this.MSG_LOG_DIR_NO_EXISTS = "aerender ERROR: Directory specified for log file does not exist: ";
this.MSG_LOG_DIR_NOT_A_DIR = "aerender ERROR: Directory specified for log file is a file, not a directory: ";
this.MSG_LOG_CAN_NOT_OPEN = "aerender ERROR: Can not open log file. Try checking write protection of directory: ";
//
// Variables for rendering
//
this.log_file = null;
this.has_user_log_file = false;
this.is_verbose_mode = true;
this.saved_sound_setting = null;
this.my_sound_setting = null;
// [2] define all the functions used by this class
//
// Report an error. This writes errors to the log file, if present.
// This is called from the context of the application, so we
// need to precede variable names with gAECommandLineRenderer
//
function checkParentDied()
{
var result = false;
if(gAECommandLineRenderer.log_file instanceof Socket) {
if(! gAECommandLineRenderer.log_file.connected) {
app.project.renderQueue.stopRendering();
result = true;
}
}
return result;
}
function my_onError(error_string, severity_string)
{
// This method is called with a variety of types of messages.
// The severity_string tells us what kind.
// Choices are:
// NAKED, INFO, WARNING, PROBLEM, FATAL, PROGRESS, and DEBUG
// Two of these, PROBLEM and FATAL, are errors that should cause us to change
// the exit code:
checkParentDied();
if (severity_string == "PROBLEM" || severity_string == "FATAL") {
// These two errors cause us to change the exit code.
// We don't write an error or throw here, because we got here as part of a thrown
// error already, and the message will be printed as part of the catch.
gAECommandLineRenderer.SetExitCode(gAECommandLineRenderer.EXIT_AE_RUNTIME);
} else {
// PROBLEM and FATAL will throw exceptions, and so will be logged to the file
// when we catch the exception.
// All other errors (NAKED, INFO, WARNING, PROGRESS, and DEBUG) will not
// throw exceptions. So we log them to the file right here:
if (gAECommandLineRenderer.is_verbose_mode) {
if (gAECommandLineRenderer.log_file != null) {
if (severity_string == "NAKED") {
// everybody is confused by this category. Just use INFO instead.
gAECommandLineRenderer.log_file.writeln("INFO:" + error_string);
} else {
gAECommandLineRenderer.log_file.writeln(severity_string + ":" + error_string);
}
}
}
}
// call the error handler that was in place before we started rendering.
if (gAECommandLineRenderer.oldErrorHandler) {
gAECommandLineRenderer.oldErrorHandler(error_string,severity_string);
}
}
// Report an error and throw an exception.
// Causes the script to exit.
function my_SetExitCodeAndThrowException(code, message)
{
this.SetExitCode(code);
throw (this.EXIT_MSG_PREFIX[code] + message);
}
// Report an error. This establishes exitCodes for reporting errors from AfterFX.
function my_SetExitCode(code)
{
// Some codes are set differently depending on whether we have a custom user
// log file. Check for these and use the alternate if appropriate.
var real_code = code;
if (gAECommandLineRenderer.has_user_log_file) {
switch (real_code) {
case gAECommandLineRenderer.EXIT_SYNTAX_ERROR:
real_code = gAECommandLineRenderer.EXIT_SYNTAX_ERROR_USER_LOG;
break;
case gAECommandLineRenderer.EXIT_OTHER_SCRIPTING_ERROR:
real_code = gAECommandLineRenderer.EXIT_OTHER_SCRIPTING_ERROR_USER_LOG;
break;
case gAECommandLineRenderer.EXIT_AERENDER_RUNTIME:
real_code = gAECommandLineRenderer.EXIT_AERENDER_RUNTIME_USER_LOG;
break;
case gAECommandLineRenderer.EXIT_AE_RUNTIME:
real_code = gAECommandLineRenderer.EXIT_AE_RUNTIME_USER_LOG;
break;
}
}
// Always keep the first error. So only set if the exitCode is still EXIT_OK.
if (app.exitCode == gAECommandLineRenderer.EXIT_OK) {
app.exitCode = real_code;
}
}
// Arguments may be enclosed in quotes. This
// will remove them and return the result.
function my_StripAnyEnclosingQuotes(inString)
{
var result = inString;
if (inString &&
inString.charAt(0) == '"' &&
inString.charAt(inString.length-1) == '"') {
result = inString.substring(1,inString.length-1);
}
return result;
}
// Make sure the value is there, and returns it, stripping away any enclosing quotes.
//
function my_GetValueForFlag(arg_num, the_flag)
{
if (!this.inArgs[arg_num]) {
this.SetExitCodeAndThrowException(this.EXIT_SYNTAX_ERROR, (this.MSG_UNDEFINED_VALUE_FOR_FLAG + the_flag));
}
return this.StripAnyEnclosingQuotes(this.inArgs[arg_num]);
}
// Parse the parameter.
// Return the number of arguments used in parsing the parameter.
function my_ParseParamStartingAt(arg_num)
{
if (!this.inArgs[arg_num]) {
this.SetExitCodeAndThrowException(this.EXIT_AERENDER_RUNTIME, this.MSG_TRIED_TO_PARSE_UNDEFINED);
}
var num_args_parsed = 0;
// Check for a valid flag:
var my_flag = this.inArgs[arg_num];
if (my_flag == "-port") {
// -port is used by aerender to specify a port address for a socket.
//
// Note: this value is sought/parsed earlier, in the SetupDefaultLog method.
// We can just ignore here.
var dummy = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-project") {
this.in_project_path = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-teamproject") {
this.in_teamproject_name = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-comp") {
this.in_comp_name = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-rqindex") {
this.in_rq_index = parseInt(this.GetValueForFlag(arg_num+1,my_flag));
num_args_parsed = 2;
}
if (my_flag == "-RStemplate") {
this.in_RStemplate = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-OMtemplate") {
this.in_OMtemplate = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-output") {
this.in_output_path = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-log") {
this.in_logfile_path = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-s") {
this.in_start_frame = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-e") {
this.in_end_frame = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-i") {
this.in_increment = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-mem_usage") {
this.in_image_cache_percent = this.GetValueForFlag(arg_num+1,my_flag);
this.in_max_mem_percent = this.GetValueForFlag(arg_num+2,my_flag);
num_args_parsed = 3;
}
if (my_flag == "-v") {
this.in_verbose_flag = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-close") {
this.in_close_flag = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-sound") {
this.in_sound_flag = this.GetValueForFlag(arg_num+1,my_flag);
num_args_parsed = 2;
}
if (my_flag == "-doSavePrefsOnQuit") {
// The effect of this flag will be taken into account when we
// exit the app. See comment in the "finally" block.
// All we do here is increment the num_args_parsed count.
num_args_parsed = 1;
}
if (my_flag == "-continueOnMissingFootage") {
this.in_stop_on_missing_frame = false;
num_args_parsed = 1;
}
if (num_args_parsed == 0) {
this.SetExitCodeAndThrowException(this.EXIT_SYNTAX_ERROR, (this.MSG_BAD_FLAG + my_flag));
}
return num_args_parsed;
}
// This parses the inArgs array. Assumes
// the array has already been filled.
function my_ParseInArgs()
{
// First, undefine all the inputs we're potentially looking for
this.in_project_path = null;
this.in_teamproject_name = null;
this.in_comp_name = null;
this.in_rq_index = null;
this.in_RStemplate = null;
this.in_OMtemplate = null;
this.in_output_path = null;
this.in_logfile_path = null;
this.in_start_frame = null;
this.in_end_frame = null;
this.in_increment = null;
this.in_image_cache_percent = null;
this.in_max_mem_percent = null;
this.in_verbose_flag = null;
this.in_close_flag = null;
this.in_sound_flag = null;
// Special case: check if any argument is "-help"
for (var i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?