我正在尝试从lambda运行sox音频二进制文件,我遵循了本指南:http://marcelog.github.io/articles/static_sox_transcoding_lambda_mp3.html 因此,我使用最新的Amazon Linux版本的docker创建了sox二进制文件,并将lambda部署为具有以下结构的zip软件包:
sox
index.js
Lambda代码:
exports.handler = async (event) => {
initializeContext();
try {
const object = await getFile("test.mp3");
const fs = require('fs');
fs.writeFileSync("/tmp/test.mp3", object.Body);
let result = child_process.execFileSync('sox', ['/tmp/test.mp3', '/tmp/testOutput.mp3', ... <filter params here>], {
encoding: 'ascii'
// shell: true
});
const file = fs.readFileSync("/tmp/testOutput.mp3");
await putFile("testOutput.mp3", file);
}
catch(err) {
try {
await log("error", err);
}
catch(err) {}
}
};
let getFile = async function(fileName) {
const params = {
Bucket: bucket,
Key: fileName
};
return await s3.getObject(params).promise();
};
let putFile = async function(fileName, body) {
const params = {
Bucket: bucket,
Key: fileName,
Body: body
};
await s3.putObject(params).promise();
};
因此,我需要从S3获取文件,对其进行处理并返回结果。 S3加载经过测试可以工作。但是,尝试启动“ sox”过程时出现“ EACCES”错误。 我想念什么?是否可以源自我使用了上一个Amazon Linux映像而Lambda使用了更旧版本的事实?
答案 0 :(得分:1)
我在处理音频文件时遇到了麻烦。 npm软件包很方便。
https://github.com/stojanovic/lambda-audio
如果您的命令是
sox input.mp3 -c 1 output.wav
您的节点代码将如下所示,
const lambdaAudio = require('lambda-audio')
lambdaAudio.sox('./input.mp3 -c 1 /tmp/output.wav')
.then(response => {
// Do something when the file was converted
})
.catch(errorResponse => {
console.log('Error from the sox command:', errorResponse)
})
并将所有复杂的问题留在npm软件包中。
希望有帮助。
答案 1 :(得分:0)
最后,我发现要确保文件许可权,我必须在Amazon Linux docker映像内创建zip包。所以你需要
npm i lambda-audio
在其中,然后将node_modules与index.js一起压缩。 我的lambda包zip根文件夹是:
node_modules // npm i lambda-audio result
index.js
具有内存消耗优化功能的Node 8.10运行时工作解决方案:
process.env["PATH"] = process.env["PATH"] + ":" + process.env["LAMBDA_TASK_ROOT"];
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const lambdaAudio = require("lambda-audio");
let bucket;
exports.handler = async (event) => {
try {
bucket = event.bucket;
const { inputFileName, outputFileName } = event;
const fs = require("fs");
const inputStream = fs.createWriteStream("/tmp/input.mp3");
await getFileToStream(inputFileName, inputStream);
await lambdaAudio.sox("/tmp/input.mp3 /tmp/output.mp3 <YOUR FILTERS HERE>);
fs.unlinkSync("/tmp/input.mp3"); // removing unused input file
const outputStream = fs.createReadStream("/tmp/output.mp3");
await uploadFileFromStream(outputFileName, outputStream);
}
catch(err) {
// Logging
}
};
let getFileToStream = async function(fileName, writeStream) {
const params = {
Bucket: bucket,
Key: fileName
};
const readStream = s3.getObject(params).createReadStream();
const end = new Promise((resolve, reject) => {
writeStream.on('close', () => resolve());
writeStream.on('error', (err) => reject(err));
readStream.on('error', (err) => reject(err));
});
readStream.pipe(writeStream);
return end;
};
let uploadFileFromStream = async function(fileName, readStream) {
const params = {
Bucket: bucket,
Key: fileName,
Body: readStream
};
return await s3.upload(params).promise();
};