Je veux créer des vignettes à partir de vidéos téléchargées sur S3, je sais comment le créer avec Node.js et ffmpeg.
Selon cet article du forum je peux ajouter des bibliothèques:
ImageMagick est la seule bibliothèque externe actuellement fournie par Par défaut, mais vous pouvez inclure toutes les dépendances supplémentaires dans le fichier .zip fichier que vous fournissez lorsque vous créez une fonction Lambda. Notez que si cela est une bibliothèque ou un exécutable natif, vous devrez vous assurer qu'il fonctionne sur Amazon Linux.
Mais comment puis-je mettre du binaire statique ffmpeg sur aws lambda?
Et comment puis-je appeler depuis Node.js ce binaire statique (ffmpeg) avec AWS Lambda?
Je suis novice avec Amazon AWS et Linux
Quelqu'un peut-il m'aider?
Le processus décrit par Naveen est correct, mais il dissimule un détail qui peut être très pénible - notamment le fichier binaire ffmpeg dans le zip et son accès au sein de votre fonction lambda.
Je viens de traverser ça, ça a marché comme ça:
/dist
chaque fois qu'elle est créée)/tmp/
dir et un chmod
pour vous donner l'accès.@loretoparisi
et de @allen
).Faites-moi savoir si plus de détails sont nécessaires, je peux mettre à jour cette réponse.
La copie et chmod (étape 2) n’est évidemment pas idéale… aimerions savoir si quelqu'un a trouvé un meilleur moyen de gérer cela, ou si cela est typique de ce style d'architecture.
L'étape copy + chmod n'est plus nécessaire, comme l'a souligné @Allen - j'exécute ffmpeg dans les fonctions Lambda directement à partir de/var/task/sans aucun problème à ce stade. Assurez-vous de chmod 755
quels que soient les fichiers binaires avant de les télécharger sur Lambda (comme l'a souligné @Allen).
Je n'utilise plus fluent-ffmpeg pour faire le travail. Au lieu de cela, je mets à jour le PATH pour inclure le process.env['LAMBDA_TASK_ROOT']
et exécute des scripts bash simples.
Au sommet de votre fonction Lambda:
process.env['PATH'] = process.env['PATH'] + "/" + process.env['LAMBDA_TASK_ROOT']
Pour un exemple qui utilise ffmpeg: lambda-pngs-to-mp4 .
Pour une multitude de composants lambda utiles: lambduh .
MISE À JOUR AVEC PLUS DE DÉTAIL:
J'ai téléchargé le binaire statique ffmpeg ici . Amazon recommande de démarrer un EC2 et de créer un binaire pour votre utilisation, car cet environnement sera le même que les conditions sur lesquelles Lambda est exécuté. Probablement une bonne idée, mais plus de travail, et ce téléchargement statique a fonctionné pour moi.
J'ai extrait uniquement le binaire ffmpeg
dans le dossier /dist
de mon projet à archiver.
Lorsque vous transférez votre fichier Zip sur lambda, il se trouve à /var/task/
. Pour une raison quelconque, j'ai rencontré des problèmes d'accès en essayant d'utiliser le fichier binaire à cet emplacement, et d'autres problèmes en essayant de modifier les autorisations sur le fichier. Une solution rapide consiste à déplacer le fichier binaire vers les autorisations /tmp/
et chmod
.
Dans Node, vous pouvez exécuter Shell via un child_process
. Ce que j'ai fait ressemble à ceci:
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
}
}
)
Cela devrait vous donner un binaire ffmpeg exécutable dans votre fonction lambda - mais vous devez tout de même vous assurer qu'il se trouve sur votre $ PATH.
J'ai abandonné fluent-ffmpeg et utilisé noeud pour lancer des commandes ffmpeg au lieu de lancer un script bash depuis noeud. Pour moi, je devais donc ajouter /tmp/
à mon chemin en haut de la fonction lambda:
process.env.PATH = process.env.PATH + ':/tmp/'
Si vous utilisez fluent-ffmpeg, vous pouvez définir le chemin d'accès à ffmpeg via:
process.env['FFMPEG_PATH'] = '/tmp/ffmpeg';
Auto-prise quelque peu liée/sans vergogne: je travaille sur un ensemble de modules pour faciliter la création de fonctions Lambda à partir de modules composables sous le nom Lambduh . Cela pourrait vous faire gagner du temps. Un exemple rapide: gérer ce scénario avec lambduh-execute serait aussi simple que:
promises.Push(execute({
Shell: "cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg",
})
Où promises
est un tableau de promesses à exécuter.
J'ai créé un GitHub repo qui fait exactement cela (ainsi que redimensionne la vidéo en même temps). La réponse de Russ Matney a été extrêmement utile pour rendre le fichier FFmpeg exécutable.
Je ne sais pas quelle bibliothèque de mode personnalisé vous utiliseriez pour la tâche ffmpeg; néanmoins, les étapes à suivre sont les mêmes.
npm install <package name>
dans ce répertoire (ceci mettrait automatiquement en place les modules et les fichiers appropriés)index.js
dans le répertoire du projet lambda, puis utilisez la fonction require(<package-name>)
et effectuez votre tâche principale pour la création de vignettes vidéo. Je travaille avec cela sans le déplacer vers /tmp
. J'ai exécuté chmod 755
sur mon exécutable et ensuite cela a fonctionné! J'ai eu des problèmes lorsque je l'ai précédemment défini à chmod 777
.
Au moment où j'écris, comme décrit ci-dessus, il n'est plus nécessaire de copier les fichiers binaires du dossier en cours, c'est-à-dire le dossier var/task
ou process.env['LAMBDA_TASK_ROOT']
dans le dossier /tmp
.
chmod 755 dist/ff*
si vous y avez vos binaires ffmpeg
et ffprobe
.
En passant, auparavant, ma solution à 2 cents qui perdait 2 jours de temps était la suivante:
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
}
aidé par le bon module lambduh
:
// lambuh & dependencies
var Q = require('q');
var execute = require('lambduh-execute');
Comme décrit ici et confirmé par l'auteur du module, ceci peut être considéré comme inutile, en passant, il est intéressant de bien comprendre l'environnement d'exécution lambda (la machine) qui est bien décrit dans Exploring the Lambda Runtime environnement .
Je viens juste de passer en revue les problèmes décrits ci-dessus et je me suis retrouvé avec le même concept de déplacement de mes scripts nécessitant une exécution dans le répertoire/tmp.
var childProcess = require("child_process");
var Q = require('q');
Le code que j'ai utilisé est ci-dessous avec des promesses:
.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;
})
Pour que le fichier binaire soit directement exécutable sur AWS Lambda (sans devoir copier au préalable dans/tmp et chmod), vous devez vous assurer que le fichier binaire dispose des droits d'exécution lorsqu'il est ajouté au fichier Zip.
Cela pose problème sous Windows car Windows ne reconnaît pas les fichiers binaires Linux. Si vous utilisez Windows 10, utilisez le shell Ubuntu Bash pour créer le paquet.
J'ai créé un modèle de fonction Node.js spécialement à cet effet ici . Il vous permet de déployer un ou plusieurs fichiers binaires sur Lambda, puis d'exécuter une commande shell arbitraire et de capturer la sortie.