it-swarm.com.de

AWS Lambda macht Video-Thumbnails

Ich möchte Thumbnails von Videos erstellen, die in S3 hochgeladen wurden, ich weiß, wie man es mit Node.js und ffmpeg macht. 

Nach diesem Forumbeitrag kann ich Bibliotheken hinzufügen:

ImageMagick ist die einzige externe Bibliothek, die derzeit von .__ bereitgestellt wird. Standardeinstellung, Sie können jedoch zusätzliche Abhängigkeiten in die ZIP-Datei einfügen Datei, die Sie beim Erstellen einer Lambda-Funktion angeben. Beachten Sie, dass wenn. Ist eine native Bibliothek oder ausführbare Datei, müssen Sie sicherstellen, dass sie läuft unter Amazon Linux.

Aber wie kann ich statische ffmpeg binär auf aws lambda setzen?

Und wie kann ich diese statische Binärdatei (ffmpeg) von Node.js mit AWS Lambda aufrufen?

Ich bin Neuling mit Amazon AWS und Linux

Kann mir jemand helfen?

21
Jesus

Der von Naveen skizzierte Prozess ist korrekt, aber er beschönigt ein Detail, das ziemlich schmerzhaft sein kann - einschließlich der ffmpeg-Binärdatei in der Zip-Klasse und dem Zugriff innerhalb Ihrer Lambda-Funktion.

Ich habe es gerade durchgemacht, es ging so:

  1. Fügen Sie die statische Binärdatei von ffmpeg in Ihr gepacktes Lambda-Funktionspaket ein (ich habe einen Schluckauf-Vorgang, um dies bei jeder Erstellung in /dist zu kopieren).
  2. Wenn Ihre Funktion aufgerufen wird, verschieben Sie die Binärdatei in ein /tmp/-Verzeichnis und chmod, um Ihnen Zugriff zu gewähren (Update vom Februar 2017: Es wird berichtet, dass dies nicht länger erforderlich ist, siehe: @loretoparisi und @allens Antworten).
  3. aktualisieren Sie Ihren PATH, um die ausführbare Datei von ffmpeg einzuschließen (ich habe fluent-ffmpeg verwendet, mit der Sie zwei env-vars setzen können, um das einfacher zu handhaben. 

Lassen Sie mich wissen, wenn mehr Details erforderlich sind, ich kann diese Antwort aktualisieren.

Die Kopie und das Chmod (Schritt 2) sind offensichtlich nicht ideal. Ich würde gerne wissen, ob jemand einen besseren Weg gefunden hat, um damit umzugehen, oder ob dies typisch für diesen Architekturstil ist.

(2. Update, das vor dem ersten Update geschrieben wird, ist relevanter):

Der Schritt copy + chmod ist nicht mehr erforderlich, wie @Allen darauf hinweist - ich führe ffmpeg in Lambda-Funktionen direkt von/var/task/aus ohne Probleme an dieser Stelle. Stellen Sie sicher, dass chmod 755 alle Binärdateien ist, bevor Sie sie in Lambda hochladen (auch als @Allen angegeben).

Ich benutze Fluent-ffmpeg nicht mehr für die Arbeit. Vielmehr aktualisiere ich den PATH, um den process.env['LAMBDA_TASK_ROOT'] einzuschließen und einfache Bash-Skripts auszuführen.

An der Spitze Ihrer Lambda-Funktion:

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

Für ein Beispiel, das ffmpeg verwendet: lambda-pngs-to-mp4 .

Für eine Menge nützlicher Lambda-Komponenten: lambduh .

Das folgende Update wurde für die Nachwelt hinterlassen, ist aber nicht mehr notwendig:

AKTUALISIERUNG MIT MEHR DETAILS:

Ich habe die statische ffmpeg-Binärdatei hier heruntergeladen. Amazon empfiehlt, eine EC2 zu starten und dort eine Binärdatei zu erstellen, da diese Umgebung den Bedingungen entspricht, unter denen Lambda läuft. Wahrscheinlich eine gute Idee, aber mehr Arbeit, und dieser statische Download hat für mich funktioniert.

Ich zog nur die ffmpeg-Binärdatei in den zu archivierenden /dist-Ordner meines Projekts.

Wenn Sie Ihre Zip in Lambda hochladen, lebt sie bei /var/task/. Aus irgendeinem Grund bin ich auf Zugriffsprobleme gestoßen, als ich versuchte, die Binärdatei an diesem Speicherort zu verwenden, und weitere Probleme, bei denen versucht wurde, Berechtigungen für die Datei dort zu bearbeiten. Um dies schnell zu umgehen, verschieben Sie die Binärdatei dort in die Berechtigungen /tmp/ und chmod.

In Node können Sie Shell über einen child_process ausführen. Was ich gemacht habe sieht so aus:

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
    }
  }
)

