Невозможно сохранить двоичные данные в AWS S3 из jQuery - PullRequest
1 голос
/ 09 ноября 2019

Я пытаюсь загрузить объект Blob в S3, который загружается, но поврежденным способом. Приложение предназначено для записи audio на веб-странице и сохранения ее на S3.

HTML + Javascript Code:

        <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>

AWS Lambda, которая создает дамп в S3

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 для безопасной отправки этих данных

1 Ответ

0 голосов
/ 10 ноября 2019

MediaRecorder не генерирует тип данных .wav. По умолчанию он, вероятно, генерирует данные типа MIME audio/webm; codecs=opus. или audio/ogg; codec=vorbis. Ваша лямбда-функция выглядит так, как будто она верно хранит входящие данные. Но это не данные .wav, это что-то другое.

Ваш пример кода позволяет MediaRecorder выбрать свой собственный тип MIME. В этом случае вы должны спросить его, что он использовал. Например,

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

Или вы можете (попытаться) указать, какой тип MIME вам нужен. В этом случае вы все равно должны спросить его, что он на самом деле использовал. (Браузеры различаются по типам MIME, которые они генерируют, и по тому, как они реагируют, когда они не могут предоставить именно тот тип, который вы хотите.) Если ваш браузер может это сделать, этот код будет генерировать , вероятно, mp3 (он же MPEG Layer III) audio .

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

Или, вы можете попробовать audio/mp4 MIME type и посмотреть, какой аудио кодек вы получите. Это может варьироваться от браузера к браузеру.

Обычно вы можете использовать ffmpeg для преобразования любого типа MIME в другой после того, как вы его записали. Это удобно, если требуется вывод .wav или какой-то другой конкретный формат. Требуется некоторый взлом, но вы можете сделать это в своей лямбда-функции .

...