您当前的位置: 首页 > 

插件开发

暂无认证

  • 6浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

AfterEffect插件--常规功能开发--命令行渲染--js脚本开发--AE插件

插件开发 发布时间:2022-03-03 09:38:09 ,浏览量:6

  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             
关注
打赏
1665481431
查看更多评论
0.1277s