So viel sollte Ihnen eine ausführbare ffmpeg-Binärdatei in Ihrer Lambda-Funktion geben - aber Sie müssen trotzdem sicherstellen, dass sie auf Ihrem $ PATH steht. 

Ich habe Fluent-ffmpeg und den Knoten zum Starten von ffmpeg-Befehlen zugunsten eines einfachen Starts eines bash-Skripts aus dem Knoten aufgegeben. Daher musste ich /tmp/ zu meinem Pfad oben in der Lambda-Funktion hinzufügen:

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

Wenn Sie fluent-ffmpeg verwenden, können Sie den Pfad auf ffmpeg setzen:

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

Etwas verwandter/schamloser Self-Plug: Ich arbeite an einer Reihe von Modulen, um das Erstellen von Lambda-Funktionen aus zusammensetzbaren Modulen unter dem Namen Lambduh zu vereinfachen. Könnte etwas Zeit sparen, diese Dinge zusammenzubringen. Ein schnelles Beispiel: Die Handhabung dieses Szenarios mit lambduh-execute wäre so einfach wie:

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

Dabei ist promises ein Array von Versprechen, die ausgeführt werden sollen.

37
Russ Matney

Ich habe ein GitHub-Repo erstellt, das genau das tut (und das Video gleichzeitig skaliert). Russ Matneys Antwort war äußerst hilfreich, um die FFmpeg-Datei ausführbar zu machen.

6
BKH

Ich bin nicht sicher, welche benutzerdefinierte Modusbibliothek Sie für die ffmpeg-Aufgabe verwenden würden. Trotzdem sind die Schritte, die zu erreichen sind, gleich.

  1. Erstellen Sie ein separates Verzeichnis für Ihr Lambda-Projekt 
  2. Führen Sie npm install <package name> in diesem Verzeichnis aus (dies würde automatisch die node_modules und die entsprechenden Dateien einfügen)
  3. Erstellen Sie im Lambda-Projektverzeichnis eine index.js-Datei, verwenden Sie dann die require(<package-name>) und führen Sie Ihre Hauptaufgabe für die Erstellung von Video-Miniaturansichten aus 
  4. Wenn Sie fertig sind, können Sie den Lambda-Projektordner mit einem Zip versehen und ihn in die AWS-Verwaltungskonsole hochladen und die Indexdatei und den Handler konfigurieren.
  5. Restliche Konfigurationen folgen dem gleichen Prozess wie IAM-Ausführungsrolle, Trigger, Speicher und Timeout-Spezifikation usw.
2
Naveen Vijay

Ich habe das zum Laufen gebracht, ohne es zu /tmp zu verschieben. Ich lief chmod 755 auf meine ausführbare Datei und dann hat es funktioniert! Ich hatte Probleme, als ich ihn vorher auf chmod 777 eingestellt habe.

2
Allen

Zu dem Zeitpunkt, an dem ich schreibe, wie oben beschrieben, ist es nicht mehr erforderlich, Binärdateien aus dem aktuellen Ordner, dh dem var/task- oder dem process.env['LAMBDA_TASK_ROOT']-Ordner, in den /tmp-Ordner zu kopieren. Es ist also nur zu tun 

chmod 755 dist/ff*

wenn Sie Ihre Binärdateien ffmpeg und ffprobe dort haben.

Übrigens, meine bisherige 2-Cent-Lösung, die 2 Tage Zeit verschwendete, war dies

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

      }

geholfen vom guten lambduh Modul:

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

Wie hier beschrieben und bestätigt von Modulautor, kann dies als nicht erforderlich betrachtet werden. Es ist übrigens interessant, die Lambda-Laufzeitumgebung (die Maschine) gut zu verstehen, die in Exploring the Lambda Runtime beschrieben wird Umgebung .

2
loretoparisi

Ich habe gerade die gleichen Probleme wie oben beschrieben durchgearbeitet und am Ende das gleiche Konzept wie das Verschieben meiner Skripts, die eine Ausführung erfordern, in das Verzeichnis/tmp verschoben. 

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

Code, den ich verwendet habe, ist unten mit Versprechen:

.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

Damit die Binärdatei direkt auf AWS Lambda ausgeführt werden kann (ohne zuvor nach/tmp und chmod kopieren zu müssen), müssen Sie sicherstellen, dass die Binärdatei die Berechtigung hat, wenn sie der Zip-Datei hinzugefügt wird.

Dies ist unter Windows problematisch, da Windows Linux-Binärdateien nicht erkennt. Wenn Sie Windows 10 verwenden, erstellen Sie das Paket mit der Ubuntu Bash Shell.

Ich habe eine Node.js-Funktionsvorlage speziell für diesen Zweck erstellt: hier . Sie können ein oder mehrere Binärdateien für Lambda bereitstellen, dann einen beliebigen Shell-Befehl ausführen und die Ausgabe erfassen.

0
Hai Phan