Nexrender: Proposal for post-rendering tasks

Created on 25 May 2018  路  5Comments  路  Source: inlife/nexrender

After reading through #26 and comments from @inlife on #61 I have started thinking about how to support post-render tasks in a way that is useful to many users while not being overly complex.

I am starting a new issue because I'm taking a different direction from what was being discussed in #26 and I don't want to clutter that too much. If you'd prefer me post this in there instead, just let me know and I'll move it over!

Design decisions

For context, here are the major points I considered while thinking about this feature proposal.

  1. Should we support generic post-render tasks?

    • i.e., let people execute any arbitrary node code

    • this gives most flexibility to accomplish whatever you want



      • but is probably hardest to implement correctly


      • and requires users to be able to write own code for the tasks



  2. Should we support a predefined set of post-render tasks, which can be optionally used via configuration?

    • examples: upload video: (S3, youtube, ftp), email the video, trigger a webhook

    • this gives users the power to use these features without having to write them

    • would allow us to iterate one type of task at a time and add more whenever we see the need

As I thought about it more, I came to the conclusion that the 2nd approach may make the most sense. Although we will not be able to support every scenario and use cases, I think we can support a few of the most common scenarios that will satisfy the needs of a large percentage of users.

My conclusion relies on the assumption that the vast majority of use cases for post-render tasks center around 2 needs:

  1. Upload / Send the video somewhere
  2. Trigger some action / send some notification

If anyone has use cases that fall outside of these, please let me know! I want to make this feature work for as many users as possible, so any input would be welcome.

Design proposal: predefined set of post-render tasks - used optionally via configuration

For uploads, I think a handful of targets could work for most scenarios: S3, YouTube, and maybe FTP.
For triggering actions/notifications, we can simply use webhooks as suggested in #26.

All of this can be configured by adding fields to the project model - that way users only need to be concerned about the task(s) they need.

Add a new optional key to the project model: "post_render_tasks"

{
    "template": "template1.aepx",
    "composition": "base",
    "assets": assets,
    "post_render_tasks": {
        ...
    }
}

If "post_render_tasks" is present on the project model, we inspect it to see which tasks are configured.
Example - Upload to S3:

{
    "template": "template1.aepx",
    "composition": "base",
    "assets": assets,
    "post_render_tasks": {
        "upload": {
          "s3": {
            "bucket": "my-awesome-bucket",
          }
        }
    }
}

Since upload is present in post_render_tasks, we start the upload task. The upload task looks at the keys inside of upload and sees s3, so it triggers an upload to S3 using the provided parameters.

This structure allows us to have multiple post-render tasks for a given job. For example, upload to youtube and S3:

{
    "template": "template1.aepx",
    "composition": "base",
    "assets": assets,
    "post_render_tasks": {
        "upload": {
          "s3": {
            "bucket": "my-awesome-bucket",
          },
          "youtube": {
            // youtube API and other config goes here
          }
        }
    }
}

Or upload to S3 and trigger a webhook:

{
    "template": "template1.aepx",
    "composition": "base",
    "assets": assets,
    "post_render_tasks": {
        "upload": {
          "s3": {
            "bucket": "my-awesome-bucket",
          },
        },
        "webhook": {
          "failed": "https://example.com/api/v1/render-callback",
          "finished": "https://example.com/api/v1/render-callback"
        }
    }
}

Doing it this way provides flexibility for users - they can opt in to use one task, multiple, or none as fits their needs. It is simple because user will not have to write any additional code, they will just have to specify configuration in the project JSON.

It also provides flexibility for development, because we could incrementally add support for additional tasks if we see the need. For example, we could implement a feature for uploading to S3. Then later we could enhance and add support for uploading to youtube, etc.

@inlife what do you think?

feature

Most helpful comment

hello everyone,
after recent research of the newly discovered methods of interaction with ae project
wanted to publish my latest design iteration of the job (formally project) document:

