Golang 基于chrome浏览器语音识别web演示系统WebHTK开发之 UI篇

简介:

   没啥好说的,直接上现阶段的HTML代码,后续修改,再更新该篇博客。

   record.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<!DOCTYPE html>
                                                    
<html>
   <head>
     <meta charset= "utf-8" />
     <meta http-equiv= "X-UA-Compatible"  content= "IE=edge" />
     <meta name= "viewport"  content= "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
     <meta name= "keywords"  content= "PONPON,HTK,Go语言" />
     <meta name= "description"  content= "基于Beego开发语音识别演示系统" />
     <meta name= "generator"  content= "PONPON"  />
                                                    
     <link href= "/static/css/bootstrap.min.css"  rel= "stylesheet" >
     <link href= "/static/css/docs.css"  rel= "stylesheet" >
     <link href= "http://cdn.bootcss.com/highlight.js/7.3/styles/github.min.css"  rel= "stylesheet" >
     <link rel= "shortcut icon"  href= "/static/img/Logoicon.jpg" >
                                                    
     <link rel= "stylesheet"  href= "http://libs.baidu.com/fontawesome/4.0.3/css/font-awesome.min.css" />
     <link rel= "alternate"  type= "application/rss+xml"  href= "/rss.xml" />
                                                    
     <script type= "text/javascript"  src= "/static/lib/recorder.js" > </script>
     <script type= "text/javascript"  src= "/static/lib/jquery-1.10.1.min.js" > </script>
     <script type= "text/javascript"  src= "/static/lib/recController.js" > </script>
                                                    
                                                    
<title>WebHTK 演示系统</title>
     </head>
         <body>
         <nav id= "header" >
          <div class= "container960 text-center"  >
              <h3 id= "header-h"  class= "center"  >闽南语 - 语音识别演示系统</h3>
                                                                    
                                                                
                                                    
                  <ul id= "resultbox"  class= "center"  style= "padding-top:425px;font-size:20px;text-align: center;color:#FFC8B6;font-family:'微软雅黑'" >
                      <li >识别结果</li>
                  </ul>
                                                    
                 <form style= "padding-top:20px;" >
                     <a id= "img"  href= "javascript://"   >
                         <img  src= "/static/img/aa.png"  style= "width:85px;height:85px;"  alt= "" />
                     </a>
                 </form>
                 <div id= "message"  style= "padding-top:10px;font-size:16px;color:#F5FFFA;text-align: center;font-family:'微软雅黑'" >点击麦克风,开始录音!</div>
                                                    
            <script type= "text/javascript" >
                                                    
            var  recording =  false ;
                                                    
            function  test() {
          if  (!recording) {    
              document.getElementById( "img" ).innerHTML= "<img  src='/static/img/a1.png' style='width:85px;height:85px;'' alt=''/>" ;
             toRecord();
              recording= true ;
         } else {
                   document.getElementById( "img" ).innerHTML= "<img  src='/static/img/aa.png' style='width:85px;height:85px;'' alt=''/>" ;
             toSend();
             recording =  false ;
         }
             };
                                                    
             function  toRecord(){
             rec.record();
              var  dd = ws.send( "start" );
              $( "#message" ).text( "再次点击,结束录音!" );
              intervalKey = setInterval( function () {
                  rec.exportWAV( function (blob) {
                      rec.clear();
                      ws.send(blob);
                                                    
                  });
              }, 300);
             }
                                                             
                                                    
             function  toSend(){
                 rec.stop();
                 if  (intervalKey ==  null ) {
                     $( "#message" ).text( "请先录音再发送!" );
                     return
                 };
                 ws.send(sampleRate);
                 ws.send(channels);
                 ws.send( "stop" );
                 rec.clear();
                 clearInterval(intervalKey);
                 intervalKey =  null ;
                                                                    
             }
                                                             
          </script>
         </div>
     </nav>
                                                    
             <audio class= "hide"  controls autoplay></audio>
         </body>
</html>


   recorder.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
