Javascript 将HTML5音频数据发布到服务器

Javascript 将HTML5音频数据发布到服务器,javascript,python,html,audio,flask,Javascript,Python,Html,Audio,Flask,我目前正在实现一个web应用程序,我希望用户录制一些音频,然后我希望一个提交按钮将录制的mp3文件发布到服务器 function submit(blob) { var reader = new window.FileReader(); reader.readAsDataURL(blob); reader.onloadend = function() { var fd = new FormData(); base64data = reader.result;

我目前正在实现一个web应用程序,我希望用户录制一些音频,然后我希望一个提交按钮将录制的mp3文件发布到服务器

function submit(blob) {
  var reader = new window.FileReader();
  reader.readAsDataURL(blob);
  reader.onloadend = function() {

    var fd = new FormData();
    base64data = reader.result;
    fd.append('file', base64data, 'audio.mp3');

    $.ajax({
      type: 'POST',
      url: '/',
      data: fd,
      cache: false,
      processData: false,
      contentType: false,
      enctype: 'multipart/form-data'
    }).done(function(data) {
      console.log(data);
    });
  }

}
我的服务器(Flask)的主路由
“/”
正在等待POST请求:

@app.route('/', methods=['GET', 'POST'])
def index():
  if request.method == "GET":
    return render_template('index.html', request="GET")
  else:
    print request.files
    print request.form
    print request.form['file']
    if 'file' not in request.files:
      flash('No file part')
      return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
      flash('No selected file')
      return redirect(request.url)
    if file and allowed_file(file.filename):
      handle_file(file)
    return render_template('index.html', request="POST")
以下是我的JS代码:

这里有两个主要问题:

1) 当我在录制后下载mp3文件时,媒体播放器无法打开它。似乎我只是在录制音频时做错了什么

2) 当我收到POST请求后,在服务器中打印request.form时,我只得到以下信息:

ImmutableMultiDict([('file', u'')])
打印请求。表单['file']
返回一个空行

为什么会这样?POST请求是否有问题

最后,我希望能够解码我发布的字符串以转换回mp3。我该怎么做


注意:所有这些都不必保持不变。任务是录制音频,然后将其发布到服务器。如果有更有效的方法,欢迎提供任何提示。另外,我不在乎文件是wav还是mp3。

尝试将音频blob转换为Base64,并将Base64字符串发送到服务器

function submit(blob) {
  var reader = new window.FileReader();
  reader.readAsDataURL(blob);
  reader.onloadend = function() {

    var fd = new FormData();
    base64data = reader.result;
    fd.append('file', base64data, 'audio.mp3');

    $.ajax({
      type: 'POST',
      url: '/',
      data: fd,
      cache: false,
      processData: false,
      contentType: false,
      enctype: 'multipart/form-data'
    }).done(function(data) {
      console.log(data);
    });
  }

}
现在,在服务器中将base64字符串转换为二进制流


关于如何在python中解码Base64的更多信息,请参阅本文

注意:这个答案只处理chrome和Firefox中的当前实现。所有这些都可能很快发生变化。


我不确定您的服务器端代码是否有错误,但请不要将二进制数据作为字符串发送。相反,使用FormData将其作为多部分发送(您将赢得30%的数据+完整性)

此外,在MediaRecorder代码中,您似乎在每个
dataavailable
事件中完成文件。这通常不是你想要的


目前,没有浏览器支持本机录制为mp3

var mimes=['mpeg','mpeg3','x-mpeg3','mp3','x-mpeg']

log(mimes.some(m=>MediaRecorder.isTypeSupported('audio/'+m))1)您是否尝试过将
Blob
类型设置为
“音频/webm;codecs=opus”
“音频/ogg;codecs=opus”
?;2) 在
XMLHttpRequest()
load
事件中调用相应的函数。Afaik没有UA支持本机编码为mp3(可能很快会随着版税的结束而改变)。最简单的方法是不设置它,让浏览器将其处理为首选的MimeType。类似地,发送formData时不需要设置请求头。在文件名上检查文件的有效性是一个非常糟糕的主意。现在我想这不会解决你们的问题,但我认为这是值得告诉你们的。我认为将音频文件发布到服务器端是不明智的。我也不会用老js来做这个。我建议使用上传方法,而不是post,将其上传到文件服务器。然后在成功时使用filename向服务器发布消息。现在后端API只需处理声音文件。为什么不将blob数据转换为base64并发布base64字符串,并在后端将base64字符串解码回音频流?您应该检查此repo它完全符合您的需要,但它使用节点作为后端当我这样做时,烧瓶
request.form
ImmutableMultiDict([('file',u')])
base64string
不应该是该dict条目的值吗?Base64编码会使请求膨胀。从每个字节可以存储1..265,到只能存储1..64。Base64比原材料差4倍。谢谢。我想最后一个带.wav的是我要用的。然而,这里并不真正需要设置超时,因为我想要一个
start
stop
按钮,就像我的示例中那样。您将如何更改它以适应这些按钮?@pk1914只需将超时时调用的函数移动到您想要调用的位置,就像在单击事件中一样。