From 2ec6637c8d2e3c514008dc7609112420e32f6b5e Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 05:13:14 +0000 Subject: [PATCH 01/15] add html5 demo for online ws srv --- funasr/runtime/html5/demo.gif | Bin 0 -> 233931 bytes funasr/runtime/html5/h5Server.py | 65 + funasr/runtime/html5/readme.md | 91 ++ funasr/runtime/html5/requirement.txt | 3 + funasr/runtime/html5/server.crt | 15 + funasr/runtime/html5/server.key | 15 + funasr/runtime/html5/static/index.html | 43 + funasr/runtime/html5/static/main.js | 166 ++ funasr/runtime/html5/static/pcm.js | 96 ++ funasr/runtime/html5/static/recorder-core.js | 1493 ++++++++++++++++++ funasr/runtime/html5/static/wav.js | 86 + funasr/runtime/html5/static/wsconnecter.js | 80 + 12 files changed, 2153 insertions(+) create mode 100644 funasr/runtime/html5/demo.gif create mode 100644 funasr/runtime/html5/h5Server.py create mode 100644 funasr/runtime/html5/readme.md create mode 100644 funasr/runtime/html5/requirement.txt create mode 100644 funasr/runtime/html5/server.crt create mode 100644 funasr/runtime/html5/server.key create mode 100644 funasr/runtime/html5/static/index.html create mode 100644 funasr/runtime/html5/static/main.js create mode 100644 funasr/runtime/html5/static/pcm.js create mode 100644 funasr/runtime/html5/static/recorder-core.js create mode 100644 funasr/runtime/html5/static/wav.js create mode 100644 funasr/runtime/html5/static/wsconnecter.js diff --git a/funasr/runtime/html5/demo.gif b/funasr/runtime/html5/demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..f487f2c662b1e097abe9f46bf6ce1dd6068c93fa GIT binary patch literal 233931 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®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ξ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 html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv + +##配置nginx wss协议(了解的可以跳过) +生成证书(注意这种证书并不能被所有浏览器认可,部分手动授权可以访问,最好使用其他认证的官方ssl证书) + +### 生成私钥,按照提示填写内容 +openssl genrsa -des3 -out server.key 1024 + +### 生成csr文件 ,按照提示填写内容 +openssl req -new -key server.key -out server.csr + +### 去掉pass +cp server.key server.key.org +openssl rsa -in server.key.org -out server.key + +### 生成crt文件,有效期1年(365天) +openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt + +##nginx转发配置示例 +```shell +events { [0/1548] + worker_connections 1024; + accept_mutex on; + } +http { + error_log error.log; + access_log access.log; + server { + + listen 5921 ssl http2; # nginx listen port for wss + server_name www.test.com; + + ssl_certificate /funasr/server.crt; + ssl_certificate_key /funasr/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + + location /wss/ { + + + proxy_pass http://127.0.0.1:1111/; # asr online model ws address:port + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 600s; + + } + } +``` + +## Acknowledge +1. This project is maintained by [FunASR community](https://github.com/alibaba-damo-academy/FunASR). +2. We acknowledge [爱医声](http://www.aihealthx.com/) for contributing the html5 demo. \ No newline at end of file diff --git a/funasr/runtime/html5/requirement.txt b/funasr/runtime/html5/requirement.txt new file mode 100644 index 000000000..7f8721ac9 --- /dev/null +++ b/funasr/runtime/html5/requirement.txt @@ -0,0 +1,3 @@ +flask +gevent +pyOpenSSL diff --git a/funasr/runtime/html5/server.crt b/funasr/runtime/html5/server.crt new file mode 100644 index 000000000..808b73e6e --- /dev/null +++ b/funasr/runtime/html5/server.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCAbECFCObiVAMkMlCGmMDGDFx5Nx3XYvOMA0GCSqGSIb3DQEBCwUAMGMx +CzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5n +MRAwDgYDVQQKDAdhbGliYWJhMQwwCgYDVQQLDANhc3IxEDAOBgNVBAMMB2FsaWJh +YmEwHhcNMjMwNTEyMTQzNjAxWhcNMjQwNTExMTQzNjAxWjBjMQswCQYDVQQGEwJD +TjEQMA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwH +YWxpYmFiYTEMMAoGA1UECwwDYXNyMRAwDgYDVQQDDAdhbGliYWJhMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQDEINLLMasJtJQPoesCfcwJsjiUkx3hLnoUyETS +NBrrRfjbBv6ucAgZIF+/V15IfJZR6u2ULpJN0wUg8xNQReu4kdpjSdNGuQ0aoWbc +38+VLo9UjjsoOeoeCro6b0u+GosPoEuI4t7Ky09zw+FBibD95daJ3GDY1DGCbDdL +mV/toQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAB5KNWF1XIIYD1geMsyT6/ZRnGNA +dmeUyMcwYvIlQG3boSipNk/JI4W5fFOg1O2sAqflYHmwZfmasAQsC2e5bSzHZ+PB +uMJhKYxfj81p175GumHTw5Lbp2CvFSLrnuVB0ThRdcCqEh1MDt0D3QBuBr/ZKgGS +hXtozVCgkSJzX6uD +-----END CERTIFICATE----- diff --git a/funasr/runtime/html5/server.key b/funasr/runtime/html5/server.key new file mode 100644 index 000000000..aac8b2646 --- /dev/null +++ b/funasr/runtime/html5/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDEINLLMasJtJQPoesCfcwJsjiUkx3hLnoUyETSNBrrRfjbBv6u +cAgZIF+/V15IfJZR6u2ULpJN0wUg8xNQReu4kdpjSdNGuQ0aoWbc38+VLo9Ujjso +OeoeCro6b0u+GosPoEuI4t7Ky09zw+FBibD95daJ3GDY1DGCbDdLmV/toQIDAQAB +AoGARpA0pwygp+ZDWvh7kDLoZRitCK+BkZHiNHX1ZNeAU+Oh7FOw79u43ilqqXHq +pxPEFYb7oVO8Kanhb4BlE32EmApBlvhd3SW07kn0dS7WVGsTvPFwKKpF88W8E+pc +2i8At5tr2O1DZhvqNdIN7r8FRrGQ/Hpm3ItypUdz2lZnMwECQQD3dILOMJ84O2JE +NxUwk8iOYefMJftQUO57Gm7XBVke/i3r9uajSqB2xmOvUaSyaHoJfx/mmfgfxYcD +M+Re6mERAkEAyuaV5+eD82eG2I8PgxJ2p5SOb1x5F5qpb4KuKAlfHEkdolttMwN3 +7vl1ZWUZLVu2rHnUmvbYV2gkQO1os7/DkQJBAIDYfbN2xbC12vjB5ZqhmG/qspMt +w6mSOlqG7OewtTLaDncq2/RySxMNQaJr1GHA3KpNMwMTcIq6gw472tFBIMECQF0z +fjiASEROkcp4LI/ws0BXJPZSa+1DxgDK7mTFqUK88zfY91gvh6/mNt7UibQkJM0l +SVvFd6ru03hflXC77YECQQDDQrB9ApwVOMGQw+pwbxn9p8tPYVi3oBiUfYgd1RDO +uhcRgxv7gT4BSiyI4nFBMCYyI28azTLlUiJhMr9MNUpB +-----END RSA PRIVATE KEY----- diff --git a/funasr/runtime/html5/static/index.html b/funasr/runtime/html5/static/index.html new file mode 100644 index 000000000..1cdc7d7d3 --- /dev/null +++ b/funasr/runtime/html5/static/index.html @@ -0,0 +1,43 @@ + + + + + + 语音识别 + + + + + + + + + + +
+ +
+ 语音识别结果显示: +
+ + +
+
请点击开始
+
+ + + +
+ + +
+
+ + + + + + + + + diff --git a/funasr/runtime/html5/static/main.js b/funasr/runtime/html5/static/main.js new file mode 100644 index 000000000..706658230 --- /dev/null +++ b/funasr/runtime/html5/static/main.js @@ -0,0 +1,166 @@ +/** + * Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights + * Reserved. MIT License (https://opensource.org/licenses/MIT) + */ +/* 2022-2023 by zhaoming,mali aihealthx.com */ + + +// 连接; 定义socket连接类对象与语音对象 +var wsconnecter = new WebSocketConnectMethod({msgHandle:getJsonMessage,stateHandle:getConnState}); +var audioBlob; + +// 录音; 定义录音对象,wav格式 +var rec = Recorder({ + type:"pcm", + bitRate:16, + sampleRate:16000, + onProcess:recProcess +}); + + + + +var sampleBuf=new Int16Array(); +// 定义按钮响应事件 +var btnStart = document.getElementById('btnStart'); +btnStart.onclick = start; +var btnStop = document.getElementById('btnStop'); +btnStop.onclick = stop; +btnStop.disabled = true; + + + +var rec_text="" +var info_div = document.getElementById('info_div'); + + +// 语音识别结果; 对jsonMsg数据解析,将识别结果附加到编辑框中 +function getJsonMessage( jsonMsg ) { + console.log( "message: " + JSON.parse(jsonMsg.data)['text'] ); + var rectxt=""+JSON.parse(jsonMsg.data)['text']; + var varArea=document.getElementById('varArea'); + rec_text=rec_text+rectxt.replace(/ +/g,""); + varArea.value=rec_text; + + +} + +// 连接状态响应 +function getConnState( connState ) { + if ( connState === 0 ) { + + rec.open( function(){ + rec.start(); + console.log("开始录音"); + + }); + } else if ( connState === 1 ) { + //stop(); + } else if ( connState === 2 ) { + stop(); + console.log( 'connecttion error' ); + } +} + + +// 识别启动、停止、清空操作 +function start() { + info_div.innerHTML="正在连接asr服务器,请等待..."; + // 清除显示 + clear(); + //控件状态更新 + + isRec = true; + btnStart.disabled = true; + btnStop.disabled = false; + //启动连接 + wsconnecter.wsStart(); +} + + +function stop() { + var chunk_size = new Array( 5, 10, 5 ); + var request = { + "chunk_size": chunk_size, + "wav_name": "h5", + "is_speaking": false, + "chunk_interval":10, + }; + if(sampleBuf.length>0){ + wsconnecter.wsSend(sampleBuf,false); + console.log("sampleBuf.length"+sampleBuf.length); + sampleBuf=new Int16Array(); + } + wsconnecter.wsSend( JSON.stringify(request) ,false); + + + + + + + // 控件状态更新 + isRec = false; + info_div.innerHTML="请等候..."; + btnStop.disabled = true; + setTimeout(function(){btnStart.disabled = false;info_div.innerHTML="请点击开始";}, 3000 ); + rec.stop(function(blob,duration){ + + console.log(blob); + var audioBlob = Recorder.pcm2wav(data = {sampleRate:16000, bitRate:16, blob:blob}, + function(theblob,duration){ + console.log(theblob); + var audio_record = document.getElementById('audio_record'); + audio_record.src = (window.URL||webkitURL).createObjectURL(theblob); + audio_record.controls=true; + audio_record.play(); + + + } ,function(msg){ + console.log(msg); + } + ); + + + + },function(errMsg){ + console.log("errMsg: " + errMsg); + }); + // 停止连接 + + + +} + +function clear() { + + var varArea=document.getElementById('varArea'); + + varArea.value=""; + rec_text=""; + +} + + +function recProcess( buffer, powerLevel, bufferDuration, bufferSampleRate,newBufferIdx,asyncEnd ) { + if ( isRec === true ) { + var data_48k = buffer[buffer.length-1]; + + var array_48k = new Array(data_48k); + var data_16k=Recorder.SampleData(array_48k,bufferSampleRate,16000).data; + + sampleBuf = Int16Array.from([...sampleBuf, ...data_16k]); + var chunk_size=960; // for asr chunk_size [5, 10, 5] + info_div.innerHTML=""+bufferDuration/1000+"s"; + while(sampleBuf.length>=chunk_size){ + sendBuf=sampleBuf.slice(0,chunk_size); + sampleBuf=sampleBuf.slice(chunk_size,sampleBuf.length); + wsconnecter.wsSend(sendBuf,false); + + + + } + + + + } +} \ No newline at end of file diff --git a/funasr/runtime/html5/static/pcm.js b/funasr/runtime/html5/static/pcm.js new file mode 100644 index 000000000..51c1efe2e --- /dev/null +++ b/funasr/runtime/html5/static/pcm.js @@ -0,0 +1,96 @@ +/* +pcm编码器+编码引擎 +https://github.com/xiangyuecn/Recorder + +编码原理:本编码器输出的pcm格式数据其实就是Recorder中的buffers原始数据(经过了重新采样),16位时为LE小端模式(Little Endian),并未经过任何编码处理 + +编码的代码和wav.js区别不大,pcm加上一个44字节wav头即成wav文件;所以要播放pcm就很简单了,直接转成wav文件来播放,已提供转换函数 Recorder.pcm2wav +*/ +(function(){ +"use strict"; + +Recorder.prototype.enc_pcm={ + stable:true + ,testmsg:"pcm为未封装的原始音频数据,pcm数据文件无法直接播放;支持位数8位、16位(填在比特率里面),采样率取值无限制" +}; +Recorder.prototype.pcm=function(res,True,False){ + var This=this,set=This.set + ,size=res.length + ,bitRate=set.bitRate==8?8:16; + + var buffer=new ArrayBuffer(size*(bitRate/8)); + var data=new DataView(buffer); + var offset=0; + + // 写入采样数据 + if(bitRate==8) { + for(var i=0;i>8)+128; + data.setInt8(offset,val,true); + }; + }else{ + for (var i=0;i=pcmSampleRate时不会进行任何处理,小于时会进行重新采样 +prevChunkInfo:{} 可选,上次调用时的返回值,用于连续转换,本次调用将从上次结束位置开始进行处理。或可自行定义一个ChunkInfo从pcmDatas指定的位置开始进行转换 +option:{ 可选,配置项 + frameSize:123456 帧大小,每帧的PCM Int16的数量,采样率转换后的pcm长度为frameSize的整数倍,用于连续转换。目前仅在mp3格式时才有用,frameSize取值为1152,这样编码出来的mp3时长和pcm的时长完全一致,否则会因为mp3最后一帧录音不够填满时添加填充数据导致mp3的时长变长。 + frameType:"" 帧类型,一般为rec.set.type,提供此参数时无需提供frameSize,会自动使用最佳的值给frameSize赋值,目前仅支持mp3=1152(MPEG1 Layer3的每帧采采样数),其他类型=1。 + 以上两个参数用于连续转换时使用,最多使用一个,不提供时不进行帧的特殊处理,提供时必须同时提供prevChunkInfo才有作用。最后一段数据处理时无需提供帧大小以便输出最后一丁点残留数据。 + } + +返回ChunkInfo:{ + //可定义,从指定位置开始转换到结尾 + index:0 pcmDatas已处理到的索引 + offset:0.0 已处理到的index对应的pcm中的偏移的下一个位置 + + //仅作为返回值 + frameNext:null||[Int16,...] 下一帧的部分数据,frameSize设置了的时候才可能会有 + sampleRate:16000 结果的采样率,<=newSampleRate + data:[Int16,...] 转换后的PCM结果;如果是连续转换,并且pcmDatas中并没有新数据时,data的长度可能为0 +} +*/ +Recorder.SampleData=function(pcmDatas,pcmSampleRate,newSampleRate,prevChunkInfo,option){ + prevChunkInfo||(prevChunkInfo={}); + var index=prevChunkInfo.index||0; + var offset=prevChunkInfo.offset||0; + + var frameNext=prevChunkInfo.frameNext||[]; + option||(option={}); + var frameSize=option.frameSize||1; + if(option.frameType){ + frameSize=option.frameType=="mp3"?1152:1; + }; + + var nLen=pcmDatas.length; + if(index>nLen+1){ + CLog("SampleData似乎传入了未重置chunk "+index+">"+nLen,3); + }; + var size=0; + for(var i=index;i1){//新采样低于录音采样,进行抽样 + size=Math.floor(size/step); + }else{//新采样高于录音采样不处理,省去了插值处理 + step=1; + newSampleRate=pcmSampleRate; + }; + + size+=frameNext.length; + var res=new Int16Array(size); + var idx=0; + //添加上一次不够一帧的剩余数据 + for(var i=0;i0){ + var u8Pos=(res.length-frameNextSize)*2; + frameNext=new Int16Array(res.buffer.slice(u8Pos)); + res=new Int16Array(res.buffer.slice(0,u8Pos)); + }; + + return { + index:index + ,offset:offset + + ,frameNext:frameNext + ,sampleRate:newSampleRate + ,data:res + }; +}; + + +/*计算音量百分比的一个方法 +pcmAbsSum: pcm Int16所有采样的绝对值的和 +pcmLength: pcm长度 +返回值:0-100,主要当做百分比用 +注意:这个不是分贝,因此没用volume当做名称*/ +Recorder.PowerLevel=function(pcmAbsSum,pcmLength){ + /*计算音量 https://blog.csdn.net/jody1989/article/details/73480259 + 更高灵敏度算法: + 限定最大感应值10000 + 线性曲线:低音量不友好 + power/10000*100 + 对数曲线:低音量友好,但需限定最低感应值 + (1+Math.log10(power/10000))*100 + */ + var power=(pcmAbsSum/pcmLength) || 0;//NaN + var level; + if(power<1251){//1250的结果10%,更小的音量采用线性取值 + level=Math.round(power/1250*10); + }else{ + level=Math.round(Math.min(100,Math.max(0,(1+Math.log(power/10000)/Math.log(10))*100))); + }; + return level; +}; + +/*计算音量,单位dBFS(满刻度相对电平) +maxSample: 为16位pcm采样的绝对值中最大的一个(计算峰值音量),或者为pcm中所有采样的绝对值的平局值 +返回值:-100~0 (最大值0dB,最小值-100代替-∞) +*/ +Recorder.PowerDBFS=function(maxSample){ + var val=Math.max(0.1, maxSample||0),Pref=0x7FFF; + val=Math.min(val,Pref); + //https://www.logiclocmusic.com/can-you-tell-the-decibel/ + //https://blog.csdn.net/qq_17256689/article/details/120442510 + val=20*Math.log(val/Pref)/Math.log(10); + return Math.max(-100,Math.round(val)); +}; + + + + +//带时间的日志输出,可设为一个空函数来屏蔽日志输出 +//CLog(msg,errOrLogMsg, logMsg...) err为数字时代表日志类型1:error 2:log默认 3:warn,否则当做内容输出,第一个参数不能是对象因为要拼接时间,后面可以接无数个输出参数 +Recorder.CLog=function(msg,err){ + var now=new Date(); + var t=("0"+now.getMinutes()).substr(-2) + +":"+("0"+now.getSeconds()).substr(-2) + +"."+("00"+now.getMilliseconds()).substr(-3); + var recID=this&&this.envIn&&this.envCheck&&this.id; + var arr=["["+t+" "+RecTxt+(recID?":"+recID:"")+"]"+msg]; + var a=arguments,console=window.console||{}; + var i=2,fn=console.log; + if(typeof(err)=="number"){ + fn=err==1?console.error:err==3?console.warn:fn; + }else{ + i=1; + }; + for(;i1?arr:""); + }else{ + fn.apply(console,arr); + }; +}; +var CLog=function(){ Recorder.CLog.apply(this,arguments); }; +var IsLoser=true;try{IsLoser=!console.log.apply;}catch(e){}; + + + + +var ID=0; +function initFn(set){ + this.id=++ID; + + //如果开启了流量统计,这里将发送一个图片请求 + Traffic(); + + + var o={ + type:"mp3" //输出类型:mp3,wav,wav输出文件尺寸超大不推荐使用,但mp3编码支持会导致js文件超大,如果不需支持mp3可以使js文件大幅减小 + ,bitRate:16 //比特率 wav:16或8位,MP3:8kbps 1k/s,8kbps 2k/s 录音文件很小 + + ,sampleRate:16000 //采样率,wav格式大小=sampleRate*时间;mp3此项对低比特率有影响,高比特率几乎无影响。 + //wav任意值,mp3取值范围:48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 + //采样率参考https://www.cnblogs.com/devin87/p/mp3-recorder.html + + ,onProcess:NOOP //fn(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd) buffers=[[Int16,...],...]:缓冲的PCM数据,为从开始录音到现在的所有pcm片段;powerLevel:当前缓冲的音量级别0-100,bufferDuration:已缓冲时长,bufferSampleRate:缓冲使用的采样率(当type支持边录边转码(Worker)时,此采样率和设置的采样率相同,否则不一定相同);newBufferIdx:本次回调新增的buffer起始索引;asyncEnd:fn() 如果onProcess是异步的(返回值为true时),处理完成时需要调用此回调,如果不是异步的请忽略此参数,此方法回调时必须是真异步(不能真异步时需用setTimeout包裹)。onProcess返回值:如果返回true代表开启异步模式,在某些大量运算的场合异步是必须的,必须在异步处理完成时调用asyncEnd(不能真异步时需用setTimeout包裹),在onProcess执行后新增的buffer会全部替换成空数组,因此本回调开头应立即将newBufferIdx到本次回调结尾位置的buffer全部保存到另外一个数组内,处理完成后写回buffers中本次回调的结尾位置。 + + //*******高级设置****** + //,sourceStream:MediaStream Object + //可选直接提供一个媒体流,从这个流中录制、实时处理音频数据(当前Recorder实例独享此流);不提供时为普通的麦克风录音,由getUserMedia提供音频流(所有Recorder实例共享同一个流) + //比如:audio、video标签dom节点的captureStream方法(实验特性,不同浏览器支持程度不高)返回的流;WebRTC中的remote流;自己创建的流等 + //注意:流内必须至少存在一条音轨(Audio Track),比如audio标签必须等待到可以开始播放后才会有音轨,否则open会失败 + + //,audioTrackSet:{ deviceId:"",groupId:"", autoGainControl:true, echoCancellation:true, noiseSuppression:true } + //普通麦克风录音时getUserMedia方法的audio配置参数,比如指定设备id,回声消除、降噪开关;注意:提供的任何配置值都不一定会生效 + //由于麦克风是全局共享的,所以新配置后需要close掉以前的再重新open + //更多参考: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints + + //,disableEnvInFix:false 内部参数,禁用设备卡顿时音频输入丢失补偿功能 + + //,takeoffEncodeChunk:NOOP //fn(chunkBytes) chunkBytes=[Uint8,...]:实时编码环境下接管编码器输出,当编码器实时编码出一块有效的二进制音频数据时实时回调此方法;参数为二进制的Uint8Array,就是编码出来的音频数据片段,所有的chunkBytes拼接在一起即为完整音频。本实现的想法最初由QQ2543775048提出 + //当提供此回调方法时,将接管编码器的数据输出,编码器内部将放弃存储生成的音频数据;环境要求比较苛刻:如果当前环境不支持实时编码处理,将在open时直接走fail逻辑 + //因此提供此回调后调用stop方法将无法获得有效的音频数据,因为编码器内没有音频数据,因此stop时返回的blob将是一个字节长度为0的blob + //目前只有mp3格式实现了实时编码,在支持实时处理的环境中将会实时的将编码出来的mp3片段通过此方法回调,所有的chunkBytes拼接到一起即为完整的mp3,此种拼接的结果比mock方法实时生成的音质更加,因为天然避免了首尾的静默 + //目前除mp3外其他格式不可以提供此回调,提供了将在open时直接走fail逻辑 + }; + + for(var k in set){ + o[k]=set[k]; + }; + this.set=o; + + this._S=9;//stop同步锁,stop可以阻止open过程中还未运行的start + this.Sync={O:9,C:9};//和Recorder.Sync一致,只不过这个是非全局的,仅用来简化代码逻辑,无实际作用 +}; +//同步锁,控制对Stream的竞争;用于close时中断异步的open;一个对象open如果变化了都要阻止close,Stream的控制权交个新的对象 +Recorder.Sync={/*open*/O:9,/*close*/C:9}; + +Recorder.prototype=initFn.prototype={ + CLog:CLog + + //流相关的数据存储在哪个对象里面;如果提供了sourceStream,数据直接存储在当前对象中,否则存储在全局 + ,_streamStore:function(){ + if(this.set.sourceStream){ + return this; + }else{ + return Recorder; + } + } + + //打开录音资源True(),False(msg,isUserNotAllow),需要调用close。注意:此方法是异步的;一般使用时打开,用完立即关闭;可重复调用,可用来测试是否能录音 + ,open:function(True,False){ + var This=this,streamStore=This._streamStore(); + True=True||NOOP; + var failCall=function(errMsg,isUserNotAllow){ + isUserNotAllow=!!isUserNotAllow; + This.CLog("录音open失败:"+errMsg+",isUserNotAllow:"+isUserNotAllow,1); + False&&False(errMsg,isUserNotAllow); + }; + + var ok=function(){ + This.CLog("open ok id:"+This.id); + True(); + + This._SO=0;//解除stop对open中的start调用的阻止 + }; + + + //同步锁 + var Lock=streamStore.Sync; + var lockOpen=++Lock.O,lockClose=Lock.C; + This._O=This._O_=lockOpen;//记住当前的open,如果变化了要阻止close,这里假定了新对象已取代当前对象并且不再使用 + This._SO=This._S;//记住open过程中的stop,中途任何stop调用后都不能继续open中的start + var lockFail=function(){ + //允许多次open,但不允许任何一次close,或者自身已经调用了关闭 + if(lockClose!=Lock.C || !This._O){ + var err="open被取消"; + if(lockOpen==Lock.O){ + //无新的open,已经调用了close进行取消,此处应让上次的close明确生效 + This.close(); + }else{ + err="open被中断"; + }; + failCall(err); + return true; + }; + }; + + //环境配置检查 + var checkMsg=This.envCheck({envName:"H5",canProcess:true}); + if(checkMsg){ + failCall("不能录音:"+checkMsg); + return; + }; + + + //***********已直接提供了音频流************ + if(This.set.sourceStream){ + if(!Recorder.GetContext()){ + failCall("不支持此浏览器从流中获取录音"); + return; + }; + + Disconnect(streamStore);//可能已open过,直接先尝试断开 + This.Stream=This.set.sourceStream; + This.Stream._call={}; + + try{ + Connect(streamStore); + }catch(e){ + failCall("从流中打开录音失败:"+e.message); + return; + } + ok(); + return; + }; + + + //***********打开麦克风得到全局的音频流************ + var codeFail=function(code,msg){ + try{//跨域的优先检测一下 + window.top.a; + }catch(e){ + failCall('无权录音(跨域,请尝试给iframe添加麦克风访问策略,如allow="camera;microphone")'); + return; + }; + + if(/Permission|Allow/i.test(code)){ + failCall("用户拒绝了录音权限",true); + }else if(window.isSecureContext===false){ + failCall("浏览器禁止不安全页面录音,可开启https解决"); + }else if(/Found/i.test(code)){//可能是非安全环境导致的没有设备 + failCall(msg+",无可用麦克风"); + }else{ + failCall(msg); + }; + }; + + + //如果已打开并且有效就不要再打开了 + if(Recorder.IsOpen()){ + ok(); + return; + }; + if(!Recorder.Support()){ + codeFail("","此浏览器不支持录音"); + return; + }; + + //请求权限,如果从未授权,一般浏览器会弹出权限请求弹框 + var f1=function(stream){ + //https://github.com/xiangyuecn/Recorder/issues/14 获取到的track.readyState!="live",刚刚回调时可能是正常的,但过一下可能就被关掉了,原因不明。延迟一下保证真异步。对正常浏览器不影响 + setTimeout(function(){ + stream._call={}; + var oldStream=Recorder.Stream; + if(oldStream){ + Disconnect(); //直接断开已存在的,旧的Connect未完成会自动终止 + stream._call=oldStream._call; + }; + Recorder.Stream=stream; + if(lockFail())return; + + if(Recorder.IsOpen()){ + if(oldStream)This.CLog("发现同时多次调用open",1); + + Connect(streamStore,1); + ok(); + }else{ + failCall("录音功能无效:无音频流"); + }; + },100); + }; + var f2=function(e){ + var code=e.name||e.message||e.code+":"+e; + This.CLog("请求录音权限错误",1,e); + + codeFail(code,"无法录音:"+code); + }; + + var trackSet={ + noiseSuppression:false //默认禁用降噪,原声录制,免得移动端表现怪异(包括系统播放声音变小) + ,echoCancellation:false //回声消除 + }; + var trackSet2=This.set.audioTrackSet; + for(var k in trackSet2)trackSet[k]=trackSet2[k]; + trackSet.sampleRate=Recorder.Ctx.sampleRate;//必须指明采样率,不然手机上MediaRecorder采样率16k + + try{ + var pro=Recorder.Scope[getUserMediaTxt]({audio:trackSet},f1,f2); + }catch(e){//不能设置trackSet就算了 + This.CLog(getUserMediaTxt,3,e); + pro=Recorder.Scope[getUserMediaTxt]({audio:true},f1,f2); + }; + if(pro&&pro.then){ + pro.then(f1)[CatchTxt](f2); //fix 关键字,保证catch压缩时保持字符串形式 + }; + } + //关闭释放录音资源 + ,close:function(call){ + call=call||NOOP; + + var This=this,streamStore=This._streamStore(); + This._stop(); + + var Lock=streamStore.Sync; + This._O=0; + if(This._O_!=Lock.O){ + //唯一资源Stream的控制权已交给新对象,这里不能关闭。此处在每次都弹权限的浏览器内可能存在泄漏,新对象被拒绝权限可能不会调用close,忽略这种不处理 + This.CLog("close被忽略(因为同时open了多个rec,只有最后一个会真正close)",3); + call(); + return; + }; + Lock.C++;//获得控制权 + + Disconnect(streamStore); + + This.CLog("close"); + call(); + } + + + + + + /*模拟一段录音数据,后面可以调用stop进行编码,需提供pcm数据[1,2,3...],pcm的采样率*/ + ,mock:function(pcmData,pcmSampleRate){ + var This=this; + This._stop();//清理掉已有的资源 + + This.isMock=1; + This.mockEnvInfo=null; + This.buffers=[pcmData]; + This.recSize=pcmData.length; + This[srcSampleRateTxt]=pcmSampleRate; + return This; + } + ,envCheck:function(envInfo){//平台环境下的可用性检查,任何时候都可以调用检查,返回errMsg:""正常,"失败原因" + //envInfo={envName:"H5",canProcess:true} + var errMsg,This=this,set=This.set; + + //检测CPU的数字字节序,TypedArray字节序是个迷,直接拒绝罕见的大端模式,因为找不到这种CPU进行测试 + var tag="CPU_BE"; + if(!errMsg && !Recorder[tag] && window.Int8Array && !new Int8Array(new Int32Array([1]).buffer)[0]){ + Traffic(tag); //如果开启了流量统计,这里将发送一个图片请求 + errMsg="不支持"+tag+"架构"; + }; + + //编码器检查环境下配置是否可用 + if(!errMsg){ + var type=set.type; + if(This[type+"_envCheck"]){//编码器已实现环境检查 + errMsg=This[type+"_envCheck"](envInfo,set); + }else{//未实现检查的手动检查配置是否有效 + if(set.takeoffEncodeChunk){ + errMsg=type+"类型"+(This[type]?"":"(未加载编码器)")+"不支持设置takeoffEncodeChunk"; + }; + }; + }; + + return errMsg||""; + } + ,envStart:function(mockEnvInfo,sampleRate){//平台环境相关的start调用 + var This=this,set=This.set; + This.isMock=mockEnvInfo?1:0;//非H5环境需要启用mock,并提供envCheck需要的环境信息 + This.mockEnvInfo=mockEnvInfo; + This.buffers=[];//数据缓冲 + This.recSize=0;//数据大小 + + This.envInLast=0;//envIn接收到最后录音内容的时间 + This.envInFirst=0;//envIn接收到的首个录音内容的录制时间 + This.envInFix=0;//补偿的总时间 + This.envInFixTs=[];//补偿计数列表 + + //engineCtx需要提前确定最终的采样率 + var setSr=set[sampleRateTxt]; + if(setSr>sampleRate){ + set[sampleRateTxt]=sampleRate; + }else{ setSr=0 } + This[srcSampleRateTxt]=sampleRate; + This.CLog(srcSampleRateTxt+": "+sampleRate+" set."+sampleRateTxt+": "+set[sampleRateTxt]+(setSr?" 忽略"+setSr:""), setSr?3:0); + + This.engineCtx=0; + //此类型有边录边转码(Worker)支持 + if(This[set.type+"_start"]){ + var engineCtx=This.engineCtx=This[set.type+"_start"](set); + if(engineCtx){ + engineCtx.pcmDatas=[]; + engineCtx.pcmSize=0; + }; + }; + } + ,envResume:function(){//和平台环境无关的恢复录音 + //重新开始计数 + this.envInFixTs=[]; + } + ,envIn:function(pcm,sum){//和平台环境无关的pcm[Int16]输入 + var This=this,set=This.set,engineCtx=This.engineCtx; + var bufferSampleRate=This[srcSampleRateTxt]; + var size=pcm.length; + var powerLevel=Recorder.PowerLevel(sum,size); + + var buffers=This.buffers; + var bufferFirstIdx=buffers.length;//之前的buffer都是经过onProcess处理好的,不允许再修改 + buffers.push(pcm); + + //有engineCtx时会被覆盖,这里保存一份 + var buffersThis=buffers; + var bufferFirstIdxThis=bufferFirstIdx; + + //卡顿丢失补偿:因为设备很卡的时候导致H5接收到的数据量不够造成播放时候变速,结果比实际的时长要短,此处保证了不会变短,但不能修复丢失的音频数据造成音质变差。当前算法采用输入时间侦测下一帧是否需要添加补偿帧,需要(6次输入||超过1秒)以上才会开始侦测,如果滑动窗口内丢失超过1/3就会进行补偿 + var now=Date.now(); + var pcmTime=Math.round(size/bufferSampleRate*1000); + This.envInLast=now; + if(This.buffers.length==1){//记下首个录音数据的录制时间 + This.envInFirst=now-pcmTime; + }; + var envInFixTs=This.envInFixTs; + envInFixTs.splice(0,0,{t:now,d:pcmTime}); + //保留3秒的计数滑动窗口,另外超过3秒的停顿不补偿 + var tsInStart=now,tsPcm=0; + for(var i=0;i3000){ + envInFixTs.length=i; + break; + }; + tsInStart=o.t; + tsPcm+=o.d; + }; + //达到需要的数据量,开始侦测是否需要补偿 + var tsInPrev=envInFixTs[1]; + var tsIn=now-tsInStart; + var lost=tsIn-tsPcm; + if( lost>tsIn/3 && (tsInPrev&&tsIn>1000 || envInFixTs.length>=6) ){ + //丢失过多,开始执行补偿 + var addTime=now-tsInPrev.t-pcmTime;//距离上次输入丢失这么多ms + if(addTime>pcmTime/5){//丢失超过本帧的1/5 + var fixOpen=!set.disableEnvInFix; + This.CLog("["+now+"]"+(fixOpen?"":"未")+"补偿"+addTime+"ms",3); + This.envInFix+=addTime; + + //用静默进行补偿 + if(fixOpen){ + var addPcm=new Int16Array(addTime*bufferSampleRate/1000); + size+=addPcm.length; + buffers.push(addPcm); + }; + }; + }; + + + var sizeOld=This.recSize,addSize=size; + var bufferSize=sizeOld+addSize; + This.recSize=bufferSize;//此值在onProcess后需要修正,可能新数据被修改 + + + //此类型有边录边转码(Worker)支持,开启实时转码 + if(engineCtx){ + //转换成set的采样率 + var chunkInfo=Recorder.SampleData(buffers,bufferSampleRate,set[sampleRateTxt],engineCtx.chunkInfo); + engineCtx.chunkInfo=chunkInfo; + + sizeOld=engineCtx.pcmSize; + addSize=chunkInfo.data.length; + bufferSize=sizeOld+addSize; + engineCtx.pcmSize=bufferSize;//此值在onProcess后需要修正,可能新数据被修改 + + buffers=engineCtx.pcmDatas; + bufferFirstIdx=buffers.length; + buffers.push(chunkInfo.data); + bufferSampleRate=chunkInfo[sampleRateTxt]; + }; + + var duration=Math.round(bufferSize/bufferSampleRate*1000); + var bufferNextIdx=buffers.length; + var bufferNextIdxThis=buffersThis.length; + + //允许异步处理buffer数据 + var asyncEnd=function(){ + //重新计算size,异步的早已减去添加的,同步的需去掉本次添加的然后重新计算 + var num=asyncBegin?0:-addSize; + var hasClear=buffers[0]==null; + for(var i=bufferFirstIdx;i10 && This.envInFirst-now>1000){ //1秒后开始onProcess性能监测 + This.CLog(procTxt+"低性能,耗时"+slowT+"ms",3); + }; + + if(asyncBegin===true){ + //开启了异步模式,onProcess已接管buffers新数据,立即清空,避免出现未处理的数据 + var hasClear=0; + for(var i=bufferFirstIdx;i"+res.length+" 花:"+(Date.now()-t1)+"ms"); + + setTimeout(function(){ + t1=Date.now(); + This[set.type](res,function(blob){ + ok(blob,duration); + },function(msg){ + err(msg); + }); + }); + } + +}; + +if(window[RecTxt]){ + CLog("重复引入"+RecTxt,3); + window[RecTxt].Destroy(); +}; +window[RecTxt]=Recorder; + + + + +//=======从WebM字节流中提取pcm数据,提取成功返回Float32Array,失败返回null||-1===== +var WebM_Extract=function(inBytes, scope){ + if(!scope.pos){ + scope.pos=[0]; scope.tracks={}; scope.bytes=[]; + }; + var tracks=scope.tracks, position=[scope.pos[0]]; + var endPos=function(){ scope.pos[0]=position[0] }; + + var sBL=scope.bytes.length; + var bytes=new Uint8Array(sBL+inBytes.length); + bytes.set(scope.bytes); bytes.set(inBytes,sBL); + scope.bytes=bytes; + + //先读取文件头和Track信息 + if(!scope._ht){ + readMatroskaVInt(bytes, position);//EBML Header + readMatroskaBlock(bytes, position);//跳过EBML Header内容 + if(!BytesEq(readMatroskaVInt(bytes, position), [0x18,0x53,0x80,0x67])){ + return;//未识别到Segment + } + readMatroskaVInt(bytes, position);//跳过Segment长度值 + while(position[0]1){//多声道,提取一个声道 + var arr2=[]; + for(var i=0;i=arr.length)return; + var b0=arr[i],b2=("0000000"+b0.toString(2)).substr(-8); + var m=/^(0*1)(\d*)$/.exec(b2); + if(!m)return; + var len=m[1].length, val=[]; + if(i+len>arr.length)return; + for(var i2=0;i2arr.length)return; + for(var i2=0;i2>8)+128; + data.setInt8(offset,val,true); + }; + }else{ + for (var i=0;i Date: Mon, 15 May 2023 05:26:23 +0000 Subject: [PATCH 02/15] change demo gif url --- funasr/runtime/html5/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index 917865b05..e1dcfb619 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -29,7 +29,7 @@ https://127.0.0.1:1337/static/index.html ### demo页面如下 -![img](https://github.com/zhaomingwork/FunASR/tree/for-html5-demo/funasr/runtime/html5/demo.gif) +![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) ##后端配置 From 98c71103ae3cbf76c34191ce988157987d62a5c9 Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 05:28:21 +0000 Subject: [PATCH 03/15] little change --- funasr/runtime/html5/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index e1dcfb619..d354f61b6 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -32,13 +32,13 @@ https://127.0.0.1:1337/static/index.html ![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) -##后端配置 +## 后端配置 h5打开麦克风需要https协议,同时后端的asr websocket也必须是wss协议,而目前[online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket)模型只支持ws协议,所以我们通过nginx配置实现wss协议到ws协议的转换。 -##具体过程如下: +## 具体过程如下: 浏览器htts --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv -##配置nginx wss协议(了解的可以跳过) +## 配置nginx wss协议(了解的可以跳过) 生成证书(注意这种证书并不能被所有浏览器认可,部分手动授权可以访问,最好使用其他认证的官方ssl证书) ### 生成私钥,按照提示填写内容 @@ -54,7 +54,7 @@ openssl rsa -in server.key.org -out server.key ### 生成crt文件,有效期1年(365天) openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -##nginx转发配置示例 +## nginx转发配置示例 ```shell events { [0/1548] worker_connections 1024; From c8fe32c5bc0d7ec434d4cbce9f38bd0e1617c93a Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 07:00:16 +0000 Subject: [PATCH 04/15] change readme for more detail --- funasr/runtime/html5/readme.md | 44 +++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index d354f61b6..92c63d305 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -9,42 +9,53 @@ pyOpenSSL ``` ### javascript +[html5录音](https://github.com/xiangyuecn/Recorder) ```shell -Recorder [html5录音](https://github.com/xiangyuecn/Recorder) +Recorder ``` -## html5服务配置 -### 启动html5服务 + +### demo页面如下 +![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) + +## 具体数据流向: +浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv + +## 1.html5 demo服务启动 +### 启动html5服务,需要ssl证书(自己生成请往后看) ```shell usage: h5Server.py [-h] [--host HOST] [--port PORT] [--certfile CERTFILE] [--keyfile KEYFILE] python h5Server.py --port 1337 ``` -注: -wsconnecter.js里配置online asr wss路径 +## 2.启动ws asr online srv +[具体请看online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) +目前online asr只提供ws接口,需要通过nginx将wss转发到该online asr端口上 + +## 3.修改wsconnecter.js里asr接口地址 +wsconnecter.js里配置online asr服务地址路径,这里配置的是nginx的wss端口) var Uri = "wss://xxx:xxx/" -### 浏览器打开地址 +## 4.配置nginx并启动 + +## 5.浏览器打开地址测试 https://127.0.0.1:1337/static/index.html -### demo页面如下 -![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) -## 后端配置 + +## nginx配置说明(了解的可以跳过) h5打开麦克风需要https协议,同时后端的asr websocket也必须是wss协议,而目前[online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket)模型只支持ws协议,所以我们通过nginx配置实现wss协议到ws协议的转换。 -## 具体过程如下: -浏览器htts --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv - -## 配置nginx wss协议(了解的可以跳过) +## 自行生成证书 生成证书(注意这种证书并不能被所有浏览器认可,部分手动授权可以访问,最好使用其他认证的官方ssl证书) -### 生成私钥,按照提示填写内容 +```shell +### 1)生成私钥,按照提示填写内容 openssl genrsa -des3 -out server.key 1024 -### 生成csr文件 ,按照提示填写内容 +### 2)生成csr文件 ,按照提示填写内容 openssl req -new -key server.key -out server.csr ### 去掉pass @@ -53,6 +64,7 @@ openssl rsa -in server.key.org -out server.key ### 生成crt文件,有效期1年(365天) openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt +``` ## nginx转发配置示例 ```shell @@ -76,7 +88,7 @@ http { location /wss/ { - proxy_pass http://127.0.0.1:1111/; # asr online model ws address:port + proxy_pass http://127.0.0.1:1111/; # asr online model ws address and port proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; From d3c47020b6abd8de93b720fba823229018507a95 Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 07:05:30 +0000 Subject: [PATCH 05/15] little change --- funasr/runtime/html5/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index 92c63d305..1c30cd3c0 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -33,7 +33,7 @@ python h5Server.py --port 1337 目前online asr只提供ws接口,需要通过nginx将wss转发到该online asr端口上 ## 3.修改wsconnecter.js里asr接口地址 -wsconnecter.js里配置online asr服务地址路径,这里配置的是nginx的wss端口) +wsconnecter.js里配置online asr服务地址路径,这里配置的是nginx的wss端口 var Uri = "wss://xxx:xxx/" ## 4.配置nginx并启动 From 00de4511009a7fbbb88142b2b2a0faeaa0e3e7d9 Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 14:05:26 +0000 Subject: [PATCH 06/15] add ws_server_online support wss --- funasr/runtime/html5/readme.md | 22 +++++++++++-------- funasr/runtime/html5/static/main.js | 1 + funasr/runtime/html5/static/wsconnecter.js | 1 + .../python/websocket/ws_server_online.py | 13 +++++++++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index 1c30cd3c0..d52ace5ed 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -17,9 +17,15 @@ Recorder ### demo页面如下 ![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) -## 具体数据流向: -浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv - +## 两种ws_server_online连接模式 +### 1)直接连接模式,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> wss asr online srv(证书生成请往后看) +```shell +python ws_server_online.py --certfile server.crt --keyfile server.key --port 5921 +``` +### 2)nginx中转,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv +```shell +python ws_server_online.py --port 5921 +``` ## 1.html5 demo服务启动 ### 启动html5服务,需要ssl证书(自己生成请往后看) @@ -28,17 +34,15 @@ usage: h5Server.py [-h] [--host HOST] [--port PORT] [--certfile CERTFILE] [--keyfile KEYFILE] python h5Server.py --port 1337 ``` -## 2.启动ws asr online srv +## 2.启动ws or wss asr online srv [具体请看online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) -目前online asr只提供ws接口,需要通过nginx将wss转发到该online asr端口上 +online asr只提供两种ws和wss模式,wss模式可以直接启动,无需nginx中转。否则需要通过nginx将wss转发到该online asr的ws端口上 ## 3.修改wsconnecter.js里asr接口地址 -wsconnecter.js里配置online asr服务地址路径,这里配置的是nginx的wss端口 +wsconnecter.js里配置online asr服务地址路径,这里配置的是wss端口 var Uri = "wss://xxx:xxx/" -## 4.配置nginx并启动 - -## 5.浏览器打开地址测试 +## 4.浏览器打开地址测试 https://127.0.0.1:1337/static/index.html diff --git a/funasr/runtime/html5/static/main.js b/funasr/runtime/html5/static/main.js index 706658230..5f6bb108b 100644 --- a/funasr/runtime/html5/static/main.js +++ b/funasr/runtime/html5/static/main.js @@ -59,6 +59,7 @@ function getConnState( connState ) { } else if ( connState === 2 ) { stop(); console.log( 'connecttion error' ); + setTimeout(function(){btnStart.disabled = true;info_div.innerHTML='connecttion error';}, 4000 ); } } diff --git a/funasr/runtime/html5/static/wsconnecter.js b/funasr/runtime/html5/static/wsconnecter.js index a4c2f2202..4b22e8f08 100644 --- a/funasr/runtime/html5/static/wsconnecter.js +++ b/funasr/runtime/html5/static/wsconnecter.js @@ -72,6 +72,7 @@ function WebSocketConnectMethod( config ) { //定义socket连接方法类 } function onError( e ) { + info_div.innerHTML="连接"+e; console.log(e); stateHandle(2); } diff --git a/funasr/runtime/python/websocket/ws_server_online.py b/funasr/runtime/python/websocket/ws_server_online.py index a35b127cc..ba50f6287 100644 --- a/funasr/runtime/python/websocket/ws_server_online.py +++ b/funasr/runtime/python/websocket/ws_server_online.py @@ -7,7 +7,7 @@ import threading import logging import tracemalloc import numpy as np - +import ssl from parse_args import args from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks @@ -94,7 +94,16 @@ async def async_asr_online(websocket,audio_in): await websocket.send(message) +if len(args.certfile)>0: + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) -start_server = websockets.serve(ws_serve, args.host, args.port, subprotocols=["binary"], ping_interval=None) + # Generate with Lets Encrypt, copied to this location, chown to current user and 400 permissions + ssl_cert = args.certfile + ssl_key = args.keyfile + + ssl_context.load_cert_chain(ssl_cert, keyfile=ssl_key) + start_server = websockets.serve(ws_serve, args.host, args.port, subprotocols=["binary"], ping_interval=None,ssl=ssl_context) +else: + start_server = websockets.serve(ws_serve, args.host, args.port, subprotocols=["binary"], ping_interval=None) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever() \ No newline at end of file From 937ffec5531a040ee109f9d7ea165af45042cd28 Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 14:15:54 +0000 Subject: [PATCH 07/15] change readme.md --- funasr/runtime/html5/readme.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index d52ace5ed..a914dd782 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -19,13 +19,9 @@ Recorder ## 两种ws_server_online连接模式 ### 1)直接连接模式,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> wss asr online srv(证书生成请往后看) -```shell -python ws_server_online.py --certfile server.crt --keyfile server.key --port 5921 -``` + ### 2)nginx中转,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv -```shell -python ws_server_online.py --port 5921 -``` + ## 1.html5 demo服务启动 ### 启动html5服务,需要ssl证书(自己生成请往后看) @@ -36,8 +32,15 @@ python h5Server.py --port 1337 ``` ## 2.启动ws or wss asr online srv [具体请看online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) -online asr只提供两种ws和wss模式,wss模式可以直接启动,无需nginx中转。否则需要通过nginx将wss转发到该online asr的ws端口上 - +online asr提供两种ws和wss模式,wss模式可以直接启动,无需nginx中转。否则需要通过nginx将wss转发到该online asr的ws端口上 +### wss方式 +```shell +python ws_server_online.py --certfile server.crt --keyfile server.key --port 5921 +``` +### ws方式 +```shell +python ws_server_online.py --port 5921 +``` ## 3.修改wsconnecter.js里asr接口地址 wsconnecter.js里配置online asr服务地址路径,这里配置的是wss端口 var Uri = "wss://xxx:xxx/" @@ -48,10 +51,6 @@ https://127.0.0.1:1337/static/index.html - -## nginx配置说明(了解的可以跳过) -h5打开麦克风需要https协议,同时后端的asr websocket也必须是wss协议,而目前[online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket)模型只支持ws协议,所以我们通过nginx配置实现wss协议到ws协议的转换。 - ## 自行生成证书 生成证书(注意这种证书并不能被所有浏览器认可,部分手动授权可以访问,最好使用其他认证的官方ssl证书) @@ -70,7 +69,10 @@ openssl rsa -in server.key.org -out server.key openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt ``` -## nginx转发配置示例 +## nginx配置说明(了解的可以跳过) +h5打开麦克风需要https协议,同时后端的asr websocket也必须是wss协议,如果[online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket)以ws方式运行,我们可以通过nginx配置实现wss协议到ws协议的转换。 + +### nginx转发配置示例 ```shell events { [0/1548] worker_connections 1024; From c00336e11581165329557097cb29e5e05d5a31fd Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Mon, 15 May 2023 14:32:34 +0000 Subject: [PATCH 08/15] add fire engine manually --- funasr/runtime/python/websocket/parse_args.py | 12 +++++++++++- funasr/runtime/python/websocket/ws_server_online.py | 5 ++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/funasr/runtime/python/websocket/parse_args.py b/funasr/runtime/python/websocket/parse_args.py index d170be857..bfa5a87a9 100644 --- a/funasr/runtime/python/websocket/parse_args.py +++ b/funasr/runtime/python/websocket/parse_args.py @@ -35,6 +35,16 @@ parser.add_argument("--ncpu", type=int, default=1, help="cpu cores") - +parser.add_argument("--certfile", + type=str, + default="", + required=False, + help="certfile for ssl") + +parser.add_argument("--keyfile", + type=str, + default="", + required=False, + help="keyfile for ssl") args = parser.parse_args() print(args) \ No newline at end of file diff --git a/funasr/runtime/python/websocket/ws_server_online.py b/funasr/runtime/python/websocket/ws_server_online.py index ba50f6287..16a3abe56 100644 --- a/funasr/runtime/python/websocket/ws_server_online.py +++ b/funasr/runtime/python/websocket/ws_server_online.py @@ -53,6 +53,9 @@ async def ws_serve(websocket, path): if "is_speaking" in messagejson: websocket.is_speaking = messagejson["is_speaking"] websocket.param_dict_asr_online["is_final"] = not websocket.is_speaking + # need to fire engine manually if no data received any more + if not websocket.is_speaking: + await async_asr_online(websocket,b"") if "chunk_interval" in messagejson: websocket.chunk_interval=messagejson["chunk_interval"] if "wav_name" in messagejson: @@ -82,7 +85,7 @@ async def ws_serve(websocket, path): async def async_asr_online(websocket,audio_in): - if len(audio_in) > 0: + if len(audio_in) >=0: audio_in = load_bytes(audio_in) rec_result = inference_pipeline_asr_online(audio_in=audio_in, param_dict=websocket.param_dict_asr_online) From acf97731ecc74b984205c572c2bd5a0131960355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 16 May 2023 09:52:50 +0800 Subject: [PATCH 09/15] readme --- README.md | 5 +++-- docs/images/aihealthx.png | Bin 0 -> 11029 bytes 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 docs/images/aihealthx.png diff --git a/README.md b/README.md index e9c6ef9bb..996cde4b6 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,8 @@ If you have any questions about FunASR, please contact us by ## Contributors -|
|
|
|
| | -|:---------------------------------------------------------------:|:---------------------------------------------------------------:|:--------------------------------------------------------------:|:-------------------------------------------------------:|:-----------------------------------------------------------:| +|
|
|
|
| | | +|:---------------------------------------------------------------:|:---------------------------------------------------------------:|:--------------------------------------------------------------:|:-------------------------------------------------------:|:-----------------------------------------------------------:|:-----------------------------------------------------------:| ## Acknowledge @@ -86,6 +86,7 @@ If you have any questions about FunASR, please contact us by 4. We acknowledge [ChinaTelecom](https://github.com/zhuzizyf/damo-fsmn-vad-infer-httpserver) for contributing the VAD runtime. 5. We acknowledge [RapidAI](https://github.com/RapidAI) for contributing the Paraformer and CT_Transformer-punc runtime. 6. We acknowledge [DeepScience](https://www.deepscience.cn) for contributing the grpc service. +6. We acknowledge [AiHealthx](http://www.aihealthx.com/) for contributing the websocket service and html5. ## License This project is licensed under the [The MIT License](https://opensource.org/licenses/MIT). FunASR also contains various third-party components and some code modified from other repos under other open source licenses. diff --git a/docs/images/aihealthx.png b/docs/images/aihealthx.png new file mode 100644 index 0000000000000000000000000000000000000000..5727c5bd6d6a2b924f2f9db583c8c187d708cda3 GIT binary patch literal 11029 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 Yoc|<0d5$Cs!(HLzq`pa3iyQy^A92>PiU0rr literal 0 HcmV?d00001 From 831534a8493027d549f7d2611f8b139e2a4b288b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 16 May 2023 09:56:35 +0800 Subject: [PATCH 10/15] readme --- funasr/runtime/html5/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index a914dd782..612dc2064 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -106,4 +106,4 @@ http { ## Acknowledge 1. This project is maintained by [FunASR community](https://github.com/alibaba-damo-academy/FunASR). -2. We acknowledge [爱医声](http://www.aihealthx.com/) for contributing the html5 demo. \ No newline at end of file +2. We acknowledge [AiHealthx](http://www.aihealthx.com/) for contributing the html5 demo. \ No newline at end of file From d00974c825d16e9db46764f855dae5f255ab200d Mon Sep 17 00:00:00 2001 From: zhaomingwork Date: Tue, 16 May 2023 03:20:44 +0000 Subject: [PATCH 11/15] add english readme --- funasr/runtime/html5/readme.md | 54 +++++++-------- funasr/runtime/html5/readme_cn.md | 109 ++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 27 deletions(-) create mode 100644 funasr/runtime/html5/readme_cn.md diff --git a/funasr/runtime/html5/readme.md b/funasr/runtime/html5/readme.md index 612dc2064..5dd462b81 100644 --- a/funasr/runtime/html5/readme.md +++ b/funasr/runtime/html5/readme.md @@ -9,70 +9,70 @@ pyOpenSSL ``` ### javascript -[html5录音](https://github.com/xiangyuecn/Recorder) +[html5 recorder.js](https://github.com/xiangyuecn/Recorder) ```shell Recorder ``` -### demo页面如下 -![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) +### demo +![img](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/html5/demo.gif) -## 两种ws_server_online连接模式 -### 1)直接连接模式,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> wss asr online srv(证书生成请往后看) +## wss or ws protocol for ws_server_online +1) wss: browser microphone data --> html5 demo server --> js wss api --> wss asr online srv #for certificate generation just look back -### 2)nginx中转,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv +2) ws: browser microphone data --> html5 demo server --> js wss api --> nginx wss server --> ws asr online srv -## 1.html5 demo服务启动 -### 启动html5服务,需要ssl证书(自己生成请往后看) +## 1.html5 demo start +### ssl certificate is required ```shell usage: h5Server.py [-h] [--host HOST] [--port PORT] [--certfile CERTFILE] [--keyfile KEYFILE] python h5Server.py --port 1337 ``` -## 2.启动ws or wss asr online srv -[具体请看online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) -online asr提供两种ws和wss模式,wss模式可以直接启动,无需nginx中转。否则需要通过nginx将wss转发到该online asr的ws端口上 -### wss方式 +## 2.asr online srv start +[detail for online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) +Online asr provides wss or ws way. if started in ws way, nginx is required for relay. +### wss way, ssl certificate is required ```shell python ws_server_online.py --certfile server.crt --keyfile server.key --port 5921 ``` -### ws方式 +### ws way ```shell python ws_server_online.py --port 5921 ``` -## 3.修改wsconnecter.js里asr接口地址 -wsconnecter.js里配置online asr服务地址路径,这里配置的是wss端口 +## 3.modify asr address in wsconnecter.js according to your environment +asr address in wsconnecter.js must be wss, just like var Uri = "wss://xxx:xxx/" -## 4.浏览器打开地址测试 -https://127.0.0.1:1337/static/index.html +## 4.open browser to access html5 demo +https://youraddress:port/static/index.html -## 自行生成证书 -生成证书(注意这种证书并不能被所有浏览器认可,部分手动授权可以访问,最好使用其他认证的官方ssl证书) +## certificate generation by yourself +generated certificate may not suitable for all browsers due to security concerns. you'd better buy or download an authenticated ssl certificate from authorized agency. ```shell -### 1)生成私钥,按照提示填写内容 +### 1) Generate a private key openssl genrsa -des3 -out server.key 1024 -### 2)生成csr文件 ,按照提示填写内容 +### 2) Generate a csr file openssl req -new -key server.key -out server.csr -### 去掉pass +### 3) Remove pass cp server.key server.key.org openssl rsa -in server.key.org -out server.key -### 生成crt文件,有效期1年(365天) +### 4) Generated a crt file, valid for 1 year openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt ``` -## nginx配置说明(了解的可以跳过) -h5打开麦克风需要https协议,同时后端的asr websocket也必须是wss协议,如果[online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket)以ws方式运行,我们可以通过nginx配置实现wss协议到ws协议的转换。 - -### nginx转发配置示例 +## nginx configuration (you can skip it if you known) +https and wss protocol are required by browsers when want to open microphone and websocket. +if [online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) run in ws way, you should use nginx to convert wss to ws. +### nginx wss->ws configuration example ```shell events { [0/1548] worker_connections 1024; diff --git a/funasr/runtime/html5/readme_cn.md b/funasr/runtime/html5/readme_cn.md new file mode 100644 index 000000000..612dc2064 --- /dev/null +++ b/funasr/runtime/html5/readme_cn.md @@ -0,0 +1,109 @@ +# online asr demo for html5 + +## requirement +### python +```shell +flask +gevent +pyOpenSSL +``` + +### javascript +[html5录音](https://github.com/xiangyuecn/Recorder) +```shell +Recorder +``` + +### demo页面如下 +![img](https://github.com/alibaba-damo-academy/FunASR/blob/for-html5-demo/funasr/runtime/html5/demo.gif) + +## 两种ws_server_online连接模式 +### 1)直接连接模式,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> wss asr online srv(证书生成请往后看) + +### 2)nginx中转,浏览器https麦克风 --> html5 demo服务 --> js wss接口 --> nginx服务 --> ws asr online srv + +## 1.html5 demo服务启动 +### 启动html5服务,需要ssl证书(自己生成请往后看) + +```shell +usage: h5Server.py [-h] [--host HOST] [--port PORT] [--certfile CERTFILE] + [--keyfile KEYFILE] +python h5Server.py --port 1337 +``` +## 2.启动ws or wss asr online srv +[具体请看online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket) +online asr提供两种ws和wss模式,wss模式可以直接启动,无需nginx中转。否则需要通过nginx将wss转发到该online asr的ws端口上 +### wss方式 +```shell +python ws_server_online.py --certfile server.crt --keyfile server.key --port 5921 +``` +### ws方式 +```shell +python ws_server_online.py --port 5921 +``` +## 3.修改wsconnecter.js里asr接口地址 +wsconnecter.js里配置online asr服务地址路径,这里配置的是wss端口 +var Uri = "wss://xxx:xxx/" + +## 4.浏览器打开地址测试 +https://127.0.0.1:1337/static/index.html + + + + +## 自行生成证书 +生成证书(注意这种证书并不能被所有浏览器认可,部分手动授权可以访问,最好使用其他认证的官方ssl证书) + +```shell +### 1)生成私钥,按照提示填写内容 +openssl genrsa -des3 -out server.key 1024 + +### 2)生成csr文件 ,按照提示填写内容 +openssl req -new -key server.key -out server.csr + +### 去掉pass +cp server.key server.key.org +openssl rsa -in server.key.org -out server.key + +### 生成crt文件,有效期1年(365天) +openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt +``` + +## nginx配置说明(了解的可以跳过) +h5打开麦克风需要https协议,同时后端的asr websocket也必须是wss协议,如果[online asr](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/runtime/python/websocket)以ws方式运行,我们可以通过nginx配置实现wss协议到ws协议的转换。 + +### nginx转发配置示例 +```shell +events { [0/1548] + worker_connections 1024; + accept_mutex on; + } +http { + error_log error.log; + access_log access.log; + server { + + listen 5921 ssl http2; # nginx listen port for wss + server_name www.test.com; + + ssl_certificate /funasr/server.crt; + ssl_certificate_key /funasr/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + + location /wss/ { + + + proxy_pass http://127.0.0.1:1111/; # asr online model ws address and port + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 600s; + + } + } +``` + +## Acknowledge +1. This project is maintained by [FunASR community](https://github.com/alibaba-damo-academy/FunASR). +2. We acknowledge [AiHealthx](http://www.aihealthx.com/) for contributing the html5 demo. \ No newline at end of file From 88ee288046ec7f03f752225ce2b8c88d3bf1ee84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 17 May 2023 00:14:38 +0800 Subject: [PATCH 12/15] html5 server client docs --- docs/runtime/html5.md | 1 + 1 file changed, 1 insertion(+) create mode 120000 docs/runtime/html5.md diff --git a/docs/runtime/html5.md b/docs/runtime/html5.md new file mode 120000 index 000000000..bf47840ed --- /dev/null +++ b/docs/runtime/html5.md @@ -0,0 +1 @@ +../../funasr/runtime/html5/readme.md \ No newline at end of file From 3346a7cdc798816d2044ffc39438ba2d82881b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 17 May 2023 00:21:02 +0800 Subject: [PATCH 13/15] html5 server client docs --- docs/index.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index c2656bded..cb98f3573 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -68,10 +68,12 @@ Overview ./runtime/onnxruntime_python.md ./runtime/onnxruntime_cpp.md ./runtime/libtorch_python.md - ./runtime/grpc_python.md - ./runtime/grpc_cpp.md + ./runtime/html5.md ./runtime/websocket_python.md ./runtime/websocket_cpp.md + ./runtime/grpc_python.md + ./runtime/grpc_cpp.md + .. toctree:: :maxdepth: 1 From 16315022834eeb96562ad0a18ea869d07f10970a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=BE=E8=81=AA?= Date: Wed, 17 May 2023 15:14:08 +0800 Subject: [PATCH 14/15] fix fsmnvad --- funasr/runtime/onnxruntime/src/fsmn-vad.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/funasr/runtime/onnxruntime/src/fsmn-vad.cpp b/funasr/runtime/onnxruntime/src/fsmn-vad.cpp index f06153498..fbc983282 100644 --- a/funasr/runtime/onnxruntime/src/fsmn-vad.cpp +++ b/funasr/runtime/onnxruntime/src/fsmn-vad.cpp @@ -162,10 +162,10 @@ void FsmnVad::Forward( } // get 4 caches outputs,each size is 128*19 - for (int i = 1; i < 5; i++) { - float* data = vad_ort_outputs[i].GetTensorMutableData(); - memcpy(in_cache_[i-1].data(), data, sizeof(float) * 128*19); - } + // for (int i = 1; i < 5; i++) { + // float* data = vad_ort_outputs[i].GetTensorMutableData(); + // memcpy(in_cache_[i-1].data(), data, sizeof(float) * 128*19); + // } } void FsmnVad::FbankKaldi(float sample_rate, std::vector> &vad_feats, From a44eb39cbd7ac5fe1dd29c8617efde3fb6ebda60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=BE=E8=81=AA?= Date: Wed, 17 May 2023 15:32:00 +0800 Subject: [PATCH 15/15] fix funasr-onnx-offline-rtf --- funasr/runtime/onnxruntime/readme.md | 13 ++++++++++++ .../src/funasr-onnx-offline-rtf.cpp | 20 +++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/funasr/runtime/onnxruntime/readme.md b/funasr/runtime/onnxruntime/readme.md index 3e34a678a..4ed184f64 100644 --- a/funasr/runtime/onnxruntime/readme.md +++ b/funasr/runtime/onnxruntime/readme.md @@ -127,6 +127,8 @@ For example: ### funasr-onnx-offline-rtf ```shell ./funasr-onnx-offline-rtf --model-dir [--quantize ] + [--vad-dir ] [--vad-quant ] + [--punc-dir ] [--punc-quant ] --wav-path --thread-num [--] [--version] [-h] Where: @@ -136,6 +138,17 @@ Where: (required) the model path, which contains model.onnx, config.yaml, am.mvn --quantize false (Default), load the model of model.onnx in model_dir. If set true, load the model of model_quant.onnx in model_dir + + --vad-dir + the vad model path, which contains model.onnx, vad.yaml, vad.mvn + --vad-quant + false (Default), load the model of model.onnx in vad_dir. If set true, load the model of model_quant.onnx in vad_dir + + --punc-dir + the punc model path, which contains model.onnx, punc.yaml + --punc-quant + false (Default), load the model of model.onnx in punc_dir. If set true, load the model of model_quant.onnx in punc_dir + --wav-path (required) the input could be: wav_path, e.g.: asr_example.wav; diff --git a/funasr/runtime/onnxruntime/src/funasr-onnx-offline-rtf.cpp b/funasr/runtime/onnxruntime/src/funasr-onnx-offline-rtf.cpp index 6ba65c6c4..cf1469d3e 100644 --- a/funasr/runtime/onnxruntime/src/funasr-onnx-offline-rtf.cpp +++ b/funasr/runtime/onnxruntime/src/funasr-onnx-offline-rtf.cpp @@ -39,7 +39,7 @@ void runReg(FUNASR_HANDLE asr_handle, vector wav_list, // warm up for (size_t i = 0; i < 1; i++) { - FUNASR_RESULT result=FunASRInfer(asr_handle, wav_list[0].c_str(), RASR_NONE, NULL, 16000); + FUNASR_RESULT result=FunOfflineInfer(asr_handle, wav_list[0].c_str(), RASR_NONE, NULL, 16000); } while (true) { @@ -50,7 +50,7 @@ void runReg(FUNASR_HANDLE asr_handle, vector wav_list, } gettimeofday(&start, NULL); - FUNASR_RESULT result=FunASRInfer(asr_handle, wav_list[i].c_str(), RASR_NONE, NULL, 16000); + FUNASR_RESULT result=FunOfflineInfer(asr_handle, wav_list[i].c_str(), RASR_NONE, NULL, 16000); gettimeofday(&end, NULL); seconds = (end.tv_sec - start.tv_sec); @@ -102,12 +102,20 @@ int main(int argc, char *argv[]) TCLAP::CmdLine cmd("funasr-onnx-offline-rtf", ' ', "1.0"); TCLAP::ValueArg model_dir("", MODEL_DIR, "the model path, which contains model.onnx, config.yaml, am.mvn", true, "", "string"); TCLAP::ValueArg quantize("", QUANTIZE, "false (Default), load the model of model.onnx in model_dir. If set true, load the model of model_quant.onnx in model_dir", false, "false", "string"); + TCLAP::ValueArg vad_dir("", VAD_DIR, "the vad model path, which contains model.onnx, vad.yaml, vad.mvn", false, "", "string"); + TCLAP::ValueArg vad_quant("", VAD_QUANT, "false (Default), load the model of model.onnx in vad_dir. If set true, load the model of model_quant.onnx in vad_dir", false, "false", "string"); + TCLAP::ValueArg punc_dir("", PUNC_DIR, "the punc model path, which contains model.onnx, punc.yaml", false, "", "string"); + TCLAP::ValueArg punc_quant("", PUNC_QUANT, "false (Default), load the model of model.onnx in punc_dir. If set true, load the model of model_quant.onnx in punc_dir", false, "false", "string"); TCLAP::ValueArg wav_path("", WAV_PATH, "the input could be: wav_path, e.g.: asr_example.wav; pcm_path, e.g.: asr_example.pcm; wav.scp, kaldi style wav list (wav_id \t wav_path)", true, "", "string"); TCLAP::ValueArg thread_num("", THREAD_NUM, "multi-thread num for rtf", true, 0, "int32_t"); cmd.add(model_dir); cmd.add(quantize); + cmd.add(vad_dir); + cmd.add(vad_quant); + cmd.add(punc_dir); + cmd.add(punc_quant); cmd.add(wav_path); cmd.add(thread_num); cmd.parse(argc, argv); @@ -115,11 +123,15 @@ int main(int argc, char *argv[]) std::map model_path; GetValue(model_dir, MODEL_DIR, model_path); GetValue(quantize, QUANTIZE, model_path); + GetValue(vad_dir, VAD_DIR, model_path); + GetValue(vad_quant, VAD_QUANT, model_path); + GetValue(punc_dir, PUNC_DIR, model_path); + GetValue(punc_quant, PUNC_QUANT, model_path); GetValue(wav_path, WAV_PATH, model_path); struct timeval start, end; gettimeofday(&start, NULL); - FUNASR_HANDLE asr_handle=FunASRInit(model_path, 1); + FUNASR_HANDLE asr_handle=FunOfflineInit(model_path, 1); if (!asr_handle) { @@ -132,7 +144,7 @@ int main(int argc, char *argv[]) long modle_init_micros = ((seconds * 1000000) + end.tv_usec) - (start.tv_usec); LOG(INFO) << "Model initialization takes " << (double)modle_init_micros / 1000000 << " s"; - // read wav_scp + // read wav_path vector wav_list; string wav_path_ = model_path.at(WAV_PATH); if(is_target_file(wav_path_, "wav") || is_target_file(wav_path_, "pcm")){