( function (window) {
                                               
     var  WORKER_PATH =  '/static/lib/recorderWorker.js' ;
                                               
     var  Recorder =  function (source, chan, cfg) {
         var  config = cfg || {};
         var  channels = chan || 1;
         var  bufferLen = config.bufferLen || 8192;
         this .context = source.context;
                                               
         this .node =  this .context.createJavaScriptNode(bufferLen, channels, channels);
         var  worker =  new  Worker(config.workerPath || WORKER_PATH);
         worker.postMessage({
             command:  'init' ,
             config: {
                 sampleRate:  this .context.sampleRate
             }
         });
         var  recording =  false ,
             currCallback;
                                               
         this .node.onaudioprocess =  function (e) {
             if  (!recording)  return ;
             worker.postMessage({
                 command:  'record' ,
                 buffer: [
                     e.inputBuffer.getChannelData(0)
                 ]
             });
         }
                                               
         this .configure =  function (cfg) {
             for  ( var  prop  in  cfg) {
                 if  (cfg.hasOwnProperty(prop)) {
                     config[prop] = cfg[prop];
                 }
             }
         }
                                               
         this .record =  function () {
             recording =  true ;
         }
                                               
         this .stop =  function () {
             recording =  false ;
         }
                                               
         this .clear =  function () {
             worker.postMessage({
                 command:  'clear'
             });
         }
                                               
         this .getBuffer =  function (cb) {
             currCallback = cb || config.callback;
             worker.postMessage({
                 command:  'getBuffer'
             })
         }
                                               
         this .exportWAV =  function (cb, type) {
             currCallback = cb || config.callback;
             type = type || config.type ||  'audio/wav' ;
             if  (!currCallback)  throw  new  Error( 'Callback not set' );
             worker.postMessage({
                 command:  'exportWAV' ,
                 type: type
             });
         }
                                               
         worker.onmessage =  function (e) {
             var  blob = e.data;
             currCallback(blob);
         }
                                               
         source.connect( this .node);
         this .node.connect( this .context.destination);
     };
                                               
     window.Recorder = Recorder;
                                               
})(window);


   recorderWorker.js:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
var  recLength = 0,
     recBuffersL = [],
     sampleRate;
                                       
this .onmessage =  function (e) {
     switch  (e.data.command) {
         case  'init' :
             init(e.data.config);
             break ;
         case  'record' :
             record(e.data.buffer);
             break ;
         case  'exportWAV' :
             exportWAV(e.data.type);
             break ;
         case  'getBuffer' :
             getBuffer();
             break ;
         case  'clear' :
             clear();
             break ;
     }
};
                                       
function  init(config) {
     sampleRate = config.sampleRate;
}
                                       
function  record(inputBuffer) {
     recBuffersL.push(inputBuffer[0]);
     recLength += inputBuffer[0].length;
}
                                       
function  exportWAV(type) {
     var  bufferL = mergeBuffers(recBuffersL, recLength);
     var  interleaved = interleave(bufferL);
     var  dataview = encodeWAV(interleaved);
     var  audioBlob =  new  Blob([dataview], {
         type: type
     });
                                       
     this .postMessage(audioBlob);
}
                                       
function  getBuffer() {
     var  buffers = [];
     buffers.push(mergeBuffers(recBuffersL, recLength));
     this .postMessage(buffers);
}
                                       
function  clear(inputBuffer) {
     recLength = 0;
     recBuffersL = [];
}
                                       
function  mergeBuffers(recBuffers, recLength) {
     var  result =  new  Float32Array(recLength);
     var  offset = 0;
     for  ( var  i = 0; i < recBuffers.length; i++) {
         result.set(recBuffers[i], offset);
         offset += recBuffers[i].length;
     }
     return  result;
}
                                       
