我目前正在实现一个 Web 应用程序,我希望用户录制一些音频,然后我想要一个提交按钮以将录制的 mp3 文件发布到服务器。
我的服务器(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 请求后在我的服务器中 print request.form 时,我只得到这个:
ImmutableMultiDict([('file', u'')])
print request.form['file'] 返回一个空行。
为什么会这样?是不是POST请求有问题。
最后,我希望能够解码我发布的字符串以转换回 mp3。我该怎么做?
注意:所有这些都不必保持不变。任务是录制音频,然后将其发布到服务器。如果有更有效的方法来做到这一点,欢迎任何提示。另外,我不关心文件是 wav 还是 mp3。
最佳答案
注意:此答案仅处理 chrome 和 Firefox 中的当前实现。所有这些都可能很快发生变化。
我不确定您的服务器端代码是否有问题,但请不要将二进制数据作为字符串发送。相反,使用 FormData 将其作为多部分发送(您将赢得 30% 的数据 + 完整性)。
此外,在您的 MediaRecorder 代码中,您似乎在每个 dataavailable 事件中完成文件。这通常不是您想要的。
目前,没有浏览器支持本地录制为 mp3。
var mimes = ['mpeg', 'mpeg3', 'x-mpeg3', 'mp3', 'x-mpeg']
console.log(mimes.some(m=>MediaRecorder.isTypeSupported('audio/'+m)));
因此,如果您想采用 MediaRecorder 方式,则必须使用 opus 编解码器,封装在用于 chrome 的 webm 或 ogg 中 对于 FF :
var enc = ['ogg', 'webm'];
var mime = "";
enc.forEach(e => {
if (!mime && MediaRecorder.isTypeSupported(`audio/${e};codecs="opus"`)) {
mime = `audio/${e};codecs="opus"`;
}
});
console.log(mime);
现在我们有了正确的 mimeType,我们可以简单地告诉浏览器使用它:
var enc = ['ogg', 'webm'];
var extension = "",
mime = '';
enc.forEach(e => !extension &&
(mime = `audio/${e};codecs="opus"`) &&
MediaRecorder.isTypeSupported(mime) &&
(extension = e));
navigator.mediaDevices.getUserMedia({
audio: true
})
.then(stream => {
const chunks = [];
const rec = new MediaRecorder(stream, {
mimeType: mime // use the mimeType we've found
});
// this is not where we build the file, but where we store the chunks
rec.ondataavailable = e => chunks.push(e.data);
rec.onstop = e => {
// stop our gUM stream
stream.getTracks().forEach(t => t.stop());
// NOW create the file
let blob = new Blob(chunks, {
type: mime
});
// we could now send this blob :
// let form = new FormData();
// form.append('file', blob, 'filename.'+extension;
// ... declare xhr
// xhr.send(form);
// but we'll just fetch it for the demo :
let url = URL.createObjectURL(blob);
let au = new Audio(url);
au.controls = true;
document.body.appendChild(au);
au.play();
// and create an downloadable link from it :
let a = document.createElement('a');
a.href = url;
a.download = 'filename.' + extension;
a.innerHTML = 'download';
document.body.appendChild(a);
};
rec.start();
setTimeout(() => rec.stop(), 3000);
});
或者我们也可以让浏览器默认执行所有操作。这只是文件扩展名的问题...
现在,如果你更喜欢 wav 而不是 opus,你可以放弃 MediaRecorder,只需使用 WebAudioAPI,将你的 gUM 流传递给它,并记录数据从那里。在这里,我将使用 recorder.js为简单起见的库。
navigator.mediaDevices.getUserMedia({
audio: true
})
.then(stream => {
const aCtx = new AudioContext();
const streamSource = aCtx.createMediaStreamSource(stream);
var rec = new Recorder(streamSource);
rec.record();
setTimeout(() => {
stream.getTracks().forEach(t => t.stop());
rec.stop()
rec.exportWAV((blob) => {
// now we could send this blob with an FormData too
const url = URL.createObjectURL(blob);
let au = new Audio(url);
au.controls = true;
document.body.appendChild(au);
au.play();
let a = document.createElement('a');
a.href = url;
a.innerHTML = 'download';
a.download = 'filename.wav';
document.body.appendChild(a);
});
}, 3000);
})<script src="https://rawgit.com/mattdiamond/Recorderjs/master/dist/recorder.js"></script>
如果你真的想要一个 mp3,我想你可以使用网络上可用的 javascript lame 库之一。
关于javascript - 将 HTML5 音频数据发布到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43903963/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.