Serge
Serge

Reputation: 1601

SIGSEGV from ffmpeg on Amazon Lambda

Trying out Amazon Lambda / nodejs 8. My goal is to launch ffmpeg, generate a short clip and upload it to S3 bucket.

I created the function following the image resize tutorial. Edited the code to get output from simple linux commands like ls or cat /proc/cpuinfo - all works.

Now, added the ffmpeg binary for i686 - ffmpeg static build by JohnVan Sickle (thanks!). Changed the code to launch simple ffmpeg command that is supposed to create sa 2-seconds small video clip.

That fails, according to logs, with the signal SIGSEGV returned to the "close" event handler of child_process.spawn()

As far as I understand, this could be caused by the ffmpeg binary incompatibility with the static build. Or by some mistake in my code.

Several npm modules rely on the static builds from johnvansickle.com/ffmpeg and there are no such issues filed on their github. Maybe there's some other mistake I made?

Should I compile ffmpeg myself under Amazon Linux AMI amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2 which is under the hood of AWS Lambda?


upd. Launched EC2 t2.micro instance from the same AMI, downloaded the same ffmpeg static build, and it works just fine from the command line. Now I doubt that it is a compilation issue.

Also tried copying ffmpeg executable to /tmp/ffmpeg and chmod 755 just to make sure. Running simple ffmpeg --help command via child_process.execSync() returns "Error: Command failed: /tmp/ffmpeg --help"


const join = require('path').join;
const tmpdir = require('os').tmpdir;
const process = require('process');
const fs = require('fs');
const spawn = require('child_process').spawn;
const exec = require('child_process').exec;

const async = require('async');
const AWS = require('aws-sdk');
const util = require('util');

process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'];


const tempDir = process.env['TEMP'] || tmpdir();
const filename = join(tempDir, 'test.mp4');
const s3 = new AWS.S3();


exports.handler = function(event, context, callback) {
  var dstBucket = srcBucket + "resized";
  var dstKey  = "render-test.mp4";

  async.waterfall([
    function transform(next) {
      var args = [
        '-filter_complex',
        '"testsrc=r=25:s=640x480:d=3"',
        '-an',
        '-y',
        '-hide_banner',
        '-c:v', 'libx264',
        filename,
      ];

      console.log("Will launch ffmpeg");
      const childProcess = spawn('ffmpeg', args);

      childProcess.on('close', function(e) {
        console.log('ffmpeg close event: ' + JSON.stringify(arguments));
        next();
      });

      console.log("After launched ffmpeg");
    },

    function upload(next) {
      ...
    }
  ], function (err) {
    ...
  });
};

Upvotes: 3

Views: 1881

Answers (3)

Ryan
Ryan

Reputation: 111

Now, added the ffmpeg binary for i686

This is the 32-bit build. If you use the amd64 binary, it works fine. I just ran into the same issue with ffmpeg 7.0.1 on Amazon Linux 2023 (Node 20 runtime) and realized I had accidentally downloaded the i686 build as well. It immediately segfaults every time you run it, even with just -h or -version. I updated my lambda layer build with the 64-bit build and then everything in my lambda works fine.

Upvotes: 0

Lioness
Lioness

Reputation: 500

Instead of building a binary on your own, you can use ffmpeg-lambda-layer ( https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:145266761615:applications~ffmpeg-lambda-layer)

Deploy it and add it as a layer to your function. Within your function the binary can be accessed as '/opt/bin/ffmpeg'.

Upvotes: 1

Serge
Serge

Reputation: 1601

Fixed. Despite the misleading fact that static build of ffmpeg from JohnVanSickle.com does run on Amazon EC2 instance of the AMI, mentioned in Lambda environment, same binary fails to execute under AWS Lambda.

I compiled ffmpeg on the AWS EC2 t2.micro instance of the same AMI using markus-perl/ffmpeg-build-script. It also surprised me with an error of aom codec version. Changed one line in the script to disable the aom codec and ffmpeg finally has compiled. Took a couple of hours on the weak t2.micro instance.

The resulting ffmpeg binary is ~10Mb lighter than the static build mentioned above and runs on AWS Lambda just fine!

Hope this will help someone.

Upvotes: 4

Related Questions