没啥好说的,直接上现阶段的HTML代码,后续修改,再更新该篇博客。
record.html:
- <!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:
- (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:
- 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,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,samples);
- return view;
- }
recController.js:
- 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 = "点击麦克风,开始录音!";
- }
进入页面:
正在录音:
识别结果,目前还为将拼音转换为汉字,下图为“点亮星光”的显示结果图: