Hey I was following this blog post - https://www.serverless.com/blog/publish-aws-lambda-layers-serverless-framework which creates gif from video files using ffmpeg.
My file structure -
gifmaker
My handler.js code -
const { spawnSync } = require("child_process");
const { readFileSync, writeFileSync, unlinkSync } = require("fs");
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
module.exports.mkgif = async (event, context) => {
if (!event.Records) {
console.log("not an s3 invocation!");
return;
}
for (const record of event.Records) {
if (!record.s3) {
console.log("not an s3 invocation!");
continue;
}
if (record.s3.object.key.endsWith(".gif")) {
console.log("already a gif");
continue;
}
// get the file
const s3Object = await s3
.getObject({
Bucket: record.s3.bucket.name,
Key: record.s3.object.key
})
.promise();
// write file to disk
writeFileSync(`/tmp/${record.s3.object.key}`, s3Object.Body);
// convert to gif!
spawnSync(
"/opt/ffmpeg/ffmpeg",
[
"-i",
`/tmp/${record.s3.object.key}`,
"-f",
"gif",
`/tmp/${record.s3.object.key}.gif`
],
{ stdio: "inherit" }
);
// read gif from disk
const gifFile = readFileSync(`/tmp/${record.s3.object.key}.gif`);
// delete the temp files
unlinkSync(`/tmp/${record.s3.object.key}.gif`);
unlinkSync(`/tmp/${record.s3.object.key}`);
// upload gif to s3
await s3
.putObject({
Bucket: record.s3.bucket.name,
Key: `${record.s3.object.key}.gif`,
Body: gifFile
})
.promise();
}
};
my serverless.yml -
service: gifmaker
frameworkVersion: "2"
provider:
name: aws
runtime: nodejs12.x
region: ap-south-1
iamRoleStatements:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
Resource: "arn:aws:s3:::${self:custom.bucket}/*"
functions:
mkgif:
handler: handler.mkgif
events:
- s3: ${self:custom.bucket}
layers:
- {Ref: FfmpegLambdaLayer}
layers:
ffmpeg:
path: layer
custom:
bucket: ${env:BUCKET, 'newsgator-company4'}
Getting this error -
2020-10-07T22:32:14.695Z 13d283af-13dd-40e4-ae52-e1fc0d41f547 ERROR Invoke Error
{
"errorType": "Error",
"errorMessage": "ENOENT: no such file or directory, open '/tmp/data_store/0009.mp4'",
"code": "ENOENT",
"errno": -2,
"syscall": "open",
"path": "/tmp/data_store/0009.mp4",
"stack": [
"Error: ENOENT: no such file or directory, open '/tmp/data_store/0009.mp4'",
" at Object.openSync (fs.js:462:3)",
" at writeFileSync (fs.js:1362:35)",
" at Runtime.module.exports.mkgif [as handler] (/var/task/handler.js:29:5)",
" at runMicrotasks (<anonymous>)",
" at processTicksAndRejections (internal/process/task_queues.js:97:5)"
]
}
I have been stuck on this for hours now, cant figure out the issue. Also the lambda function has administrator role.
As I see the problem is that you are giving a path that doesn't exist
writeFileSync(`/tmp/${record.s3.object.key}`, s3Object.Body);
this becomes -> /tmp/data_store/0009.mp4
Your solution would work if your record.s3.object.key
is just 0009.mp4
and your route would be /tmp/0009.mp4
-> this would work because writeFileSync
can create a file if the file doesn't exist but in your case, it's not possible because you don't have directory data_store
and because that this is not working.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.