文章由来
这里通过简单的对话形式来描述接下来要讲的bug,相关界面在文章中都有展示,可以结合相关图片更好的理解问题
- 测试小伙伴:界面一直停留在(语音识别中...);
- 我:都到识别这一步了,应该是测试环境下后台不稳定吧,你再多试几次;
- 测试小伙伴:我去问后台了,后台说应该是前端这边的问题;
- 我:(开始检查代码),好像我这边代码也没有问题啊,你是怎么操作的?
- 测试小伙伴:我点击了一下录音键,然后就一直转圈圈;
- 我:不是长按?
- 测试小伙伴:不是,就一般的点击操作;
- 我:(开始检查代码),我这边再看看,好了跟你说。。。
定位问题
RecorderManager.stop()事件好像没生效,进微信社区查了一通,以下是社区反馈的问题捡几个重点,感兴趣的可以看看
微信社区相关反馈
问题二、小程序recorderManager.stop()发生延迟停止,求解?
- 综合上面几篇文章,终于定位到问题所在,接下来就是如何解决这个问题了
简化后代码
<!-- UI界面中红框组件 -->
<template>
<div class="select-time">
<h3 class="title">工作时间</h3>
<textarea placeholder="例:每周一三五,上午 8:00-10:00" v-model="text" @blur="changeVal" placeholder-style="color:#b2b2b2;"></textarea>
<image :src="iconRecord" @longpress ="startRecord" @touchend="endRecord" @tap="authorization" />
</div>
</template>
<script>
import tool from '@/utils/tool' // 工具方法
const recorder = wx.getRecorderManager() // 录音管理器实例
export default {
data () {
return {
iconRecord: require('@static/icon/icon_voice.png'), // 录音icon
recordFlag: false // 控制endRecord事件执行
}
},
props: {
text: {
type: String,
default: ''
} // textarea的值
},
methods: {
changeVal (e) {
const that = this
that.$emit('getTime', e.mp.detail.value)
// 调用父组件方法,并把值赋给父组件事先定义好的属性内
},
// icon点击事件
authorization () {
const that = this
wx.getSetting({
success (res) {
if (!res.authSetting['scope.record']) {
wx.authorize({
scope: 'scope.record',
success () {
// 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
},
fail () {
that.failSetting()
}
})
} else {
// that.startRecord()
tool.showToast('请长按说话', 500)
}
}
})
},
// icon长按事件
startRecord () {
tool.showRecordLoading('语音输入中...')
this.recordFlag = true
recorder.start({
duration: 15000,
format: 'mp3'
})
},
// 手指离开屏幕事件
endRecord () {
const that = this
// 除非recordFlag为true,否则不执行接下来的逻辑
if (that.recordFlag) {
wx.getSetting({
success (res) {
if (res.authSetting['scope.record']) {
wx.hideLoading()
tool.showRecordLoading('语音识别中...')
recorder.stop()
recorder.onStop(res => {
const { tempFilePath } = res
wx.uploadFile({
url: '语音识别接口', // 接口地址
header: {
// 请求头相关配置
},
name: 'voice', // 上传文件名
filePath: tempFilePath,
success (res) {
wx.hideLoading()
const temp = JSON.parse(res.data)
if (temp.code === 1) {
// 得到语音转后的文字后拼接到原来的输入框内容之后,并赋值给父组件
that.$emit('getTime', that.text + temp.data)
}
that.recordFlag = false
},
fail () {
wx.hideLoading()
that.recordFlag = false
tool.showToast('语音识别失败')
}
})
})
} else {
wx.hideLoading()
}
}
})
}
},
// 拒绝授权和再次点击录音icon时触发前往授权的引导窗
failSetting () {
wx.showModal({
title: '提示',
content: '您未授权录音,功能将无法使用',
showCancel: false,
confirmText: '前往授权',
confirmColor: '#5bb53c',
success: function (res) {
wx.openSetting({
success (res) {
// console.log(res)
}
})
}
})
}
}
}
</script>
这里着重说几点改动:
- 在录音icon上增加一个tap事件,事件作用是负责授权相关引导及提醒用户长按操作,不清楚微信授权的可以看看我上篇文章的讲解;
- 将原来的touchstart事件换成longpress事件,只有用户长按时才会触发录音事件;
- 添加一个recordFlag属性,控制touchend事件内部逻辑是否执行;
- 最后简单提一下自己改造后的wx.showToast即上面的tool.showToast(默认显示时间为1.5s)
function showToast (name, duration = 1500) {
wx.showToast({
title: name,
icon: 'none',
duration: duration,
mask: true
})
}
UI界面
接下来重点展示相关的语音识别操作界面
未操作录音功能的静态页
重点关注下图红框及红框内的绿色区域(录音icon)
授权界面
用户首次进入页面,点击录音icon会出发授权弹窗
拒绝授权的相关界面
当用户点击上图拒绝按钮,引导用户进入授权设置页,让用户知道只有授权录音后才能使用录音功能
当用户点击上图的前往授权进入授权设置页
允许授权的相关界面
当用户点击录音icon,并不是长按icon,这时提示用户请长按说话
当用户长按录音icon开始提示用户这个时候正在进行录音操作,可以说话了,即(语音输入中 ...)
当用户手指移开录音icon后,提示用户正在识别语音,这个时候说话也没用,不记录了,即(语音识别中 ...)
效果图
总结
- 看到这里肯定有人会说我小题大做
- 写文章并不全是为了给别人看的
- 你们可以认为记录仅仅是我个人的一种习惯
- 如果你正要做这个功能或想要做这个功能,看到这个文章希望多少能给你带来一点提示作用
- 如果真的帮助到你,请不要吝啬你的赞