Почему ffmpeg на Amazon Lambda вылетает с ошибкой SIGSEGV?

Пробую разобраться с Amazon Lamda под nodejs и запустить там ffmpeg, чтобы создать короткий тестовый ролик.

Функцию создал, запускается. Со стандартными командами типа ls или cat /proc/cpuinfo отрабатывает.

В package вложил статический билд ffmpeg под i686 отсюда. При его запуске через child_process.spawn() он вылетает с сигналом SIGSEGV

В сети большого шума по этому поводу не нашёл. Пакет @ffmpeg-installer/ffmpeg, который рекомендуют в tutorial'ах по разворачиванию ffmpeg в AWS Lambda, использует бинарники оттуда же.

Взял этот туториал по изменению размера картинок, он у меня отработал как надо, уменьшенную картинку в бакете создал. Изменил слегка код и подсунул бинарник ffmpeg.
Мой index.js
const join = require('path').join;
const tmpdir = require('os').tmpdir;
const process = require('process');

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

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 s3 = new AWS.S3();
 

exports.handler = function(event, context, callback) {
  // Read options from the event.
  console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
  var srcBucket = event.Records[0].s3.bucket.name;
  // Object key may have spaces or unicode non-ASCII characters.
  var srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));  
  var dstBucket = srcBucket + "resized";
  var dstKey  = "render-test.mp4";

  // Sanity check: validate that source and destination are different buckets.
  if (srcBucket == dstBucket) {
    callback("Source and destination buckets are the same.");
    return;
  }


  // Download the image from S3, transform, and upload to a different S3 bucket.
  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) {
	    
	    next();

			var fileStream = fs.createReadStream(filename);
			fileStream.on('error', function (err) {
				if (err) { throw err; }
			});  
			fileStream.on('open', function () {

				s3.putObject(
					{
					  Bucket: dstBucket,
					  Key: dstKey,
					  Body: fileStream,
	          ContentType: 'video/mp4',
					},
					next
				);

			});
    }
  ], function (err) {
      if (err) {
        console.error(
          'Unable to resize ' + srcBucket + '/' + srcKey +
          ' and upload to ' + dstBucket + '/' + dstKey +
          ' due to an error: ' + err
        );
      } else {
        console.log(
          'Successfully rendered ' + dstBucket + '/' + dstKey
        );
      }

      callback(null, "message");
    }
  );
};


По событию close запущенного процесса приходит { "0": null, "1": "SIGSEGV" }

Значит ли это, что надо как-то скомпилировать ffmpeg самому под AMI amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2?

Upd. Запустил этот же статичный билд ffmpeg без проблем на EC2 инстансе из того же AMI. Т.е. вероятно, дело не в компиляции. Пробовал, как где-то писали, переносить сам ffmpeg в папку /tmp уже на Lambde и еще раз ставить файлу chmod 400. Убеждался, что он именно там и с правильными пермишшнами через ls -lA /tmp/ffmpeg на ламбде.

Не срабатывает даже простая команда ffmpeg --help через child_process.execSync() возвращает Error: Command failed: /tmp/ffmpeg --help
  • Вопрос задан
  • 186 просмотров
Решения вопроса 1
sergiks
@sergiks Автор вопроса
♬♬
В итоге победил компиляцией ffmpeg'а на AWS EC2 t2.micro из образа, на котором работает Lambda.

Статический билд с сайта JohnVanSickle хоть и запускается на такой машине, на Lambda почему-то упорно падает с ошибкой. Поэтому увы, только компилировать.

Использовал скрипт markus-perl/ffmpeg-build-script. Но и с ним не гладко: компиляция падала с ошибкой кодека aom / av1, который упорно показывал свою версию как 0.1.0, а не требуемую 1.0.0. Создал тикет. Эта мелочь вылечилась отказом от кодека aom - в 376-й строке скрипта build-ffmpeg заменил --enable-libaom на --disable-libaom

Сборка на слабеньком t2.micro заняла долгие несколько часов, но итоговый бинарник заработал в AWS Lambda!
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы