【问题标题】:Unable to save binary data into AWS S3 from jQuery无法将二进制数据从 jQuery 保存到 AWS S3
【发布时间】:2019-11-09 14:11:07
【问题描述】:

我正在尝试将 Blob 对象上传到 S3,该对象确实已上传,但方式已损坏。该应用程序是关于在网页上记录audio 并将其保存到 S3。

HTML + Javascript 代码:

        <p>
            <button id=startRecord>START</button>
            <button id=stopRecord disabled>Submit</button>
        </p>
        <p id="recording"></p>
        <p>
            <a id=audioDownload></a>
        </p>

<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>

<script type="text/javascript">

    var audioContent;
    navigator.mediaDevices.getUserMedia({audio:true})
    .then(stream => {
        rec = new MediaRecorder(stream);
        rec.ondataavailable = e => {
            audioChunks.push(e.data);
            if (rec.state == "inactive"){
            let blob = new Blob(audioChunks);
            // audioContent = blob
            // audioContent = URL.createObjectURL(new Blob(audioChunks));
            // console.log(audioContent);

                $.ajax({
                  type: "POST",
                  url: 'https://aws-api-url/prod/audio',
                  data: new Blob(audioChunks),
                  crossDomain: true,
                  processData: false,
                  headers: {"x-api-key": 'someKey'},
                  contentType: false
                });
        // audioDownload.href = audioContent;
        // audioDownload.download = 'test';
        // audioDownload.innerHTML = 'download';
            }
        }
    })
    .catch(e=>console.log(e));

startRecord.onclick = e => {
  startRecord.disabled = true;
  stopRecord.disabled=false;
  document.getElementById("recording").innerHTML = "Listening...";
  audioChunks = [];
  rec.start();
}
stopRecord.onclick = e => {
    document.getElementById("recording").innerHTML = "";
  startRecord.disabled = false;
  stopRecord.disabled=true;
  rec.stop();
}
</script>

转储到 S3 的 AWS Lambda

import json
import boto3

def lambda_handler(event, context):
    # TODO implement

    s3_client = boto3.client('s3', aws_access_key_id='',aws_secret_access_key='')

    s3_client.put_object(Body=event['body'], Bucket='bucket', Key='incoming/test.wav')

    return {
        'statusCode': 200,
       'headers': {
        'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps(event)
    }

我可以对我的 Javascript 进行哪些更改以安全地发送这些数据

【问题讨论】:

    标签: javascript amazon-web-services html5-audio getusermedia


    【解决方案1】:

    MediaRecorder 不生成 .wav 数据类型。默认情况下,它可能会生成MIME typeaudio/webm; codecs=opus 的数据。或audio/ogg; codec=vorbis。您的 lambda 函数看起来像是忠实地存储了传入的数据。但它不是 .wav 数据,它是别的东西。

    您的示例代码允许 MediaRecorder 选择自己的 MIME 类型。在这种情况下,您应该问它使用了什么。例如

    rec = new MediaRecorder(stream);
    console.log (rec.mimeType);
    

    或者,您可以(尝试)告诉它您想要的 MIME 类型。在这种情况下,您仍然应该询问它实际使用了什么。 (浏览器在生成的 MIME 类型以及在无法提供您想要的确切类型时的响应方式各不相同。)如果您的浏览器可以做到这一点,这段代码可能 generate mp3 (aka MPEG Layer III) audio .

    rec = new MediaRecorder(stream, {mimeType: "audio/mpeg"});
    console.log (rec.mimeType);
    

    或者,你可以试试audio/mp4 MIME type,看看你得到了什么音频编解码器。它可能因浏览器而异。

    您通常可以在录制后使用ffmpeg 将任何 MIME 类型转换为另一种类型。如果需要 .wav 输出或其他特定格式,这很方便。 It takes some hacking, but you can do it in your lambda function.

    【讨论】:

    • 我确实解决了这个mimeType 问题,但是问题仍然存在。我发现 lambda 函数正在读取我的 event['body']str,不确定这是否是问题所在。有什么想法吗?
    • 我不熟悉 python 语言的 AWS lambda 端点。但是,我相信 AWS 会将 POST 操作的二进制有效负载编码为 base64 文本字符串。您需要使用base64.b64decode() 将其转换为二进制对象。看到这个:: medium.com/swlh/…
    猜你喜欢
    • 2011-07-03
    • 2019-03-30
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 2018-06-08
    相关资源
    最近更新 更多