vue中使用微信jssdk语音聊天功能,实现语音输入内容的van-field输入框组件

一、配置项

1、绑定域名
2、引入JS文件
前两步直接看官方文档
3、wx.config配置:
这边要注意有一个坑必须要注意一下:可能会遇到安卓系统配置正常,ios上面报签名无效配置失败。
如果是使用的hash模式的路由应该不会遇到这种情况,毕竟使用官方的方法取#前面的地址应该都是一样的。如果用的history路由模式的要注意一下:
因为用的是vue单页spa,在单页spa方面vue的history在iOS中页面地址会始终为第一次进入的链接地址。然后微信那边校验的页面地址跟我们传的不一样就会出现校验失败的问题,所以在ios中我们要判断一下,记录第一次进入的地址,然后将他传给接口就可以了。
可以在路由守卫中存储第一次进入的地址:

// 路由加载前
router.beforeEach((to, _from, next) => {
    
    
  if(!window.initUrl){
    
    
    window.initUrl = location.href.split('#')[0];
  }
  next()
})

 // 获取小程序配置
    getWxConfig() {
    
    
      let req = {
    
    
        url:'',
      };
      // 判断ios和安卓
      if (this.agent == 'ios') {
    
    
        req.url = window.initUrl;
      }else{
    
    
        req.url = window.location.href.split("#")[0];
      }
      this.$apiData.getWxConfig(req).then((res) => {
    
    
        if (res.data.code == "0000") {
    
    
          wx.config({
    
    
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来。
            appId: data.appId, // 必填,公众号的唯一标识
            timestamp: data.timestamp, // 必填,生成签名的时间戳
            nonceStr: data.nonceStr, // 必填,生成签名的随机串
            signature: data.signature, // 必填,签名
            jsApiList: [ "startRecord","stopRecord", "playVoice","pauseVoice","stopVoice","uploadVoice", "downloadVoice","downloadVoice","translateVoice","onVoiceRecordEnd",], // 必填,需要使用的JS接口列表
          });
        } 
      });
    },

二、父组件

<speek-field :value="person.age" label="年龄" placeholder="请输入年龄" required :rules="[{pattern:'/^((\d) | ([1-9]\d))$/',message:'请输入正确的年龄'}]"
@inputStop="(val)=>{inputStop('age',val)}"/>
inputStop(label,value){
    
    
	this.$set(this.person,label,value)
}

三、输入框子组件

只实现简单的语音转文字,不做语音的上传;录音时长应不超过1分钟,否则执行wx.onVoiceRecordEnd

1、html页面部分

<van-field
v-model="value"
:label="label"
:placeholder="placeholder"
:required="required"
:rules="rules"
@input="input"
>
	<template #button>
		<van-button size="mini" type="primary" @touchstart="touchstart" @touchend="touchend">长按录音</van-button>
	</template>
</van-field>

2、JS部分

<script>
import {
    
    Toast} from 'vant'
export default{
    
    
	name:'speek-field',
	data(){
    
    
		return{
    
    
			isRecord:false,
		}
	},
	props:{
    
    
		value:String,
		label:String,
		placeholder:String,
		required:{
    
    
			type:Boolean,
			default:()=> false
		},
		rules:{
    
    
	      type:Array,
	      default:()=>[]
	    }
	},
	methods:{
    
    
		input(value){
    
    
		//键盘输入内容时节流,1s不再不输入则任务停止输入
	      clearTimeout(this.timer)
	      this.timer=setTimeout(()=>{
    
    
	        this.$emit('inputStop',value);
	        clearTimeout(this.timer)//输入内容传给父组件后,则清除定时器
	      },1000)
	    },
	    touchstart(e){
    
    
	      e.preventDefault();//阻止默认事件
	      this.timeOut = setTimeout(() => {
    
    
	        console.log('在这里执行长按事件---',);
	        wx.startRecord({
    
    
		        success: () => {
    
    
		          this.voiceTimer = setInterval(() => {
    
    
		            this.voiceTime++;
		          }, 1000);
		          this.voiceEnd();
		        },
		        cancel: () => {
    
    
		          Toast("用户拒绝授权录音");
		        },
		    });//开始录音
	        this.timeOut = 0//若开始录音,timeOut=0,当结束录音时,执行停止录音函数
	        this.isRecord = true
	      }, 500);
	    },
	    touchend(e){
    
    
	      e.preventDefault();
	      clearTimeout(this.timeOut)//结束录音时清除定时器
	      if (this.timeOut!=0) {
    
    
	      //点击事件的逻辑
	        this.$toast.show('长按录音')
	      }else{
    
    
	      //长按事件的逻辑
	        if (this.isRecord) {
    
    
	          this.endSpeek()
	          this.isRecord=false
	        } else {
    
    
	          return
	        }
	      }
	    },
	    voiceEnd() {
    
    
	      let that = this;
	      wx.onVoiceRecordEnd({
    
    
	        // 录音时间超过一分钟没有停止的时候会执行 complete 回调
	        complete: async (res)=> {
    
    
	          that.voiceLocalId = res.localId;
	          clearInterval(that.voiceTimer);
	          await  that.translateResult();
	        },
	      });
	    },
	    endSpeek(){
    
    
	    	wx.stopRecord({
    
    
			  success: (res) => {
    
    
			  //录音结果
			    this.voiceLocalId = res.localId;
			    //语音转文字
			    this.translateResult()
			    }
			});
	    },
	    translateResult(){
    
    
	    	wx.translateVoice({
    
    
		        localId: this.voiceLocalId, // 需要识别的音频的本地Id,由录音相关接口获得,时长不超过1分钟
		        isShowProgressTips: 0, // 默认为1,显示进度提示
		        success: (res)=> {
    
    
		          console.log("res.translateResult", res.translateResult); // 语音识别的结果,输出的字符串最后有一个句号“。”,用slice删掉
		          let speekRes = res.translateResult.slice(0,res.translateResult.length-1)
		          this.$emit('inputStop', speekRes)//把语音结果传给父组件
		        },
		        fail: (error) => {
    
    
			       Toast(error + "语音停止失败");
		        },
	      });
	    }
	},
}
</script>

参考链接:
1、https://blog.csdn.net/weixin_45442630/article/details/121415829
2、官方文档

拜拜

猜你喜欢

转载自blog.csdn.net/qq_33235680/article/details/127426409