it-roy-ru.com

AWS Lambda делает видео миниатюры

Я хочу сделать миниатюры из видео, загруженных на S3, я знаю, как сделать это с Node.js и ffmpeg. 

Согласно это сообщение на форуме я могу добавить библиотеки:

ImageMagick - единственная внешняя библиотека, которая в настоящее время предоставляется по умолчанию, но вы можете включить любые дополнительные зависимости в Zip файл, который вы предоставляете при создании лямбда-функции. Обратите внимание, что если это является нативной библиотекой или исполняемым файлом, вам нужно убедиться, что это работает на Amazon Linux.

Но как я могу поместить статический двоичный файл ffmpeg на лямбда-aws?

И как я могу вызвать из Node.js этот статический двоичный файл (ffmpeg) с помощью AWS Lambda?

Я новичок в Amazon AWS и Linux

Может кто-нибудь мне помочь?

21
Jesus

Процесс, описанный Naveen, является правильным, но он затеняет детали, которые могут быть довольно болезненными - включая двоичный файл ffmpeg в Zip и доступ к нему в вашей лямбда-функции.

Я только что прошел через это, это пошло так:

  1. Включите статический бинарный файл ffmpeg в ваш zamb-пакет лямбда-функций (у меня есть задание gulp, чтобы копировать его в /dist каждый раз при сборке)
  2. Когда ваша функция вызывается, переместите двоичный файл в каталог /tmp/ и chmod, чтобы получить доступ (Обновление от февраля 2017 г .: сообщается, что в этом больше нет необходимости, см. Ответы @loretoparisi и @allen).
  3. обновите ваш PATH, включив в него исполняемый файл ffmpeg (я использовал fluent-ffmpeg , который позволяет вам установить два варианта env для более легкой обработки. 

Дайте мне знать, если нужно больше подробностей, я могу обновить этот ответ.

Копия и chmod (шаг 2), очевидно, не идеальны ... хотелось бы знать, если кто-нибудь нашел лучший способ справиться с этим, или это типично для этого стиля архитектуры.

(2-е обновление, запись перед первым обновлением, потому что оно более актуально):

Шаг копирования + chmod больше не нужен, как указывал @Allen - я выполняю ffmpeg в функциях Lambda непосредственно из/var/task/без проблем на этом этапе. Обязательно chmod 755 любые двоичные файлы перед загрузкой их в Lambda (также, как указал @Allen).

Я больше не использую fluent-ffmpeg для выполнения работы. Скорее я обновляю PATH для включения process.env['LAMBDA_TASK_ROOT'] и выполняю простые сценарии bash.

В верхней части вашей лямбда-функции:

process.env['PATH'] = process.env['PATH'] + "/" + process.env['LAMBDA_TASK_ROOT']

Для примера, который использует ffmpeg: lambda-pngs-to-mp4 .

Для множества полезных лямбда-компонентов: лямбду .

Приведенное ниже обновление оставлено для потомков, но больше не нужно:

ОБНОВЛЕНИЕ С БОЛЬШЕ ДЕТАЛЕЙ:

Я скачал статический двоичный файл ffmpeg здесь . Amazon рекомендует загрузить EC2 и создать бинарный файл для вашего использования, потому что эта среда будет соответствовать условиям Lambda. Вероятно, хорошая идея, но больше работы, и эта статическая загрузка работала для меня.

Я поместил только двоичный файл ffmpeg в папку /dist моего архива проекта.

Когда вы загружаете свой Zip в lambda, он живет по адресу /var/task/. По какой-то причине я столкнулся с проблемами доступа, пытаясь использовать двоичный файл в этом месте, и с другими проблемами, пытаясь редактировать разрешения для файла. Быстрый обходной путь - переместить двоичный файл в разрешения /tmp/ и chmod.

В Node вы можете запустить Shell через child_process. То, что я сделал, выглядит так:

require('child_process').exec(
  'cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg;',
  function (error, stdout, stderr) {
    if (error) {
      //handle error
    } else {
      console.log("stdout: " + stdout)
      console.log("stderr: " + stderr)
      //handle success
    }
  }
)

Это должно дать вам исполняемый двоичный файл ffmpeg в вашей лямбда-функции, но вам все равно нужно убедиться, что он находится в вашем $ PATH. 

Я отказался от fluent-ffmpeg и использовал нод для запуска команд ffmpeg в пользу простого запуска bash-скрипта вне узла, поэтому мне пришлось добавить /tmp/ в мой путь вверху лямбда-функции:

process.env.PATH = process.env.PATH + ':/tmp/'

Если вы используете fluent-ffmpeg, вы можете установить путь к ffmpeg через:

process.env['FFMPEG_PATH'] = '/tmp/ffmpeg';

В некоторой степени связанный/бесстыдный саморазъем: я работаю над набором модулей, чтобы упростить сборку функций Lambda из составных модулей под именем Lambduh . Может сэкономить время на сбор этих вещей. Быстрый пример: обработка этого сценария с помощью lambduh-execute будет такой простой:

promises.Push(execute({
  Shell: "cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg",
})

Где promises - массив обещаний, которые нужно выполнить.

37
Russ Matney

Я создал GitHub repo , который делает именно это (а также изменяет размер видео одновременно). Ответ Расса Мэтни был чрезвычайно полезен, чтобы сделать исполняемый файл FFmpeg.

6
BKH

Я не уверен, какую библиотеку пользовательского режима вы бы использовали для задачи ffmpeg; тем не менее шаги для достижения этого являются одинаковыми.

  1. Создайте отдельный каталог для вашего лямбда-проекта 
  2. Запустите npm install <package name> внутри этого каталога (это автоматически установит node_modules и соответствующие файлы)
  3. Создайте файл index.js в каталоге проекта lambda, затем используйте функцию require(<package-name>) и выполните свою основную задачу по созданию миниатюр видео 
  4. Как только вы закончите, вы можете заархивировать папку проекта lambda и загрузить ее в консоль управления AWS и настроить файл индекса и обработчик.
  5. Остальные конфигурации следуют тому же процессу, что и Роль выполнения IAM, триггер, спецификация памяти и времени ожидания и т.д.
2
Naveen Vijay

Я получил это работает, не перемещая его в /tmp. Я запустил chmod 755 на моем исполняемом файле, и тогда это сработало! У меня были проблемы, когда я ранее установил его на chmod 777.

2
Allen

В то время, когда я пишу, как уже было описано выше, больше нет необходимости копировать двоичные файлы из текущей папки, то есть папки var/task или process.env['LAMBDA_TASK_ROOT'], в папку /tmp .... Так что это просто необходимо сделать 

chmod 755 dist/ff*

если у вас есть бинарные файлы ffmpeg и ffprobe.

Кстати, раньше мой 2 центовый раствор, который потратил впустую 2 дня, был таким

Configure : function(options, logger) {

        // default options
        this._options = {

          // Temporay files folder for caching and modified/downloaded binaries
          tempDir : '/tmp/',

          /**
           * Copy binaries to temp and fix permissions
           * default to false  - since this is not longer necessary
           * @see http://stackoverflow.com/questions/27708573/aws-lambda-making-video-thumbnails/29001078#29001078
          */
          copyBinaries : false

        };

        // override defaults
        for (var attrname in options) { this._options[attrname] = options[attrname]; }

        this.logger=logger;
        var self=this;

        // add temporary folder and task root folder to PATH
        process.env['PATH'] = process.env['PATH'] + ':/tmp/:' + process.env['LAMBDA_TASK_ROOT']

        if(self._options.copyBinaries)
        {
          var result = {}
          execute(result, {
            Shell: "cp ./ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg", // copies an ffmpeg binary to /tmp/ and chmods permissions to run it
            logOutput: true
          })
          .then(function(result) {
            return execute(result, {
               Shell: "cp ./ffprobe /tmp/.; chmod 755 /tmp/ffprobe", // copies an ffmpeg binary to /tmp/ and chmods permissions to run it
               logOutput: true
             })
          })
          .then(function(result) {
             self.logger.info("LambdaAPIHelper.Configure done.");
          })
          .fail(function(err) {
            self.logger.error("LambdaAPIHelper.Configure: error %s",err);
          });
        } //copyBinaries

      }

помог хороший модуль lambduh:

// lambuh & dependencies
var Q = require('q');
var execute = require('lambduh-execute');

Как описано здесь и подтверждено автором модуля сейчас, это может считаться не нужным, кстати, интересно иметь хорошее представление о среде лямбда-времени (машины), которая хорошо описана в разделе Изучение Лямбда-среды выполнения среда .

2
loretoparisi

Я только что прошел через те же проблемы, что и описанные выше, и в итоге перешел к той же концепции перемещения моих сценариев, требующих выполнения, в каталог/tmp. 

var childProcess = require("child_process");
var Q = require('q');

Код, который я использовал ниже, с обещаниями:

.then(function(result) {
    console.log('Move Shell ffmpeg Shell script to executable state and location');
    var def = Q.defer();
    childProcess.exec("mkdir /tmp/bin; cp /var/task/bin/ffmpeg /tmp/bin/ffmpeg; chmod 755 /tmp/bin/ffmpeg",
      function (error, stdout, stderr) {
        if (error) {
          console.log("error: " + error)
        } else {
          def.resolve(result);
        }
      }
    )
    return def.promise;
  })
0
codin

Чтобы двоичный файл был непосредственно исполняемым на AWS Lambda (без необходимости сначала копировать в/tmp и chmod), необходимо убедиться, что у двоичного файла есть разрешение на исполняемый файл при добавлении в Zip-файл.

Это проблематично в Windows, потому что Windows не распознает двоичные файлы Linux. Если вы используете Windows 10, используйте Ubuntu Bash Shell для создания пакета.

Я создал шаблон функции Node.js специально для этой цели здесь . Это позволяет вам развернуть один или несколько двоичных файлов в Lambda, затем выполнить произвольную команду Shell и захватить выходные данные.

0
Hai Phan