这篇文章主要为大家详细介绍了射流研究…实现录音上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了射流研究…代码实现录音上传,供大家参考,具体内容如下
1.html页面
2.记录器。射流研究…内容
3 .烧瓶写法
1.html页面
!文档类型超文本标记语言
html lang='en '
头
meta charset='UTF-8 '
标题id='标题'/标题
/头
身体
音频id='播放器'自动播放控件/音频
p
button onclick='start_reco()'开始录音/按钮
/p
p
按钮onclick=' ai _ reco()' style=' background-color:玉米花蓝'发送语音指令/按钮
/p
/body
脚本类型=' application/JavaScript ' src='/static/jquery-3。3 .1 .量滴js '/脚本
脚本类型=' text/JavaScript ' src='/static/recorder。js '/脚本
脚本类型='应用程序/javascript '
var reco=null
var audio _ context=新音频上下文();//音频内容对象
领航员。getuser media=(navigator。getuser media | |
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
领航员。msgetusermedia);//兼容其他浏览器
领航员。getuser media({ audio:true },create_stream,function (err) {
console.log(错误)
});
函数创建流(用户媒体){
var流输入=音频上下文。createmediastreamsource(user _ media);
reco=新记录器(stream _ input);
}
函数start_reco() {
reco。record();
}
函数ai_reco() {
reco。stop();
reco。导出wav(函数(wav _ file){
控制台。log(wav _ file);
var FormData=new FormData();//表单表单{key:value}
formdata.append('audio ',wav _ file);//表单输入类型='文件'
$.ajax({
网址:"/receive _ audio ",
类型:' post ',
processData: false,
contentType: false,
数据:formdata,
数据类型:' json ',
成功:函数(数据){
console.log(数据);
文档。getelementbyid(“player”).src='/get _ audio/'数据。文件名;
}
})
});
reco。clear();
}
/脚本
/html
2.记录器。射流研究…内容
直接复制保存即可
(函数{ if(type of exports===' object '类型的模块!=='未定义'){ module。exports=f()} else if(类型定义===' function '定义。amd){ define([],f)} else { var g;如果(窗口类型!==' undefined '){ g=window } else if(类型为全局!==' undefined '){ g=global } else if(type of self!==' undefined '){ g=self } else { g=this } g . Recorder=f()} })(function(){ var define,module,exportsreturn(函数e(t,n,r){函数s(o,u){if(!n[o]){if(!t[o]){ var a=type of require==' function ' require;如果(!ua)返回一个(o,0);如果返回i(o,0);var f=新错误('找不到模块‘o’);throw f.code='MODULE_NOT_FOUND ',f } var l=n[o]={ exports:{ } };t[o][0].call(l.exports,function(e){ var n=t[o][1][e];返回s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports } var I=需求类型==' function ' requirefor(var o=0;或。长度;o)s(r[o]);return s })({ 1:[函数(要求、模块、导出){
使用严格的;
module.exports=require(' ./记录器)。记录器;
},{'./recorder':2}],2:[函数(要求、模块、导出){
使用严格的;
var _createClass=(function () {
功能定义属性(目标、道具){
for(var I=0;我道具。长度;i ) {
var descriptor=props[I];描述符。enumerable=描述符。可枚举| | falsedescriptor . configurable=true if(descriptor中的' value ')描述符。可写=真;Object.defineProperty(target,descriptor.key,descriptor);
}
}返回函数(构造函数、protoProps、staticProps) {
if(proto props)定义属性(构造函数。原型,proto道具);if(静态属性)定义属性(构造函数,静态道具);返回构造函数;
};
})();
Object.defineProperty(导出,' __esModule ',{
值:真
});
出口。记录器=未定义;
var _ inline worker=require(' inline-worker ');
var _ inline worker 2=_ interopRequireDefault(_ inline worker);
function _ interopRequireDefault(obj){
返回对象对象__esModule?目标默认值:obj };
}
function _classCallCheck(实例,构造函数){
如果(!(构造函数的实例实例)){
抛出新类型错误(“不能将类作为函数调用");
}
}
定义变量记录器=出口。记录器=(function () {
函数记录器(源,cfg) {
var _ this=this
_classCallCheck(this,Recorder);
this.config={
巴佛伦:4096,
numChannels: 2,
mimeType: 'audio_pcm/wav '
};
this.recording=false
this.callbacks={
获取缓冲区:[],
exportWAV: []
};
Object.assign(this.config,CFG);
这个。上下文=源.上下文
这个。node=(这个。语境。createscriptprocessor | |这个。语境。创建JavaScript节点).调用(this.context,this.config.bufferLen,this.config.numChannels,this。配置。numchannels);
这个。节点。onaudioprocess=函数(e){
如果(!_this .录音)返回;
var buffer=[];
对于(var通道=0;频道_这个。配置。通道数;频道){
缓冲。按下(例如输入缓冲区。getchanneldata(channel));
}
_this.worker.postMessage({
命令:"记录",
缓冲:缓冲
});
};
来源。连接(这个。节点);
这个。节点。连接(这个。语境。目的地);//这应该没有必要
var self={ };
这个。worker=new _ inline worker 2。默认(function(){
var recLength=0,
recBuffers=[],
采样率=未定义,
numChannels=未定义
self.onmessage=function (e) {
开关(数据命令){
案例“初始化”:
初始化数据。config);
打破;
案例"记录":
记录(数据。缓冲);
打破;
案例" exportWAV ":
导出wav(电子数据。类型);
打破;
案例"获取缓冲区":
get buffer();
打破;
案例"清除":
clear();
打破;
}
};
函数初始化(配置){
sampleRate=config.sampleRate
numChannels=config。numChannels
初始化缓冲区();
}
函数记录(输入缓冲区){
对于(var通道=0;通道数;频道){
记录缓冲区[通道]。push(输入缓冲区[通道]);
}
recLength=inputBuffer[0].长度;
}
函数exportWAV(类型){
var buffers=[];
对于(var通道=0;通道数;频道){
缓冲器。push(合并缓冲区(记录缓冲区[通道],重新长度));
}
var交错=未定义;
if (numChannels===2) {
interleaved=interleave(buffers[0],buffers[1]);
}否则{
交错=缓冲区[0];
}
var dataview=encodeWAV(交错);
var audio Blob=new Blob([dataview],{ type:type });
自我。post message({ command:' export wav ',data:audio blob });
}
函数getBuffer() {
var buffers=[];
对于(var通道=0;通道数;频道){
缓冲器。push(合并缓冲区(记录缓冲区[通道],重新长度));
}
自我。post message({ command:' get buffer ',data:buffers });
}
函数clear() {
recLength=0;
记录缓冲区=[];
初始化缓冲区();
}
函数initBuffers() {
对于(var通道=0;通道数;频道){
rec buffers[channel]=[];
}
}
函数mergeBuffers(recBuffers,recLength) {
var result=new float 32 array(recLength);
var offset=0;
for(var I=0;i recBuffers.lengthi ) {
result.set(recBuffers[i],offset);
offset=recBuffers[i].长度;
}
返回结果;
}
函数交错(输入,输入){
变量长度=inputl。长度输入。长度;
var result=new Float32Array(长度);
定义变量指数=0,
输入索引=0;
而(索引长度){
result[index]=inputL[inputIndex];
结果[索引]=inputR[输入索引];
inputIndex
}
返回结果;
}
函数浮动到16位PCM(输出、偏移、输入){
for(var I=0;我输入。长度;I,offset=2) {
var s=Math.max(-1,Math.min(1,input[I]);
output.setInt16(offset,s 0?s *0x8000 : s *0x7FFF,true);
}
}
函数writeString(视图,偏移量,字符串){
for(var I=0;我字符串。长度;i ) {
view.setUint8(偏移量I,字符串。charcodeat(I));
}
}
函数encodeWAV(示例){
var buffer=新数组缓冲区(44个样本。长度* 2);
var view=新数据视图(缓冲区);
/* RIFF标识符*/
writeString(视图,0,“RIFF”);
/* RIFF块长度*/
view.setUint32(4,36 samples.length * 2,true);
/* RIFF类型*/
writeString(view,8,' WAVE ');
/*格式块标识符*/
writeString(view,12,' fmt ');
/*格式块长度*/
view.setUint32(16,16,true);
/*样本格式(原始)*/
view.setUint16(20,1,true);
/*频道计数*/
view.setUint16(22,numChannels,true);
/*采样速率*/
view.setUint32(24,sampleRate,true);
/*字节速率(采样速率*块对齐)*/
view.setUint32(28,sampleRate * 4,true);
/*块对齐(通道数*每个样本的字节数)*/
view.setUint16(32,numChannels * 2,true);
/*每个样本的位数*/
view.setUint16(34,16,true);
/*数据块标识符*/
writeString(view,36,' data ');
/*数据块长度*/
view.setUint32(40,samples.length * 2,true);
浮动到16位PCM(视图,44,示例);
返回视图;
}
},自我);
this.worker.postMessage({
命令:" init ",
配置:{
采样率:这个。语境。抽样率
numChannels:这个。配置。数字频道
}
});
这个。工人。on消息=函数(e){
var CB=_ this。回调[电子数据。命令].pop();
if (typeof cb=='function') {
CB(电子数据。数据);
}
};
}
_createClass(记录器,[{
键:"记录",
值:函数记录(){
this.recording=true
}
}, {
按键:"停止",
值:函数stop() {
this.recording=false
}
}, {
按键:"清除",
值:函数clear() {
这个。工人。postmessage({ command:' clear ' });
}
}, {
关键字:"获取缓冲区",
值:函数获取缓冲区(cb) {
CB=CB | |这个。配置。回调;
如果(!cb)抛出新错误("未设置回调");
这个。复试。获取缓冲区。推(CB);
这个。工人。postmessage({ command:' getBuffer ' });
}
}, {
关键字:" exportWAV ",
值:函数exportWAV(cb,mimeType) {
mime type=mime type | | this。配置。mime类型;
CB=CB | |这个。配置。回调;
如果(!cb)抛出新错误("未设置回调");
这个。复试。导出wav。推(CB);
this.worker.postMessage({
命令:' exportWAV ',
类型:mimeType
});
}
}], [{
键:"强制下载",
值:函数强制下载(blob,文件名){
var url=(window .URL || window.webkitURL).createObjectURL(blob);
var link=窗口。文档。createelement(' a ');
link.href=url
链接。download=filename | | '输出。wav ';
var click=文档。创建事件(“事件”);
click.initEvent('click ',true,true);
link.dispatchEvent(点击);
}
}]);
返回记录器;
})();
exports.default=记录器
},{'inline-worker':3}],3:[function(require,module,exports){
使用严格的;
module.exports=require(' ./inline-worker ');
},{'./inline-worker':4}],4:[函数(要求、模块、导出){
(功能(全局){
使用严格的;
var _ create class=(function(){ function define properties(target,props){ for(var key in props){ var prop=props[key];prop.configurable=trueif(prop。值)道具。可写=真;} Object.defineProperties(目标、道具);}返回函数(构造函数,protoProps,静态props){ if(proto props)定义属性(构造函数。原型,proto道具);if(静态属性)定义属性(构造函数,静态道具);返回构造函数;};})();
var _classCallCheck=function(实例,构造函数){如果(!(构造函数的实例instance)){抛出新类型错误('不能将类作为函数调用');} };
var WORKER_ENABLED=!(global===global.window global .统一资源定位器全局. Blob全局。工人);
var InlineWorker=(function () {
函数InlineWorker(func,self) {
var _ this=this
_classCallCheck(this,inline worker);
if (WORKER_ENABLED) {
var functionBody=func.toString().修剪()。match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\w]*?)}$/)[1];
var url=global .URL.createObjectURL(新全局. Blob([functionBody],{ type:' text/JavaScript ' });
返回新的全局。工人(网址);
}
这个自我=自我
这个。自我。postmessage=函数(数据){
setTimeout(function () {
_这个。on message({ data:data });
}, 0);
};
setTimeout(function () {
func。打电话(自己);
}, 0);
}
_createClass(InlineWorker,{
后期消息:{
值:函数邮件(数据){
var _ this=this
setTimeout(function () {
_这个。自我。on message({ data:data });
}, 0);
}
}
});
返回在线工人
})();
module.exports=InlineWorker
}).调用(这,全局类型!=='未定义?全局:自我类型!=='未定义?自我:窗口类型!=='未定义?窗口:{})
},{}]},{},[1])(1)
});
3 .烧瓶写法
.
@app.route('/')
定义索引():
返回render_template('index.html ')
@app.route('/receive_audio ',methods=['POST'])
定义接收音频():
file=request.files.get('音频)
如果文件:
文件路径=OS。路径。join(BAISE _ DIR,' data ',' %s.m4a' % uuid4())
文件.保存(文件路径)
text=baidu.auido2text(filepath)
answer=tuling.chat(正文)
res=百度. text2audio(答案)
if res.get('err_no')==200:
return {'code': 200,' filename': res.get('filename')}
return {'code': 201,' msg ':'上传失败'}
@ app。路线('/get _ audio/filename ')
def获取_音频(文件名):
返回发送文件(os.path.join(白色目录,'数据,文件名))
.
注意瓶启动互联网协议(互联网协议的缩写)写成127.0.0.1 其他地址射流研究…可能会报错
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。