当前位置: 首页 > news >正文

uniapp中实现语音识别(app+小程序)

一.app版本需要先去百度智能云申请
在这里插入图片描述

注意填写完,需要打包成自定义基座或者安装rpk包,本地是无效的

封装recording-popup.vue组件

<template><up-popup round="16" closeable :show="recordShow" :close-on-click-overlay="false" :safe-area-inset-bottom="false"@close="close" @open="open"><view class="tag-popup-box"><view class="title"><text>{{ tips }}</text><imagesrc="https://observe-oss.oss-cn-shanghai.aliyuncs.com/wisdom-bay-vue/home/home-icon-close-gray-20.075vw%402x.png"@click="close" /></view><view class="voice-box"><imagesrc="https://observe-oss.oss-cn-shanghai.aliyuncs.com/wisdom-bay-vue/home/home-release-recording-blue-90px%402x.png"class="voice-icon" @click="startRecord" /></view></view></up-popup>
</template>
<script setup>import {onBeforeUnmount,onMounted,ref,watch} from "vue";const recordShow = ref(false)const tips = ref('点击开始录音')const emits = defineEmits(['micInput'])const startRecord = async () => {// #ifdef H5uni.showToast({title: '浏览器暂不支持该功能,请前往APP体验',icon: 'none',duration: 2000})// #endif// #ifdef APP-PLUSlet options = {engine: 'baidu',timeout: 10 * 1000, //超时时间punctuation: true, //是否需要标点符号continue: true, //语音识别是否采用持续模式userInterface: true, //安卓手机为true时会影响@touchend触摸结束事件,暂未发现好的解决方法};plus.speech.startRecognize(options, (s) => {emits('micInput', s)}, (errMsg) => {console.log('语音识别失败:' + JSON.stringify(errMsg));});// #endif}const onEnd = () => {close()}const open = () => {// #ifdef H5uni.showToast({title: '浏览器暂不支持该功能,请前往APP体验',icon: 'none',duration: 2000})// #endif// #ifdef APP-PLUSconst info = uni.getAppAuthorizeSetting();if(info.microphoneAuthorized !== 'authorized') {plus.nativeUI.toast('请打开麦克风权限,再重启应用');return false;}plus.speech.addEventListener('end', onEnd, false);// #endif}const close = () => {recordShow.value = false// #ifdef APP-PLUSplus.speech.stopRecognize();// #endif}onBeforeUnmount(() => {// #ifdef APP-PLUSplus.speech.stopRecognize();// #endif})defineExpose({recordShow})
</script>
<style scoped lang="scss">.tag-popup-box {height: 19.655vw;background: #FFFFFF;width: 100%;padding: 1.5vw 1.5vw 0;box-sizing: border-box;border-radius: 1.2vw 1.2vw 0vw 0vw;.voice-box {width: 100%;display: flex;justify-content: center;margin-top: 2.251vw;.voice-icon {width: 6.752vw;height: 6.752vw;}}.title {display: flex;justify-content: space-between;align-items: center;margin-bottom: 2.251vw;&>text {font-size: 1.125vw;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: #333333;line-height: 1.65vw;}&>image {width: 1.65vw;height: 1.65vw;}}.content {width: 100%;height: 3.601vw;background: rgba(153, 153, 153, 0.08);border-radius: 0.45vw;padding: 0 0.975vw;box-sizing: border-box;}.confirm-btn {margin-top: 5.176vw;width: 100%;height: 3vw;text-align: center;background: #07B780;border-radius: 0.3vw;font-size: 1.05vw;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #FFFFFF;line-height: 3vw;}}
</style>

使用recording-popup

<recording-popup ref="recordingPopupRef" @mic-input="micInput" />const recordingPopupRef = ref('')
const text = ref('')const openRecord = () => {recordingPopupRef.value.recordShow = true
},
const micInput = (str) => {//如果你知道输入框的cursor,就可以像我这样写,要是不知道就写成text.value += str了if (cursor === 0) {text.value += str} else {text.value = text.value.slice(0, cursor) + str + text.value.slice(cursor);}
}

二.小程序版本,进入微信小程序后台-->进入设置-->第三方设置-->添加插件->搜索同声传译-->完成添加。
在这里插入图片描述
在manifest.json文件中增加插件版本等信息

 "mp-weixin" : {"plugins" : {"WechatSI" : {"version" : "0.3.5","provider" : ""}},}

封装recording-popup.vue组件

<template><view><u-popupround="16" :show="recordShow" :close-on-click-overlay="false":safe-area-inset-bottom="false"@close="close"@open="open"><view class="tag-popup-box"><view class="title"><text>{{ tips }}</text><imagesrc=""@click="close"/></view><view class="voice-box" @touchstart="startRecord" @touchend="stopRecord" @touchcancel="stopRecord"><imagesrc=""class="voice-icon"/></view></view></u-popup></view>
</template>
<script setup lang="ts">
import {onMounted, ref, watch} from "vue";
let start = false
const tips = ref<string>('按住开始录音')
const props = defineProps({show: {type: Boolean,default: false}
})
const manager = ref<any>()
const emits = defineEmits(['update:show','startRecord','textChange','micInput'])const startRecord = async () => {if (start) return // 防止还在识别中时又触发录音console.log('touch started')tips.value = '准备中...'try {await checkPermission()} catch (e) {tips.value = '需要授权'return}manager.value.start()emits("startRecord")
}const stopRecord = () => {if (!start) return // 触发极短时间,stop会在还未start的情况下触发console.log('touch ended or canceled')manager.value.stop()
}watch(() => props.show, (value) => {recordShow.value = value
})const recordShow = ref<boolean>(props.show)
const open = () => {manager.value = requirePlugin("WechatSI").getRecordRecognitionManager()// recordShow.value = truemanager.value.onStart = (e:any) => {console.log('on-start')console.log(e)start = truetips.value = '正在识别...'}manager.value.onStop = (e:any) => {console.log('on-stop')console.log(e)start = falseif (e.result){tips.value = '按住开始录音'emits("micInput", e.result)} else {tips.value = '识别失败,请重试'}}manager.value.onRecognize = (e:any) => {console.log('on-recognize')console.log(e)}manager.value.onError = (e:any) => {console.log('on-error')console.log(e)start = falsetips.value = '识别失败,请重试'}
}
const close = () => {recordShow.value = falseemits('update:show', recordShow.value)
}const  checkPermission = async () => {const sRes = await uni.getSetting()if (sRes.authSetting['scope.record']) returntry {const aRes = await uni.authorize({scope: 'scope.record'})} catch (e) {const mRes = await uni.showModal({title: '授权',content: '请打开 录音功能 权限以便进行语音识别',showCancel: true,})if (mRes.cancel) throw new Error('授权失败')const sRes = await uni.openSetting()if (sRes.authSetting['scope.record']) {uni.showModal({title: '授权成功',content: '请继续点击下方按钮 进行语音输入',showCancel: false})throw new Error('授权成功')}throw new Error('授权失败')}
}
</script>
<style scoped lang="scss">
.tag-popup-box{height: 524rpx;background: #FFFFFF;width: 100%;padding: 40rpx 40rpx 0 ;box-sizing: border-box;border-radius: 32rpx 32rpx 0rpx 0rpx;.voice-box{width: 100%;display: flex;justify-content: center;margin-top: 60rpx;.voice-icon{width: 180rpx;height: 180rpx;}}.title{display: flex;justify-content: space-between;align-items: center;margin-bottom: 60rpx;&>text{font-size: 30rpx;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: #333333;line-height: 44rpx;}&>image{width: 44rpx;height: 44rpx;}}.content{width: 100%;height: 96rpx;background: rgba(153, 153, 153, 0.08);border-radius: 12rpx;padding: 0 26rpx;box-sizing: border-box;}.confirm-btn{margin-top: 138rpx;width: 100%;height: 80rpx;text-align: center;background: #07B780;border-radius: 8rpx;font-size: 28rpx;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #FFFFFF;line-height: 80rpx;}
}
</style>

使用recording-popup

<recording-popup :show="recordShow" @mic-input="micInput" />const recordShow = ref<boolean>(false)
const text = ref('')const open = () => {
recordShow.value = true
}
const micInput = (str) => {//如果你知道输入框的cursor,就可以像我这样写,要是不知道就写成text.value += str了if (cursor === 0) {text.value += str} else {text.value = text.value.slice(0, cursor) + str + text.value.slice(cursor);}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++解决:早餐组合
  • 抽象代数精解【4】
  • Web开发:用C#的逻辑理解VUE语法(VUE + Webapi小白开发笔记)
  • k8s安装ingress-nginx
  • [H贪心] lc100376. 新增道路查询后的最短距离 II(贪心+读题+代码实现+周赛409_3)
  • web3 solana
  • 机器学习练手(六):机器学习算法实践实战
  • 【深度学习】【框架】【基本结构】transformer
  • Python如何将Category类的数组categoryList,导出成JSON格式
  • Action部署在线上写文章
  • C#根据反射操作对象
  • 操作系统篇--八股文学习第十二天| 什么是死锁,如何避免死锁?,介绍一下几种典型的锁,讲一讲你理解的虚拟内存
  • Typescript配置文件(tsconfig.json)详解系列五:allowArbitraryExtensions
  • PointNet点云语义分割
  • 使用Apache http client发送json数据(demo)
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【前端学习】-粗谈选择器
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Angular 响应式表单 基础例子
  • Angular数据绑定机制
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Linux各目录及每个目录的详细介绍
  • Python利用正则抓取网页内容保存到本地
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 码农张的Bug人生 - 见面之礼
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 走向全栈之MongoDB的使用
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​MySQL主从复制一致性检测
  • ​Redis 实现计数器和限速器的
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #《AI中文版》V3 第 1 章 概述
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (12)Hive调优——count distinct去重优化
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Matlab)使用竞争神经网络实现数据聚类
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (备份) esp32 GPIO
  • (二)学习JVM —— 垃圾回收机制
  • (篇九)MySQL常用内置函数
  • (七)glDrawArry绘制
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (五)activiti-modeler 编辑器初步优化
  • (小白学Java)Java简介和基本配置
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功