我一直在这里和Google上关注一些示例,这些示例如何编写Nodejs Lambda函数以从URL提取(音频)文件并将其保存到S3。到目前为止,我已经到达:
var AWS = require('aws-sdk');
var https = require('https');
var s3 = new AWS.S3();
const querystring = require('querystring');
exports.handler = function(event, context) {
const params = querystring.parse(event.body);
const audioUrl = params['audioUrl'];
https.get(audioUrl, function(res) {
var body = '';
res.on('data', function(chunk) {
// Agregates chunks
body += chunk;
});
res.on('end', function() {
// Once you received all chunks, send to S3
var params = {
Bucket: 'bucket_name',
Key: 'filename.wav',
Body: body
};
s3.putObject(params, function(err, data) {
if (err) {
console.error("ERROR: ", err, err.stack);
} else {
console.log("DATA:", data);
}
});
});
});
};
这导致文件名为 filename.wav 的文件被保存到S3存储桶,但该文件不是我想要的WAV音频文件。似乎在从audioUrl检索文件并将其保存到S3的过程中,文件的格式/编码丢失了。
任何提示或解决方案将不胜感激!
谢谢!
答案 0 :(得分:1)
您要将二进制文件转换为字符串,这就是为什么您上传的文件已损坏。您需要做的是使用Buffer
而不是string
。
const chunks = [];
res.on('data', function(chunk) {
// Agregates chunks
chunks.push(chunk)
});
res.on('end', function() {
// Once you received all chunks, send to S3
var params = {
Bucket: 'bucket_name',
Key: 'filename.wav',
Body: Buffer.concat(chunks)
};
s3.putObject(params, function(err, data) {
if (err) {
console.error("ERROR: ", err, err.stack);
} else {
console.log("DATA:", data);
}
});
});
在任何情况下,与其直接缓冲这些块,不如直接传递该流,并让S3 SDK处理它。
var params = {
Bucket: 'bucket_name',
Key: 'filename.wav',
Body: res // pass the readable stream directly
};
s3.putObject(params, function(err, data) {});
直接传递流的唯一警告是,该库只能使用可以确定其长度的流。如果该请求正确设置了内容长度,则不会有任何问题。
您可以改用s3.upload
来绕过此限制。
注意:已经有一段时间没有使用S3 SDK了,但是上一次我使用S3 SDK时,他们不支持管道,而是直接使用管道:res.pipe(s3.putObject())