main.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /**
  2. * Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
  3. * Reserved. MIT License (https://opensource.org/licenses/MIT)
  4. */
  5. /* 2022-2023 by zhaoming,mali aihealthx.com */
  6. // 连接; 定义socket连接类对象与语音对象
  7. var wsconnecter = new WebSocketConnectMethod({msgHandle:getJsonMessage,stateHandle:getConnState});
  8. var audioBlob;
  9. // 录音; 定义录音对象,wav格式
  10. var rec = Recorder({
  11. type:"pcm",
  12. bitRate:16,
  13. sampleRate:16000,
  14. onProcess:recProcess
  15. });
  16. var sampleBuf=new Int16Array();
  17. // 定义按钮响应事件
  18. var btnStart = document.getElementById('btnStart');
  19. btnStart.onclick = record;
  20. var btnStop = document.getElementById('btnStop');
  21. btnStop.onclick = stop;
  22. btnStop.disabled = true;
  23. btnStart.disabled = true;
  24. btnConnect= document.getElementById('btnConnect');
  25. btnConnect.onclick = start;
  26. var awsslink= document.getElementById('wsslink');
  27. var rec_text=""; // for online rec asr result
  28. var offline_text=""; // for offline rec asr result
  29. var info_div = document.getElementById('info_div');
  30. var upfile = document.getElementById('upfile');
  31. var isfilemode=false; // if it is in file mode
  32. var file_data_array; // array to save file data
  33. var totalsend=0;
  34. var now_ipaddress=window.location.href;
  35. now_ipaddress=now_ipaddress.replace("https://","wss://");
  36. now_ipaddress=now_ipaddress.replace("static/index.html","");
  37. var localport=window.location.port;
  38. now_ipaddress=now_ipaddress.replace(localport,"10095");
  39. document.getElementById('wssip').value=now_ipaddress;
  40. addresschange();
  41. function addresschange()
  42. {
  43. var Uri = document.getElementById('wssip').value;
  44. document.getElementById('info_wslink').innerHTML="点此处手工授权(IOS手机)";
  45. Uri=Uri.replace(/wss/g,"https");
  46. console.log("addresschange uri=",Uri);
  47. awsslink.onclick=function(){
  48. window.open(Uri, '_blank');
  49. }
  50. }
  51. upfile.onclick=function()
  52. {
  53. btnStart.disabled = true;
  54. btnStop.disabled = true;
  55. btnConnect.disabled=false;
  56. }
  57. upfile.onchange = function () {
  58.       var len = this.files.length;
  59. for(let i = 0; i < len; i++) {
  60. let fileAudio = new FileReader();
  61. fileAudio.readAsArrayBuffer(this.files[i]);
  62. fileAudio.onload = function() {
  63. var audioblob= fileAudio.result;
  64. file_data_array=audioblob;
  65. console.log(audioblob);
  66. info_div.innerHTML='请点击连接进行识别';
  67. }
  68.           fileAudio.onerror = function(e) {
  69.             console.log('error' + e);
  70.           }
  71. }
  72. }
  73. function play_file()
  74. {
  75. var audioblob=new Blob( [ new Uint8Array(file_data_array)] , {type :"audio/wav"});
  76. var audio_record = document.getElementById('audio_record');
  77. audio_record.src = (window.URL||webkitURL).createObjectURL(audioblob);
  78. audio_record.controls=true;
  79. //audio_record.play(); //not auto play
  80. }
  81. function start_file_send()
  82. {
  83. sampleBuf=new Int16Array( file_data_array );
  84. var chunk_size=960; // for asr chunk_size [5, 10, 5]
  85. while(sampleBuf.length>=chunk_size){
  86. sendBuf=sampleBuf.slice(0,chunk_size);
  87. totalsend=totalsend+sampleBuf.length;
  88. sampleBuf=sampleBuf.slice(chunk_size,sampleBuf.length);
  89. wsconnecter.wsSend(sendBuf);
  90. }
  91. stop();
  92. }
  93. function on_recoder_mode_change()
  94. {
  95. var item = null;
  96. var obj = document.getElementsByName("recoder_mode");
  97. for (var i = 0; i < obj.length; i++) { //遍历Radio
  98. if (obj[i].checked) {
  99. item = obj[i].value;
  100. break;
  101. }
  102. }
  103. if(item=="mic")
  104. {
  105. document.getElementById("mic_mode_div").style.display = 'block';
  106. document.getElementById("rec_mode_div").style.display = 'none';
  107. btnStart.disabled = true;
  108. btnStop.disabled = true;
  109. btnConnect.disabled=false;
  110. isfilemode=false;
  111. }
  112. else
  113. {
  114. document.getElementById("mic_mode_div").style.display = 'none';
  115. document.getElementById("rec_mode_div").style.display = 'block';
  116. btnStart.disabled = true;
  117. btnStop.disabled = true;
  118. btnConnect.disabled=true;
  119. isfilemode=true;
  120. info_div.innerHTML='请点击选择文件';
  121. }
  122. }
  123. function getAsrMode(){
  124. var item = null;
  125. var obj = document.getElementsByName("asr_mode");
  126. for (var i = 0; i < obj.length; i++) { //遍历Radio
  127. if (obj[i].checked) {
  128. item = obj[i].value;
  129. break;
  130. }
  131. }
  132. if(isfilemode)
  133. {
  134. item= "offline";
  135. }
  136. console.log("asr mode"+item);
  137. return item;
  138. }
  139. // 语音识别结果; 对jsonMsg数据解析,将识别结果附加到编辑框中
  140. function getJsonMessage( jsonMsg ) {
  141. //console.log(jsonMsg);
  142. console.log( "message: " + JSON.parse(jsonMsg.data)['text'] );
  143. var rectxt=""+JSON.parse(jsonMsg.data)['text'];
  144. var asrmodel=JSON.parse(jsonMsg.data)['mode'];
  145. if(asrmodel=="2pass-offline")
  146. {
  147. offline_text=offline_text+rectxt; //.replace(/ +/g,"");
  148. rec_text=offline_text;
  149. }
  150. else
  151. {
  152. rec_text=rec_text+rectxt; //.replace(/ +/g,"");
  153. }
  154. var varArea=document.getElementById('varArea');
  155. varArea.value=rec_text;
  156. console.log( "offline_text: " + asrmodel+","+offline_text);
  157. console.log( "rec_text: " + rec_text);
  158. if (isfilemode==true){
  159. console.log("call stop ws!");
  160. play_file();
  161. wsconnecter.wsStop();
  162. info_div.innerHTML="请点击连接";
  163. btnStart.disabled = true;
  164. btnStop.disabled = true;
  165. btnConnect.disabled=false;
  166. }
  167. }
  168. // 连接状态响应
  169. function getConnState( connState ) {
  170. if ( connState === 0 ) { //on open
  171. info_div.innerHTML='连接成功!请点击开始';
  172. if (isfilemode==true){
  173. info_div.innerHTML='请耐心等待,大文件等待时间更长';
  174. start_file_send();
  175. }
  176. else
  177. {
  178. btnStart.disabled = false;
  179. btnStop.disabled = true;
  180. btnConnect.disabled=true;
  181. }
  182. } else if ( connState === 1 ) {
  183. //stop();
  184. } else if ( connState === 2 ) {
  185. stop();
  186. console.log( 'connecttion error' );
  187. alert("连接地址"+document.getElementById('wssip').value+"失败,请检查asr地址和端口。或试试界面上手动授权,再连接。");
  188. btnStart.disabled = true;
  189. btnStop.disabled = true;
  190. btnConnect.disabled=false;
  191. info_div.innerHTML='请点击连接';
  192. }
  193. }
  194. function record()
  195. {
  196. rec.open( function(){
  197. rec.start();
  198. console.log("开始");
  199. btnStart.disabled = true;
  200. btnStop.disabled = false;
  201. btnConnect.disabled=true;
  202. });
  203. }
  204. // 识别启动、停止、清空操作
  205. function start() {
  206. // 清除显示
  207. clear();
  208. //控件状态更新
  209. console.log("isfilemode"+isfilemode);
  210. //启动连接
  211. var ret=wsconnecter.wsStart();
  212. // 1 is ok, 0 is error
  213. if(ret==1){
  214. info_div.innerHTML="正在连接asr服务器,请等待...";
  215. isRec = true;
  216. btnStart.disabled = true;
  217. btnStop.disabled = true;
  218. btnConnect.disabled=true;
  219. return 1;
  220. }
  221. else
  222. {
  223. info_div.innerHTML="请点击开始";
  224. btnStart.disabled = true;
  225. btnStop.disabled = true;
  226. btnConnect.disabled=false;
  227. return 0;
  228. }
  229. }
  230. function stop() {
  231. var chunk_size = new Array( 5, 10, 5 );
  232. var request = {
  233. "chunk_size": chunk_size,
  234. "wav_name": "h5",
  235. "is_speaking": false,
  236. "chunk_interval":10,
  237. "mode":getAsrMode(),
  238. };
  239. console.log(request);
  240. if(sampleBuf.length>0){
  241. wsconnecter.wsSend(sampleBuf);
  242. console.log("sampleBuf.length"+sampleBuf.length);
  243. sampleBuf=new Int16Array();
  244. }
  245. wsconnecter.wsSend( JSON.stringify(request) );
  246. // 控件状态更新
  247. isRec = false;
  248. info_div.innerHTML="发送完数据,请等候,正在识别...";
  249. if(isfilemode==false){
  250. btnStop.disabled = true;
  251. btnStart.disabled = true;
  252. btnConnect.disabled=true;
  253. //wait 3s for asr result
  254. setTimeout(function(){
  255. console.log("call stop ws!");
  256. wsconnecter.wsStop();
  257. btnConnect.disabled=false;
  258. info_div.innerHTML="请点击连接";}, 3000 );
  259. rec.stop(function(blob,duration){
  260. console.log(blob);
  261. var audioBlob = Recorder.pcm2wav(data = {sampleRate:16000, bitRate:16, blob:blob},
  262. function(theblob,duration){
  263. console.log(theblob);
  264. var audio_record = document.getElementById('audio_record');
  265. audio_record.src = (window.URL||webkitURL).createObjectURL(theblob);
  266. audio_record.controls=true;
  267. //audio_record.play();
  268. } ,function(msg){
  269. console.log(msg);
  270. }
  271. );
  272. },function(errMsg){
  273. console.log("errMsg: " + errMsg);
  274. });
  275. }
  276. // 停止连接
  277. }
  278. function clear() {
  279. var varArea=document.getElementById('varArea');
  280. varArea.value="";
  281. rec_text="";
  282. offline_text="";
  283. }
  284. function recProcess( buffer, powerLevel, bufferDuration, bufferSampleRate,newBufferIdx,asyncEnd ) {
  285. if ( isRec === true ) {
  286. var data_48k = buffer[buffer.length-1];
  287. var array_48k = new Array(data_48k);
  288. var data_16k=Recorder.SampleData(array_48k,bufferSampleRate,16000).data;
  289. sampleBuf = Int16Array.from([...sampleBuf, ...data_16k]);
  290. var chunk_size=960; // for asr chunk_size [5, 10, 5]
  291. info_div.innerHTML=""+bufferDuration/1000+"s";
  292. while(sampleBuf.length>=chunk_size){
  293. sendBuf=sampleBuf.slice(0,chunk_size);
  294. sampleBuf=sampleBuf.slice(chunk_size,sampleBuf.length);
  295. wsconnecter.wsSend(sendBuf);
  296. }
  297. }
  298. }