Пробую разобраться с Amazon Lamda под nodejs и запустить там ffmpeg, чтобы создать короткий тестовый ролик.
Функцию создал, запускается. Со стандартными командами типа
ls
или
cat /proc/cpuinfo
отрабатывает.
В package вложил статический билд ffmpeg под i686
отсюда. При его запуске через
child_process.spawn() он вылетает с сигналом
SIGSEGV
В сети большого шума по этому поводу не нашёл. Пакет
@ffmpeg-installer/ffmpeg, который рекомендуют в tutorial'ах по разворачиванию ffmpeg в AWS Lambda, использует бинарники оттуда же.
Взял этот
туториал по изменению размера картинок, он у меня отработал как надо, уменьшенную картинку в бакете создал. Изменил слегка код и подсунул бинарник ffmpeg.
Мой index.jsconst 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