eugeneware / gifencoder

Server side animated gif generation for node.js
Other
472 stars 49 forks source link

Using Gifencoder inside of Lambda Function #20

Closed LoganArnett closed 6 years ago

LoganArnett commented 6 years ago

Curious to see if anyone has been able to implement this. Currently I have a setup that works on the first gif encoding but it fails after that every single time. Not sure if this is a Lambda issue or a Gifencoder issue.

Any help would be greatly appreciated

heikkipora commented 6 years ago

Would you like to post a code + configuration sample?

msholty-fd commented 6 years ago

@LoganArnett I just got this working on Amazon Lambda. I essentially used the code in https://github.com/Nooshu/node-countdown-gif, but had to make sure I built it within a docker image that simulates an ec2 environment (or just ssh into an ec2 instance to build). If you have bitbucket and bitbucket pipelines enabled, you can just configure in your bitbucket-pipelines.yml like this: image: lambci/lambda:build-nodejs6.10

I had to mess with the code in the repo a bit to make this work, something along the lines of this in my index.js:

exports.handler = (event, context) => {
  const CountdownGenerator = require('./countdown-generator');
  let { time, width, height, color, bg, frames } = event.queryStringParameters;

  if(!time){
      throw Error('Time parameter is required.');
  }

  CountdownGenerator.init(time, width, height, color, bg, frames, (body) => {
    context.done(null, {
        statusCode: 200,
        headers: {
          'Content-Type': 'image/gif',
          'Content-Length': body.length,
          'Accept-Ranges': 'bytes',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': '*',
          'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key',
        },
        body: body.toString('base64'),
        isBase64Encoded: true,
    });
  });
};

Within the CountdownGenerator code, I changed it from writing to a file (unnecessary for our needs) to just returning the buffer, like this:

enc.createReadStream().pipe(concat((data) => {
  typeof cb === 'function' && cb(data);
}));

concat comes from the npm package 'concat-stream'.

Make sure you have these dependencies installed before running npm install or it ain't gonna work:

          - yum install -y yum-plugin-ovl ; yum clean all
          - yum install cairo-devel libjpeg-turbo-devel giflib-devel -y ; yum clean all

Yes, the ; yum clean all is just weird but it didn't work without it.

If your implementation fails after the first one, make sure you aren't doing anything outside of the index.js exports.handler function. Lambda functions are meant to be stateless.