function  interleave(inputL) {
     var  length;
     var  result;
                                       
     var  index = 0,
         inputIndex = 0;
                                       
     if  (sampleRate == 48000) {
         length = inputL.length / 6;
         result =  new  Float32Array(length);
         while  (index < length) {
                                       
             result[index++] = (inputL[inputIndex++] + inputL[inputIndex++] +
                 inputL[inputIndex++] + inputL[inputIndex++] +
                 inputL[inputIndex++] + inputL[inputIndex++]) / 6;
         }
     else  if  (sampleRate == 44100) {
         length = inputL.length / 6;
         result =  new  Float32Array(length);
         while  (index < length) {
                                       
             if  (inputIndex % 12 == 0) {
                 result[index++] = (inputL[inputIndex] + inputL[inputIndex++] +
                     inputL[inputIndex++] + inputL[inputIndex++] +
                     inputL[inputIndex++] + inputL[inputIndex++] +
                     inputL[inputIndex++]) / 7;
             else  {
                 result[index++] = (inputL[inputIndex++] + inputL[inputIndex++] +
                     inputL[inputIndex++] + inputL[inputIndex++] +
                     inputL[inputIndex++] + inputL[inputIndex++]) / 6;
             };
         }
     else  {
         length = inputL.length;
         result =  new  Float32Array(length);
         while  (index < length) {
             result[index++] = inputL[inputIndex++];
         }
     };
                                       
     return  result;
}
                                       
function  floatTo16BitPCM(output, offset, input) {
     for  ( var  i = 0; i < input.length; i++, offset += 2) {
         var  s = Math.max(-1, Math.min(1, input[i]));
         output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF,  true );
     }
}
                                       
function  writeString(view, offset, string) {
     for  ( var  i = 0; i < string.length; i++) {
         view.setUint8(offset + i, string.charCodeAt(i));
     }
}
                                       
function  encodeWAV(samples) {
     var  buffer =  new  ArrayBuffer(samples.length * 2);
     var  view =  new  DataView(buffer);
     floatTo16BitPCM(view, 0, samples);
                                       
     return  view;
}


   recController.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
var  onFail =  function (e) {
     console.log( 'Rejected!' , e);
};
                                
var  onSuccess =  function (s) {
     var  context =  new  webkitAudioContext();
     var  mediaStreamSource = context.createMediaStreamSource(s);
     rec =  new  Recorder(mediaStreamSource, channels);
     sampleRate = 8000;
}
                                
                                
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
                                
var  rec;
var  intervalKey =  null ;
var  audio = document.querySelector( '#audio' );
var  sampleRate;
var  channels = 1;
                                
function  startRecording() {
     if  (navigator.getUserMedia) {
         navigator.getUserMedia({
             audio:  true
         }, onSuccess, onFail);
     else  {
         console.log( 'navigator.getUserMedia not present' );
     }
}
startRecording();
//--------------------   
                                
                                
var  ws =  new  WebSocket( 'ws://'  + window.location.host +  '/join' );
ws.onopen =  function () {
     console.log( "Openened connection to websocket" );
};
                                
ws.onclose =  function () {
     console.log( "Close connection to websocket" );
}
ws.onerror =  function () {
     console.log( "Cannot connection to websocket" );
}
                                
ws.onmessage =  function (result) {
     var  data = JSON.parse(result.data);
     console.log( '识别结果:'  + data.Pinyin);
     var  result = document.getElementById( "resultbox" )
     result.getElementsByTagName( "li" )[0].innerHTML = data.Hanzi;
     document.getElementById( "message" ).innerHTML =  "点击麦克风,开始录音!" ;
}


进入页面:

wKioL1MV5_zT5fsBAAi_Ila2WRE976.jpg


正在录音:

wKiom1MV6CXzTifFAAiwJsgx_8k251.jpg


识别结果,目前还为将拼音转换为汉字,下图为“点亮星光”的显示结果图:

wKioL1MV6APT2sxZAAjIrySOhP0350.jpg










本文转自 ponpon_ 51CTO博客,原文链接:http://blog.51cto.com/liuxp0827/1367846,如需转载请自行联系原作者
相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
目录
相关文章
|
30天前
|
Web App开发 人工智能 JSON
AutoMouser:AI Chrome扩展程序,实时跟踪用户的浏览器操作,自动生成自动化操作脚本
AutoMouser是一款Chrome扩展程序,能够实时跟踪用户交互行为,并基于OpenAI的GPT模型自动生成Selenium测试代码,简化自动化测试流程。
139 17
AutoMouser:AI Chrome扩展程序,实时跟踪用户的浏览器操作,自动生成自动化操作脚本
|
1月前
|
人工智能 开发框架 自然语言处理
Eko:一句话就能快速构建复杂工作流的 AI 代理开发框架!快速实现自动操作电脑和浏览器完成任务
Eko 是 Fellou AI 推出的开源 AI 代理开发框架,支持自然语言驱动,帮助开发者快速构建从简单指令到复杂工作流的智能代理。
304 12
Eko:一句话就能快速构建复杂工作流的 AI 代理开发框架!快速实现自动操作电脑和浏览器完成任务
|
1月前
|
Web App开发 编解码 vr&ar
使用Web浏览器访问UE应用的最佳实践
在3D/XR应用开发中,尤其是基于UE(虚幻引擎)开发的高精度场景,传统终端因硬件局限难以流畅运行高帧率、复杂效果的三维应用。实时云渲染技术,将渲染任务转移至云端服务器,降低终端硬件要求,确保用户获得流畅体验。具备弹性扩展、优化传输协议、跨平台支持和安全性等优势,适用于多种终端和场景,特别集成像素流送技术,帮助UE开发者实现低代码上云操作,简化部署流程,保留UE引擎的强大开发能力,确保画面精美且终端轻量化。
使用Web浏览器访问UE应用的最佳实践
|
1月前
|
Web App开发 安全 前端开发
一个接口4个步骤轻松搞定最新版Chrome、Edge、Firefox浏览器集成ActiveX控件
目前的浏览器市场,谷歌浏览器占据了半壁江山,因此,谷歌也是最有话语权的,2015年开始取消支持 NPAPI 插件,2022 年10月停止支持 PPAPI 插件;而曾经老大哥IE浏览器也已停止服务,退出历史舞台,导致大量曾经安全、便捷的ActiveX控件无法使用。为了解决这个难题,本人特研发出allWebPlugin中间件,重新让所有ActiveX控件能在谷歌、火狐等浏览器使用。
|
1月前
|
Web App开发 数据采集 JavaScript
Chrome浏览器实例的TypeScript自动化脚本
Chrome浏览器实例的TypeScript自动化脚本
|
2月前
|
前端开发 安全 JavaScript
2025年,Web3开发学习路线全指南
本文提供了一条针对Dapp应用开发的学习路线,涵盖了Web3领域的重要技术栈,如区块链基础、以太坊技术、Solidity编程、智能合约开发及安全、web3.js和ethers.js库的使用、Truffle框架等。文章首先分析了国内区块链企业的技术需求,随后详细介绍了每个技术点的学习资源和方法,旨在帮助初学者系统地掌握Dapp开发所需的知识和技能。
2025年,Web3开发学习路线全指南
|
3月前
|
存储 前端开发 JavaScript
如何在项目中高效地进行 Web 组件化开发
高效地进行 Web 组件化开发需要从多个方面入手,通过明确目标、合理规划、规范开发、加强测试等一系列措施,实现组件的高效管理和利用,从而提高项目的整体开发效率和质量,为用户提供更好的体验。
55 7
|
3月前
|
存储 缓存 前端开发
Web端IM聊天消息该不该用浏览器本地存储?一文即懂!
鉴于目前浏览器技术的进步(主要是HTML5的普及),在Web网页端IM聊天应用的技术选型阶段,很多开发者都会纠结到底该不该像原生移动端IM那样将聊天记录缓存在浏览器的本地,还是像传统Web端即时通讯那样继续存储在服务端?本文将为你简洁明了地讲清楚浏览器本地存储技术(Web Storage),然后你就知道到底该怎么选择了。
60 1
|
3月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
66 2
|
3月前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
159 62

热门文章

最新文章