Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal for post-rendering tasks #68

Closed
joshea0 opened this issue May 25, 2018 · 5 comments
Closed

Proposal for post-rendering tasks #68

joshea0 opened this issue May 25, 2018 · 5 comments

Comments

@joshea0
Copy link
Contributor

joshea0 commented May 25, 2018

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?

@inlife
Copy link
Owner

inlife commented May 25, 2018

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.

@Laboltus
Copy link

Laboltus commented Jul 1, 2018

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

@inlife
Copy link
Owner

inlife commented Oct 29, 2018

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

@inlife
Copy link
Owner

inlife commented Jan 21, 2019

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' }
                }
            }
        ]
    }
}

@inlife inlife added this to the v1.0.0 milestone Jan 26, 2019
@inlife inlife removed the planned label Jan 26, 2019
@inlife
Copy link
Owner

inlife commented Feb 3, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants