【问题标题】:After Effects: How to launch an external process and detach itAfter Effects:如何启动外部进程并将其分离
【发布时间】:2020-01-26 14:59:28
【问题描述】:

我有一个 After Effects 脚本问题,但我不确定它是否会通过 AE 知识得到解决,也许更多的是通过独立开发。

我想从 After Effects 启动一个外部进程,实际上我想使用 After Effects 提供的 aerender.exe 启动打开的 AEP 文件的渲染,同时保持其可用。

var projectFile = app.project.file;
var aeRender = "C:\\Program Files\\Adobe\\Adobe After Effects CC 2018\\Support Files\\aerender.exe";
var myCommand = "-project" + " " + projectFile.fsName;
system.callSystem("cmd /c \""+aeRender+"\"" + " " + myCommand);

所以我编写了这个简单的 JSX 代码,它可以正常工作,它可以正确渲染场景渲染队列。 但 After Effects 处于冻结状态,它会等待进程结束。 我希望它保持可用。

所以我尝试编写一个 .cmd 文件并使用 AE system.callSystem 启动它,但我遇到了同样的问题, 我试图通过一个 .exe 文件(使用 pyInstaller 从一个简单的 python 编译),同样的问题:

import sys
import subprocess

arg = sys.argv
pythonadress = arg[0]
aeRender = arg[1]
projectFileFSname = arg[2]

myCommand = "-project" + " " +projectFileFSname
callSystem = "cmd /c \""+aeRender +"\"" + " " + myCommand
subprocess.run(callSystem)

我什至尝试使用“cmd /c start”,但似乎更糟,因为 After Effects 在该过程完成后继续冻结。

有没有办法让 AE 相信这个过程已经完成,而实际上它还没有完成?

任何帮助将不胜感激!

【问题讨论】:

    标签: python cmd jsx after-effects


    【解决方案1】:

    system.callSystem() 将冻结脚本的执行,因此您可以动态创建一个 .bat 文件并使用.execute() 运行它。

    这是一个示例 .js:

    var path = {
      "join": function ()
      {
        if (arguments.length === 0) return null;
    
        var args = [];
    
        for (var i = 0, iLen = arguments.length; i < iLen; i++)
        {
          args.push(arguments[i]);
        }
    
        return args.join(String($.os.toLowerCase().indexOf('win') > -1 ? '\\' : '/'));
      }
    };
    
    if (app.project.file !== null && app.project.renderQueue.numItems > 0)
    {
      var
      // aeRenderPath = path.join(new File($._ADBE_LIBS_CORE.getHostAppPathViaBridgeTalk()).parent.fsName, 'aerender.exe'), // works only in CC 2018 and earlier
      aeRenderPath = path.join(new File(BridgeTalk.getAppPath(BridgeTalk.appName)).parent.fsName, 'aerender.exe'),
      batFile = new File(path.join(new File($.fileName).parent.fsName, 'render.bat')),
      batFileContent = [
        '"' + aeRenderPath + '"',
        "-project",
        '"' + app.project.file.fsName + '"'
      ];
    
      batFile.open('w', undefined, undefined);
      batFile.encoding = 'UTF-8';
      batFile.lineFeed = 'Unix';
      batFile.write(batFileContent.join(' '));
      batFile.close();
    
      // system.callSystem('explorer ' + batFile.fsName);
      batFile.execute();
    
      $.sleep(1000); // Delay the script so that the .bat file can be executed before it's being deleted
      batFile.remove();
    }
    

    当然,您可以进一步开发它并使其与 OSX 兼容,为其添加更多功能等,但这是主要思想。

    这是一个包含所有 aerender 选项的列表(如果您还不知道它们):https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html

    顺便说一句,$._ADBE_LIBS_CORE.getHostAppPathViaBridgeTalk() 将为您提供“AfterFX.exe”文件路径,因此您可以通过这种方式更轻松地获得“aerender.exe”路径。

    编辑:$._ADBE_LIBS_CORE 已在 CC2019 中删除,因此您可以直接使用 BridgeTalk 代替 CC 2019 及更高版本。

    【讨论】:

    • 非常感谢 Alex 的详细回答!我只是偶然发现了另一种使用system.callSystem("explorer "+batFile.fsName) 的方法
    • 是的,它和execute() 完全一样。
    • 实际上似乎system.callSystem("explorer " + batFile.fsName) 的渲染过程开始得更慢。我不太确定为什么,但execute() 可能是更好的方法。我还使用 Node JS 中的 path 模块的 path.join 实现编辑了 javascript 示例,因此您可以更优雅地构建路径。
    • 不错的精度!我没有注意到这种延迟,但渲染通常很长,因此进程启动持续时间变得不那么重要了。
    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多