当前位置:   article > 正文

Vue项目使用js-audio-recorder录音,通过WebSocket实时发送音频文件(语音识别)

js-audio-recorder


前言

最近有个新需求,做一个语音识别的功能,将音频文件转为文字,识别完成后把文字返回到页面展示,最后使用js-audio-plugin + WebSocket实现
  • 1

一、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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2. script 标签方式

//使用
<script type="text/javascript" src="./dist/recorder.js"></script>

let recorder = new Recorder();
  • 1
  • 2
  • 3
  • 4

二、后端代码示例(服务端)

1. 配置WebScoket

pom文件

<!-- webSocket -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>5.3.9</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
@Component
public class WebSocketConfig {
    /**
     * 使用内部容器,需要配置一个Bean
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2. 代码

该注解是将类定义为一个WebSocket服务端,注解值{serverId}用于监听用户连接的URL标识,每个客户端标识不一致,客户端可以通过这个地址访问服务端

@ServerEndpoint("/websocket/{serverId}")
  • 1

需要用到的字段

    //与客户端通信
    private Session session;
    //客户端标识
    private String serverId;
    //所有连接服务的客户端,线程安全    CommunicationWebsocket是你自己的服务类
    private static ConcurrentHashMap<String, CommunicationWebsocket> communicationWebSocketSet= new ConcurrentHashMap<>();
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
	@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());
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
	@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传过去
		
	}
  • 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
	@OnClose
    public void OnClose(){
        webSocketSet.remove(this.serverId);
        System.out.println("客户端退出成功,websocket当前连接数为:"+webSocketSet.size());
    }
  • 1
  • 2
  • 3
  • 4
  • 5

三、前端代码示例

data() {
    return {
		ws: null,       //定义websocket对象
		recorder: null,          //多媒体对象,用来处理音频
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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);
},
  • 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

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)
  }
}
  • 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

如果想做成实时语音转文字,需要前端录音实时发送音频数据,需要设置compiling=true,注意的是compiling在0.x版本中生效!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/400235
推荐阅读
相关标签
  

闽ICP备14008679号