您的位置 首页 > 腾讯云社区

腾讯云语音识别云开发微信小程序---用户1529147

一、实现方式

通过录音管理器 RecorderManager调用手机的录音功能实现音频的在线采集,通过采集到的音频的base64字符串调用云开发侧实现的腾讯云一句话识别云函数,然后将识别结果回调到小程序页面中。

二、实现流程第一步:开通云开发控制台并创建云端项目环境

添加描述

添加描述

添加描述

第二步:在小程序项目根目录下创建本地云函数根目录functions,在项目根目录找到 project.config.json 文件,新增 cloudfunctionRoot 字段,值为刚才创建的本地云函数根目录名称第三步:创建一句话识别云函数并配置tencentcloud-sdk-nodejs依赖第四步:安装依赖

在asr云函数目录上右键选择在"在终端中打开"

E:tencentcloudcodewechatfunctionsasr>npm install npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 > protobufjs@6.8.8 postinstall E:tencentcloudcodewechatfunctionsasrnode_modulesprotobufjs > node scripts/postinstall npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN asr@1.0.0 No description npm WARN asr@1.0.0 No repository field. added 101 packages from 194 contributors and audited 186 packages in 8.85s found 0 vulnerabilities

第五步:在一句话识别云函数目录下的入口文件index.js中实现一句话识别的API调用Demo,然后上传Demo至云端// 云函数入口文件 const cloud = require('wx-server-sdk') // 引入云开发服务的内核SDK cloud.init( //初始化一个'wx-server-sdk' SDK 实例 { env: 'ai-test-t7t64' // 开通云开发服务后创建的云环境的环境ID(默认可以创建两个ID) } ) // 云函数入口函数 exports.main = async (event, context) => { const tencentcloud = require("tencentcloud-sdk-nodejs"); //引入腾讯云SDK // 下面的代码可以通过explorer在线生成(https://console.cloud.tencent.com/api/explorer?Product=aai&Version=2018-05-22&Action=SentenceRecognition&SignVersion=) const AaiClient = tencentcloud.aai.v20180522.Client; const models = tencentcloud.aai.v20180522.Models; const Credential = tencentcloud.common.Credential; const ClientProfile = tencentcloud.common.ClientProfile; const HttpProfile = tencentcloud.common.HttpProfile; let cred = new Credential("", ""); let httpProfile = new HttpProfile(); httpProfile.endpoint = "aai.tencentcloudapi.com"; let clientProfile = new ClientProfile(); clientProfile.httpProfile = httpProfile; let client = new AaiClient(cred, "ap-guangzhou", clientProfile); let req = new models.SentenceRecognitionRequest(); let base64Data=event.x //接收客户端post的x参数,值类型为base64字符串 let DataLen = event.s //接收音频文件的大小 var params = {"ProjectId":0,"SubServiceType":2,"EngSerViceType":"16k_zh","SourceType":1,"VoiceFormat":"mp3","UsrAudioKey":"www","Data":base64Data,"DataLen":DataLen} // 定义SDK的请求参数字典 params = JSON.stringify(params) // 转换为json字符串 req.from_json_string(params); return new Promise((resolve, reject) => { // 通过Promise容器来接收异步API的回调,然后通过当前脚本返回给客户端 client.SentenceRecognition(req, function(errMsg, response) { // 此接口是异步的,那么当前脚本无法对外直接访问接口返回值 if (errMsg) { resolve({ "Result": errMsg }) } // resp = response.to_json_string() resolve({ "Result": response}) }); }) }

注:云函数的入口文件index.js中调用的"一句话识别"API方法"SentenceRecognition”是异步的,如果直接拷贝Explorer中生成的Demo,将无法为小程序客户端返回"SentenceRecognition”的回调数据,脚本最终会返回null;所以这里我们需要使用Promise对象来获取"SentenceRecognition"的回调数据,然后返回给小程序客户端

第六步:小程序中实现音频在线采集页面voicec.wxml<!--pages/voicec/voicec.wxml--> <view class="REC"> <view class="time">{{status==0?'录音时长':(status==3?'录音结束':'录音中')}}:{{time}} 秒 ({{duration/1000}}秒)</view> <view class="rin"> <view class="{{status==3 && actionStatus==0?'show':'hide'}}" bindtap="play" hover-class="skip">{{actionStatus==1?'播放中':'播放录音'}}</view> <view class="{{status==3?'show':'hide'}}" bindtap="again" hover-class="skip">再次录制</view> </view> <view class="anniu"> <view class="{{status==0?'highlight':'gray'}}" bindtap="start" hover-class="skip">开始</view> <view class="{{status==1?'highlight':'gray'}}" bindtap="stop" hover-class="skip">暂停</view> <view class="{{status==2?'highlight':'gray'}}" bindtap="continue" hover-class="skip">继续</view> <view class="{{(status==1 || status==2)?'highlight':'gray'}}" bindtap="shutoff" hover-class="skip">停止</view> <view class="{{status==3?'highlight':'gray'}}" bindtap="recognition" hover-class="skip">识别</view> </view> <view class="progress"> <progress percent="{{time*(100/(duration/1000))}}" stroke-width="10" backgroundColor="#fff" border-radius="15" stroke-width="4" color="#7FFF00" active /> </view> </view> <view class=".REC"> <textarea placeholder="录音完成后点击识别可将音频转文字" auto-focus value="{{ Words }}" /> </view>

使用的组件:

进度条progress

