微信小程序调用科大讯飞语音文字转换无服务器代理解决方案
在使用小程序开发中有需求要用到科大讯飞的语音文字转换功能 在寻求过很多解决办法后没有找到较为合适的办法最终只能自行研究解决以下附上解决流程。网址,使用现有的微信扫码登录即可完成注册,然后通过这个网址。在录制语音开始时会触发科大讯飞鉴权事件鉴权代码如下。等待安装完成后打开小程序开发工具进行小程序的创建。删除自带所有代码后在主页添加按钮进行音频录制。wxml文件内容如下。wxss文件内容如下。
·
在使用小程序开发中有需求要用到科大讯飞的语音文字转换功能 在寻求过很多解决办法后没有找到较为合适的办法最终只能自行研究解决以下附上解决流程。
首先我们需要注册一个微信小程序开发者身份打开这个 首页 | 微信开放社区 网址,使用现有的微信扫码登录即可完成注册,然后通过这个网址微信开发者工具(开发版 Nightly Build)下载地址与更新日志 | 微信开放文档 进行工具下载
等待安装完成后打开小程序开发工具进行小程序的创建
选择第一个模板来进行项目创建
删除自带所有代码后在主页添加按钮进行音频录制
wxml文件内容如下
<view>
<button
class="tui-menu-list"
bindtouchstart="startRecordMp3" //按下按钮事件
bindtouchend="stopRecord" //抬起按钮事件
type="primary">长按录音开始</button>
</view>
wxss文件内容如下
.tui-menu-list{
position: absolute;
left: 0;
right: 0;
bottom: 10px;
margin: auto;
}
效果图如下
js文件代码如下
onLoad:function (options) {
const that = this
this.recorderManager = wx.getRecorderManager();
this.options = {
duration: 60000, // 指定录音的时常,单位ms
sampleRate: 8000, // 采样率
numberOfChannels: 1, // 录音通道数
encodeBitRate: 48000, // 编码码率
format: 'PCM', // 音频格式
frameSize: 5, // 指定帧大小,单位KB
}
this.recorderManager.onError(function () {
that.tip("录音失败!")
})
this.recorderManager.onStop(function (res) {
src = res.tempFilePath;
console.log(res.tempFilePath)
that.tip(res.tempFilePath)
})
this.recorderManager.onFrameRecorded((res) => {
const { frameBuffer } = res
var int16Arr = new Int8Array(res.frameBuffer);
const base64 = wx.arrayBufferToBase64(int16Arr)
switch (status) {
case 0:
status = 1;
var sendsty = '{"common":{"app_id":"讯飞的appid"},"business":{"language":"zh_cn","domain":"iat","accent":"mandarin","dwa":"wpgs","vad_eos":1000},"data":{"status":0,"format":"audio/L16;rate=8000","encoding":"raw","audio":"' + base64 + '"}}'
wxst.send({
data: sendsty
})
break;
case 1:
var sendsty = '{"data":{"status":1,"format":"audio/L16;rate=8000","encoding":"raw","audio":"' + base64 + '"}}'
wxst.send({
data: sendsty
})
break;
default:
console.log("default");
}
})
this.innerAudioContext = wx.createInnerAudioContext()
this.innerAudioContext.onError((res) =>{
that.tip(res)
})
},
按钮事件如下(包含录音权限获取)
//录制mp3
startRecordMp3: function (e) { //开始录音按钮
var that = this;
wx.getSetting({//查看用户有没有开启语音权限
success(res) {
if (res.authSetting['scope.record']) {
wx.authorize({
scope: 'scope.record',
success() {
that.stodd();
},
fail() {
wx.showModal({
title: '微信授权',
content: '您当前未开启语音权限,请在右上角设置(···)中开启“录音功能”',
showCancel: false,
success(res) {
if (res.confirm) {
console.log('用户点击确定')
}
}
})
}
})
}else{
var t = this;
wx.authorize({
scope: 'scope.record',
success (res){
console.log("录音授权成功",res);
//app.globalData.audioplay = true
// 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
// wx.startRecord();
t.recorderManager = uni.getRecorderManager();
t.innerAudioContext = uni.createInnerAudioContext();
// 为了防止苹果手机静音无法播放
uni.setInnerAudioOption({
obeyMuteSwitch: false
})
t.innerAudioContext.autoplay = true;
console.log("uni.getRecorderManager()",uni.getRecorderManager())
t.recorderManager.onStop(function (res) {
console.log('recorder stop' + JSON.stringify(res));
t.voicePath = res.tempFilePath;
});
},
fail(){
console.log("第一次录音授权失败");
wx.showModal({
title: '提示',
content: '您未授权录音,功能将无法使用',
showCancel: true,
confirmText: "授权",
confirmColor: "#AF1F25",
success(res){
if (res.confirm){
//确认则打开设置页面(自动切到设置页)
wx.openSetting({
success: (res) => {
console.log(res.authSetting);
if (!res.authSetting['scope.record']) {
//未设置录音授权
console.log("未设置录音授权");
wx.showModal({
title: '提示',
content: '您未授权录音,功能将无法使用', // 可以自己编辑
showCancel: false,
success: function (res) {
console.log("不知道打印的啥?")
},
})
} else {
//第二次才成功授权
console.log("设置录音授权成功");
//app.globalData.audioplay = true;
t.recorderManager = uni.getRecorderManager();
t.innerAudioContext = uni.createInnerAudioContext();
// 为了防止苹果手机静音无法播放
uni.setInnerAudioOption({
obeyMuteSwitch: false
})
t.innerAudioContext.autoplay = true;
console.log("uni.getRecorderManager()",uni.getRecorderManager())
t.recorderManager.onStop(function (res) {
console.log('recorder stop' + JSON.stringify(res));
t.voicePath = res.tempFilePath;
});
}
},
fail: function () {
console.log("授权设置录音失败");
}
})
} else if (res.cancel){
console.log("cancel");
}
} ,
fail (){
console.log("openfail");
}
})
}
})
}
}
})
},
//停止录音
stopRecord:function () { //结束录音按钮
var that = this;
const recorderManager = wx.getRecorderManager();
recorderManager.stop();
that.setData({//关闭遮罩层
shows: false,
})
},
在录制语音开始时会触发科大讯飞鉴权事件鉴权代码如下
const CryptoJS = require('crypto-js');
const Base64 = require('base64js').Base64;
var url = 'wss://iat-api.xfyun.cn/v2/iat'
var host = 'iat-api.xfyun.cn'
var apiKey = 科大讯飞官网获取'
var apiSecret = '科大讯飞官网获取'
var timedate = new Date().toString();
var strarr = timedate.split("+");
var timestr = strarr[0].toString();
var timearr = timestr.split(' ');
var date = timearr[0] + ", " + timearr[2] + " " + timearr[1] + " " + timearr[3] + " " + timearr[4] + " " + timearr[5];
console.log(date);
var algorithm = 'hmac-sha256'
var headers = 'host date request-line'
var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`
var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)
var signature = CryptoJS.enc.Base64.stringify(signatureSha)
var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
var authorization =Base64.encode(authorizationOrigin)
console.log(authorization)
url = `${url}?authorization=${authorization}&date=${encodeURIComponent(date)}&host=${host}`
const hosturl = url
设置录音格式并且沟通科大讯飞鉴权
stodd:function () {
const options = {
duration: 60000, // 指定录音的时常,单位ms
sampleRate: 8000, // 采样率
numberOfChannels: 1, // 录音通道数
encodeBitRate: 48000, // 编码码率
format: 'pcm', // 音频格式
frameSize: 5, // 指定帧大小,单位KB
}
const recorderManager = wx.getRecorderManager();
const app = getApp();
const hosturl = app.globalData.hosturl;
var xfurl = hosturl;
console.log(xfurl);
wxst = wx.connectSocket({ // 开启websocket连接
url: xfurl,
method: 'GET',
success: function (res) {
recorderManager.start(options);//开始录音
}
});
},
录制完成后提交数据
webSocketSend:function(audioData) {
console.log('开始发送数据',audioData)
let that = this
let audioDataUp = audioData.splice(0, 1)
var params = {
common: {
app_id:"科大讯飞官网控制台获取",
},
business: {
language:'zh_cn',
domain:'iat',
accent:'mandarin',
},
data: {
status: 0,
encoding: 'raw',
format: 'audio/L16;rate=8000',
data: that.toBase64(audioDataUp[0]),
},
}
console.log(JSON.stringify(params))
socketTask.send({data: JSON.stringify(params)})
handlerInterval = setInterval(() => {
// websocket未连接
if (!socketTask) {
clearInterval(handlerInterval)
return
}
// 最后一帧
if (audioData.length === 0) {
console.log('数据发送完毕')
socketTask.send(
{data:
JSON.stringify({
business: {
"language":"zh_cn",
"domain":"iat",
"accent":"mandarin"
},
data: {
status: 2,
encoding: 'raw',
format: 'audio/L16;rate=8000',
data: '',
},
})}
)
audioData = []
clearInterval(handlerInterval)
return false
}
audioDataUp = audioData.splice(0, 1)
// 中间帧
console.log('audioDataUp:',audioDataUp[0])
socketTask.send(
{
data:
JSON.stringify({
business: {
"language":"zh_cn",
"domain":"iat",
"accent":"mandarin"
},
data: {
status: 0,
encoding: 'raw',
format: 'audio/L16;rate=8000',
data: that.toBase64(audioDataUp[0]),
},
})}
)
}, 40)
},
result(resultData) {
// 识别结束
let jsonData = JSON.parse(resultData)
}
剩下的就是数据处理以及展示了。
本次内容也就告一段落了,后面等我页面数据处理完成并做完本地化后继续更新 喜欢的可以点赞关注下谢谢大家了。
更多推荐
已为社区贡献1条内容
所有评论(0)