将文件保存到AWS S3

时间:2019-12-06 02:22:40

标签: node.js amazon-s3 aws-lambda

我一直在这里和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的过程中,文件的格式/编码丢失了。

任何提示或解决方案将不胜感激!

谢谢!

1 个答案:

答案 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())