{
    template: {
        provider: 'http',
        src: 'http://fooo.bar/template.aep',

        composition: 'main',
        frameStart: 0,
        frameEnd: 542,

        outputModule: 'mycustom',
        outputExt: 'avi',
    },
    assets: [
        {
            type: 'image',
            provider: 'http',
            src: 'http://fooo.bar/image.jpg',
            layer: 'logo.jpg',
        },
        {
            type: 'audio',
            provider: 'aws-s3',
            src: 'http://fooo.bar/song.mp3',
            layer: 'audio.mp3',
        },
        {
            type: 'script',
            provider: 'http',
            src: 'http://fooo.bar/ae-script.jsx',
        },
    ],
    actions: {
        prerender: [
            { module: '@inlife/crop-images' },
        ],
        postrender: [
            {
                // upload original
                module: '@nexrender/action-upload',
                options: {
                    provider: 'aws-s3',
                    credentials: { key: 'XXXX-XX111XXX-XXXX' },
                    entry: {
                        darwin: 'result.mov',
                        win32: 'result.avi',
                    },
                }
            },
            {
                module: '@nexrender/action-ffmpeg',
                options: {
                    entry: {
                        darwin: 'result.mov',
                        win32: 'result.avi',
                    },
                    output: 'result.mp4',
                }
            },
            {
                // upload processed
                module: '@nexrender/action-upload',
                options: {
                    provider: 'youtube',
                    credentials: { key: 'XXXX-XX111XXX-XXXX' },
                    entry: 'result.mp4',
                }
            },
            {
                module: '@nexrender/action-webhook',
                options: {
                    success: 'http://example.com/api/render-callback',
                    failure: 'http://example.com/api/render-callback',
                    header: { 'Authorization: sometoken' }
                }
            }
        ]
    }
}

All 5 comments

I like the 2nd option better too. They most likely will be part of the @nexrender/core in the 1.0, sharing the dependencies with download task too (ftp/s3/http).

Also, 1st option always can be achieved by using the @nexrender/core programmatically, adding .then after the render and doing the manual custom work, so pretty much all seems to fit together quite nicely

The only thing I would want to improve in this concept is the name of the thing in the Job(formerly Project) object. However I cant think of anything else, except "post_render_tasks" :/

Overall everything seems quite nice, i like the design.

AE removed mp4 support for output module, so one of common post render actions is video encoding (by ffmpeg for example).

i just figured out a nice way to add multiple many "drivers" for both downloading assets and converting/uploading results (actions), while keeping the core itself very slim

those additional custom things like ftp, s3, youtube, ffmpeg (for mp4) can be additional peer dependencies, which you would specify when you are installing the nexrender render node (agent) with whatever combination you wish to, like:

$ npm instal @nexrender/core @nexrender/aws-s3 @nexrender/ffmpeg --save

or

$ npm install @nexrender/agent @nexrender/ftp -g

P.S. the new naming system that im still working out:

  • job - (old name is project) renamed to remove confusion between ae projects and nexrender projects
  • agent - (old name is rendernode), a binary responsible for communicating with server via api and rendering jobs via core
  • server - a binary, an API server that holds the information and schedules rendering
  • core - the programatic version of a function that can render particular job
  • api - the programatic interface that can be used on web/nodejs for communication with the server

hello everyone,
after recent research of the newly discovered methods of interaction with ae project
wanted to publish my latest design iteration of the job (formally project) document:

{
    template: {
        provider: 'http',
        src: 'http://fooo.bar/template.aep',

        composition: 'main',
        frameStart: 0,
        frameEnd: 542,

        outputModule: 'mycustom',
        outputExt: 'avi',
    },
    assets: [
        {
            type: 'image',
            provider: 'http',
            src: 'http://fooo.bar/image.jpg',
            layer: 'logo.jpg',
        },
        {
            type: 'audio',
            provider: 'aws-s3',
            src: 'http://fooo.bar/song.mp3',
            layer: 'audio.mp3',
        },
        {
            type: 'script',
            provider: 'http',
            src: 'http://fooo.bar/ae-script.jsx',
        },
    ],
    actions: {
        prerender: [
            { module: '@inlife/crop-images' },
        ],
        postrender: [
            {
                // upload original
                module: '@nexrender/action-upload',
                options: {
                    provider: 'aws-s3',
                    credentials: { key: 'XXXX-XX111XXX-XXXX' },
                    entry: {
                        darwin: 'result.mov',
                        win32: 'result.avi',
                    },
                }
            },
            {
                module: '@nexrender/action-ffmpeg',
                options: {
                    entry: {
                        darwin: 'result.mov',
                        win32: 'result.avi',
                    },
                    output: 'result.mp4',
                }
            },
            {
                // upload processed
                module: '@nexrender/action-upload',
                options: {
                    provider: 'youtube',
                    credentials: { key: 'XXXX-XX111XXX-XXXX' },
                    entry: 'result.mp4',
                }
            },
            {
                module: '@nexrender/action-webhook',
                options: {
                    success: 'http://example.com/api/render-callback',
                    failure: 'http://example.com/api/render-callback',
                    header: { 'Authorization: sometoken' }
                }
            }
        ]
    }
}

@joshea0 the postrendering tasks proposition has been successfully implemented and published as pre-release. Closing the issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Marcuzzz picture Marcuzzz  路  4Comments

bluematter picture bluematter  路  5Comments

JamesBotterill picture JamesBotterill  路  4Comments

dsrts picture dsrts  路  3Comments

panchenkoprog picture panchenkoprog  路  5Comments