将浏览器中录制的音频作为 WAV 文件保存到 Python API

问题描述 投票:0回答:2

我正在开展一个项目,需要我:

  1. 从浏览器录制音频(当前通过 MediaRecorder API)
  2. 通过 HTTP POST 发送到 Python API
  3. 将此音频数据作为 WAV 文件保存在文件系统上的某个位置

我当前将从浏览器录制的音频编码为 Base64 字符串(来自由音频块构造的 Blob):

start() {
  return new Promise(resolve => {
     navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => {
      this.mediaRecorder = new MediaRecorder(stream);
      this.audioChunks = [];
   this.mediaRecorder.addEventListener('dataavailable', event => {
        this.audioChunks.push(event.data);
      });

      this.mediaRecorder.start();
    });
});

stop() {
   this.mediaRecorder.stop();
}


getData() {
   const blob = new Blob(this.audioChunks, { type: 'audio/wav;codecs=opus' });
   const reader = new FileReader();
   reader.readAsDataURL(blob);
   reader.onloadend = () => {
   const base64data = reader.result;
   this.http.post('http://localhost:5000/test', { audio: base64data }).subscribe(res => {
    console.log(res);
  });
};

}

将其发送到后端后,尝试通过解码 Base64 字符串并使用 Python 'Wave' 包写入文件来保存音频。然而我只是在结果文件中得到静态。

def write_to_file(base64_audio):
decoded = base64.standard_b64decode(base64_audio)
print(type(decoded))
with wave.open('temp/test.wav', 'wb') as wav:
    wav.setparams((2, 2, 16000, 0, 'NONE', 'NONE'))
    wav.writeframes(decoded)

任何有关如何解决此问题或改进流程的建议将不胜感激。

python audio base64 wav mediarecorder
2个回答
0
投票

Python

import base64
import wave

from flask import Flask, request

app = Flask(__name__)


@app.route("/test", methods=["POST"])
def hello():
    data = str(request.form)[59:][:-4].replace(" ", "+").encode()
    write_to_file(data)
    return "Hello World!"


def write_to_file(base64_audio):
    import base64
    wav_file = open("temp.wav", "wb")
    decode_string = base64.b64decode(base64_audio)
    wav_file.write(decode_string)


if __name__ == "__main__":
    app.run("0.0.0.0", 5000)

HTML

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
</head>
<body>
<input type="button" value="start" onclick="start()"></br>
<input type="button" value="stop" onclick="stop()"></br>
<input type="button" value="getData" onclick="getData()"></br>

<script type="text/javascript">
    function start() {
        return new Promise(resolve => {
            navigator.mediaDevices.getUserMedia({audio: true})
                .then(stream => {
                    this.mediaRecorder = new MediaRecorder(stream);
                    this.audioChunks = [];
                    this.mediaRecorder.addEventListener('dataavailable', event => {
                        this.audioChunks.push(event.data);
                    });

                    this.mediaRecorder.start();
                });
        });
    }

    function stop() {
        this.mediaRecorder.stop();
    }


    function getData() {
        let blob = new Blob(this.audioChunks, {type: 'audio/wav;codecs=opus'});
        let reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onloadend = () => {
            let base64data = reader.result;
            console.log(base64data)
            /*
            this.http.post(, {audio: base64data}).subscribe(res => {
                console.log(res);
            });
            */
            $.ajax({
                type: "POST",
                url: 'http://localhost:5000/test',
                data: base64data,
                success: function (data) {
                    alert(data);
                }
            });
        };
    }
</script>
</body>
</html>

0
投票

回答Sreekant的问题,线路

str(request.form)[59:][:-4].replace(" ", "+").encode() 

它从表单数据的字符串中删除文本元数据。如果你看一下它,它的开头是这样的:

data:audio/wav;codecs=opus;base64,GkXfo59C

对于我的用例,我这样做了:

str(audiobytes).replace("audio/wav;codecs=opus;base64,", "").encode()
© www.soinside.com 2019 - 2024. All rights reserved.