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

2024-04-09 1164阅读

文章目录

  • 前言
  • 一、js-audio-plugin简介
  • 二、安装
    • 1. npm 方式(推荐使用)
    • 2. script 标签方式
    • 二、后端代码示例(服务端)
      • 1. 配置WebScoket
      • 2. 代码
      • 三、前端代码示例
        • 1. WebSocket代码
        • 2. 录音代码

          前言

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

          一、js-audio-plugin简介

          纯js实现浏览器端录音。

          Vue项目使用js-audio-recorder录音,通过WebSocket实时发送音频文件(语音识别)
          (图片来源网络,侵删)

          详细可参考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 标签方式

          //使用
          
          let recorder = new Recorder();
          

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

          1. 配置WebScoket

          pom文件

          
              org.springframework
              spring-websocket
              5.3.9
          
          
          @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 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版本中生效!!!

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]