多行输入框textarea

使用的视图容器:

view

使用的XML语法:

双大括号数据绑定之三元运算

使用的视图层:

bindtap事件绑定

voicec.js// pages/voicec/voicec.js const recorderManager = wx.getRecorderManager() const innerAudioContext = wx.createInnerAudioContext() var init Page({ /** * 页面的初始数据 */ data: { voiceSize:0, time: 0, duration: 60000, localFilePath: "", status: 0, actionStatus: 0, }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function() { }, /** * 生命周期函数--监听页面显示 */ onShow: function() { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function() { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function() { }, /** * 用户点击右上角分享 */ onShareAppMessage: function() { }, /**开始录音 */ start: function() { clearInterval(init) recorderManager.onStart((res) => { console.log('开始录音') this.setData({ status: 1 }) }) recorderManager.onStop((res) => { console.log('停止录音', res) this.setData({ tempFilePath: res.tempFilePath, status: 3 }) this.timeCounter(this.data.time) }) const options = { duration: this.data.duration, format: 'mp3', } this.timeCounter() recorderManager.start(options) }, /** * 录音暂停 */ stop: function() { recorderManager.onPause(() => { console.log('recorder pause') this.setData({ status: 2 }) }) this.timeCounter(this.data.time) recorderManager.pause() }, /** * 录音继续 */ continue: function() { this.setData({ status: 1 }) this.timeCounter() recorderManager.resume() }, /** * 录音停止 */ shutoff: function() { recorderManager.onStop((res) => { console.log('recorder stop', res) this.setData({ tempFilePath: res.tempFilePath, status: 3 }) }) this.timeCounter(this.data.time) recorderManager.stop() }, /** * 录音识别 */ recognition: function() { var that=this; wx.getFileInfo({ filePath:this.data.tempFilePath, success (res) { console.log("录音文件的大小为"+res.size) that.data.voiceSize=res.size } }) wx.cloud.init() wx.cloud.callFunction({ // 云函数名称 name: 'asr', // 传给云函数的参数 data: { s:that.data.voiceSize, x: wx.getFileSystemManager().readFileSync(this.data.tempFilePath, 'base64') //传入去掉格式的的base64字符串 }, success: function(res) { console.log(res) that.setData({ Words: res.result.Result.Result }) }, fail: console.error }) }, /** * 录音播放 */ play: function() { innerAudioContext.src = this.data.tempFilePath innerAudioContext.obeyMuteSwitch = false if (this.data.actionStatus == 0) { this.setData({ actionStatus: 1 }) innerAudioContext.play() } innerAudioContext.onEnded(() => { innerAudioContext.stop() this.setData({ actionStatus: 0 }) }) }, timeCounter: function(time) { var that = this if (time == undefined) { init = setInterval(function() { var time = that.data.time + 1; that.setData({ time: time }) }, 1000); } else { clearInterval(init) console.log("暂停计时") } }, /** * 重新录制 */ again: function() { var that = this wx.showModal({ title: "重新录音", content: "是否重新录制?", success(res) { if (res.confirm) { that.setData({ time: 0, tempFilePath: "", status: 0, actionStatus: 0 }) innerAudioContext.stop() } } }) } })

使用到的知识点: Page 构造器

录音管理器

HTTPS 网络请求

文件管理器FileSystemManager读取指定编码的文件内容

数据传递setData

注意:如果自定义函数中嵌套了wx等对象函数,数据传递应该先声明"var that=this",然后再嵌套函数,如wx.request中使用"that.setData"来传递数据

voicec.json{ "navigationBarTitleText": "云开发一句话识别在线测试", "backgroundColor": "#eeeeee" }

全局配置

voicec.wxss/* pages/voicec/voicec.wxss */ .REC { border-radius: 25rpx; background-color: rgb( 199,237,204 ); padding: 6rpx 0rpx; margin: 15rpx 35rpx; } .rin { justify-content: space-between; align-items: center; margin: 0rpx 120rpx; display: flex; } .rin .show { background-color: rgb(178, 228, 228); padding: 15rpx; width: 210rpx; border: 5rpx solid rgb(127, 204, 214); border-radius: 20rpx; font-size: 28rpx; display: flex; justify-content: center; align-items: center; } .rin .hide { padding: 15rpx; align-items: center; border-radius: 20rpx; display: flex; width: 215rpx; font-size: 28rpx; justify-content: center; border: 5rpx solid #eee; pointer-events: none; background-color: rgba(137, 190, 178, 0.445); } .time { text-align: center; line-height: 75rpx; font-size: 28rpx; } .progress { margin: 25rpx; } .play { margin: 0rpx 25rpx; } .content { line-height: 60rpx; font-size: 28rpx; display: flex; justify-content: center; } .anniu { display: flex; margin: 10rpx 50rpx; justify-content: space-between; } .highlight { display: flex; font-size: 28rpx; width: 80rpx; height: 80rpx; justify-content: center; border-radius: 50%; align-items: center; background-color: rgb(107, 194, 53); border: 5rpx solid rgb(127, 204, 214); } .skip { transform: scale(0.9); } .anniu .gray { pointer-events: none; background-color: rgba(137, 190, 178, 0.445); display: flex; width: 80rpx; height: 80rpx; font-size: 28rpx; justify-content: center; align-items: center; border-radius: 50%; border: 5rpx solid rgb(241, 244, 245); }

WXSS样式学习

测试效果

---来自腾讯云社区的---用户1529147

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: