Launchd process using aerender exits early

launchd

I'm trying to run aerender (After Effects' command-line renderer) via launchd to render a video on a timed interval. The command works fine in Terminal. In launchd – even when I use screen -d -m ... – it always exits early. Here's my setup.

Skip to bottom for things I've already tried.

plist for launchd:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.home.VideoGenerator</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/home/Developer/VideoGenerator/exec/render.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>StartInterval</key>
    <integer>300</integer>
    <key>StandardErrorPath</key>
    <string>/var/log/com.home.VideoGenerator.err.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/com.home.VideoGenerator.out.log</string>
</dict>
</plist>

render.sh script:

#!/bin/bash
/Applications/Adobe\ After\ Effects\ CC\ 2018/aerender -project /Users/home/Developer/VideoGenerator/resource/video.aep -comp ExportMe -output /Users/home/Developer/VideoGenerator/output/video.mov -OMtemplate Output

Output:

Here is what normal output looks like, when I run ./render.sh from the command line:

aerender version 15.0.1x73
PROGRESS: Launching After Effects...
PROGRESS: ...After Effects successfully launched
PROGRESS: Adding specified comp to Render Queue
PROGRESS:  4/2/18 8:41:57 AM PDT: Starting composition ExportMe.
...

This is truncated. It also outputs composition settings and render progress, always successful. Nothing useful for this purpose.

Here's the logged output when I run it from launchd:

aerender version 15.0.1x73
PROGRESS: Launching After Effects...
PROGRESS: ...After Effects successfully launched

And that's it. (In reality I'm running this in a context where I can log the exit code and it's always 0. For this purpose I have drastically simplified the project to what you see here, and it still doesn't run).

Things I've tried:

  • Set KeepAlive to true in the plist
    • This just relaunches the process after it exits
  • Add /dev/null as the StandardInPath in the plist (as per this post)
    • Still exits early
  • Add -i and -c to the beginning of ProgramArguments (from the same post as above)
    • Command doesn't run
  • Set AbandonProcessGroup to true in the plist
    • Still exits early
  • Append & to put the task in the background
    • Silences output
  • Launch aerender with screen -d -m ...
    • Using the -L flag and checking the log, the output is the same; it stops after aerender launches After Effects and then exits before rendering.

Running ps aux | grep aerender shows over 20 processes running (probably from all the times I've executed the script), most of them aerendercore. But no output, no video.

What am I doing wrong?

Best Answer

As you have discovered, aerender requires access to the Window Manager. You could try putting your job into ~/Library/LaunchAgents which runs in the user session, or use another scheduling tool.

launchd Alternative

If a user is logged in or even fast user switched out, you could use a tool like Power Manager to run your Window Manager requiring scripts and applications.

Power Manager on macOS

I wrote Power Manager, so feel free to ask technical questions. I suggest it in this case, because what you want is possible thanks to the tool's architecture.

per-user and Window Manager Access

Power Manager runs a per-user process called pmuser. This process allows you to run scheduled scripts and tasks as a specified user or as the Active User – the front most user.

Within your Power Manager event, look for the Environment pop-up. This controls which user environment your shell script will run in. Active User is the front most graphical user session and it has access to the Window Manager.

Power Manager scripting within the graphical user session