文章目录
前言
最近有个新需求,做一个语音识别的功能,将音频文件转为文字,识别完成后把文字返回到页面展示,最后使用js-audio-plugin + websocket实现
一、js-audio-plugin简介
纯js实现浏览器端录音。
详细可参考api:https://recorder-api.zhuyuntao.cn/recorder/
二、安装
1. npm 方式(推荐使用)
//安装
npm i js-audio-recorder
//引入
import recorder from 'js-audio-recorder';
//使用
let recorder = new recorder();
2. script 标签方式
//使用
<script type="text/javascript" src="./dist/recorder.js"></script>
let recorder = new recorder();
二、后端代码示例(服务端)
1. 配置webscoket
pom文件
<!-- websocket -->
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-websocket</artifactid>
<version>5.3.9</version>
</dependency>
@component
public class websocketconfig {
/**
* 使用内部容器,需要配置一个bean
* @return
*/
@bean
public serverendpointexporter serverendpointexporter(){
return new serverendpointexporter();
}
}
2. 代码
该注解是将类定义为一个websocket服务端,注解值{serverid}用于监听用户连接的url标识,每个客户端标识不一致,客户端可以通过这个地址访问服务端
@serverendpoint("/websocket/{serverid}")
需要用到的字段
//与客户端通信
private session session;
//客户端标识
private string serverid;
//所有连接服务的客户端,线程安全 communicationwebsocket是你自己的服务类
private static concurrenthashmap<string, communicationwebsocket> communicationwebsocketset= new concurrenthashmap<>();
@onopen
public void onopen(@pathparam(value = "serverid") string serverid, session session){
this.session = session;
this.serverid = serverid;
//存放所有的客户端连接,serverid唯一标识
websocketset.put(serverid,this);
system.out.println("客户端连接成功,websocket当前连接数为:"+websocketset.size());
}
@onmessage(maxmessagesize = 10000000)
public void onmessage(bytebuffer message){
//message是接收到客户端发来的消息
system.out.println("音频数据报文::"+message);
// 为空时 不处理
if (objectutil.isempty(message)) {
return;
}
// 临时存储 如果不想存储可以自行修改
bytearrayoutputstream bytearrayoutputstream = new bytearrayoutputstream();
byte[] bytes = message.array();
try {
bytearrayoutputstream.write(bytes);
} catch (ioexception e) {
try {
bytearrayoutputstream.close();
} catch (ioexception ex) {
ex.printstacktrace();
}
e.printstacktrace();
}
random random = new random();
string fileurl = filepath+random+".txt";
bytearrayinputstream bais = new bytearrayinputstream(bytearrayoutputstream.tobytearray());
file file = new file(fileurl);
fileoutputstream fos = null;
try {
fos = new fileoutputstream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = bais.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
bais.close();
} catch (filenotfoundexception e) {
throw new runtimeexception(e);
} catch (ioexception e) {
throw new runtimeexception(e);
}
//看个人的业务,将音频文件file传过去
}
@onclose
public void onclose(){
websocketset.remove(this.serverid);
system.out.println("客户端退出成功,websocket当前连接数为:"+websocketset.size());
}
三、前端代码示例
data() {
return {
ws: null, //定义websocket对象
recorder: null, //多媒体对象,用来处理音频
}
}
1. websocket代码
//建立websocket服务
initwebsocket() {
//初始化websocket userid为会话标识
const wsuri = 'ws://127.0.0.1:8080/websocket/'+this.userid;
//连接服务端
this.ws = new websocket(wsuri);
//指定事件回调
this.ws.onmessage = this.websocketonmessage;
this.ws.onopen = this.websocketonopen;
this.ws.onerror = this.websocketonerror;
this.ws.onclose = this.websocketclose;
},
//连接建立之后的回调
websocketonopen() {
this.ws.send("握手成功");
console.log("--------连接已建立!---------")
},
//数据接收
websocketonmessage(e) {
console.log("收到了服务端语音识别后的数据"+e)
},
//数据发送
websocketsend(data) {
//将音频数据发送到后端
this.ws.send(data);
},
//连接建立失败重连
websocketonerror() {
this.initwebsocket();
},
//关闭
websocketclose(e) {
console.log('断开连接', e);
},
2. 录音代码
//开始对讲 可以在进入页面时候调用该方法(看个人需求)
intercombegin() {
//启动浏览器麦克风,开始录制
this.handlestart();
},
//启动录音
handlestart() {
this.recorder = new recorder({
samplebits: 16, // 采样位数,支持 8 或 16,默认是16
samplerate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
numchannels: 1, // 声道,支持 1 或 2, 默认是1
// compiling: true//(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
});
// 获取录音权限
recorder.getpermission().then(
() => {
console.log("开始录音");
this.starttall=true
this.recorder.start(); // 开始录音
},
(error) => {
this.$message({
message: "请允许该网页使用麦克风",
type: "info",
});
console.log(`${error.name} : ${error.message}`);
}
);
},
//结束对讲
intercomend() {
let th = this;
try {
//获取录音数据
const blob = this.recorder.getwavblob();
//blob转为arraybuffer
let reader = new filereader()
reader.readasarraybuffer(blob)
reader.onload = function() {
console.log(this.result)
//调用websocket发送服务端
th.websocketsend(this.result)
}
//停止录音
this.starttall=false
this.recorder.stop();
} catch (e) {
console.log(e)
}
}
如果想做成实时语音转文字,需要前端录音实时发送音频数据,需要设置compiling=true,注意的是compiling在0.x版本中生效!!!
发表评论