本文介绍如何使用阿里云智能语音服务提供的微信小程序SDK,包括SDK的安装方法及SDK代码示例。
前提条件
在使用SDK前,请先阅读接口说明,详情请参见接口说明。
下载安装
下载并安装SDK。
通过Github下载对应SDK代码,或直接下载alibabacloud-nls-wx-sdk-master.zip。
导入SDK。
您可将下载好的代码放入工程合适目录下,然后根据目录位置通过require进行导入。
获取Token
getToken
获取Token并以AKID(AccessKey ID)和AKKEY(AccessKey Secret)为key缓存对应Token,如果缓存的Token过期则自动刷新并获取。缓存机制请参见微信小程序文档的数据缓存部分。
参数说明:无。
返回值:String类型的Token。
getTokenInner
直接获取Token,不带任何缓存机制,适用于用户自定义缓存方式。
参数说明:无。
返回值:String类型的Token。
频繁调用该接口会被服务端拒绝访问。
关键接口和参数描述
实现语音合成的功能,围绕SpeechSynthesizer
类进行,一般按照如下步骤编写代码(步骤2和步骤3顺序可互换):
创建
SpeechSynthesizer
实例,此时会传入语音合成服务地址和认证信息。设置语音合成的发音人、采样率、音频格式等属性:创建属性对象或者修改
SpeechSynthesizer
实例的defaultStartParams
方法返回的默认属性对象。补充
SpeechSynthesizer
实例的回调函数on
的细节(观察者模式——当连接成功建立、合成语音、发生异常等时,服务器会通过回调on
函数通知客户端)。调用
SpeechSynthesizer
实例的start
函数开始语音合成。
代码示例
以下代码示例仅供参考,代码中使用微信小程序自带录音功能,实际使用时,需要考虑微信小程序的限制,以及前端页面设计和具体业务功能。
// pages/tts/tts.js
const app = getApp()
const AKID = "Your AKID"
const AKKEY = "Your AKKEY"
const SpeechSynthesizer = require("../../utils/tts")
const formatTime = require("../../utils/util").formatTime
const sleep = require("../../utils/util").sleep
const getToken = require("../../utils/token").getToken
const fs = wx.getFileSystemManager()
Page({
/**
* 页面的初始数据
*/
data: {
ttsStart: false,
ttsText: ""
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: async function (options) {
try {
this.data.token = await getToken(AKID, AKKEY)
} catch (e) {
console.log("error on get token:", JSON.stringify(e))
return
}
let tts = new SpeechSynthesizer({
url: app.globalData.URL,
appkey:app.globalData.APPKEY,
token:this.data.token
})
tts.on("meta", (msg)=>{
console.log("Client recv metainfo:", msg)
})
tts.on("data", (msg)=>{
console.log(`recv size: ${msg.byteLength}`)
//console.log(dumpFile.write(msg, "binary"))
if (this.data.saveFile) {
try {
fs.appendFileSync(
this.data.saveFile,
msg,
"binary"
)
console.log(`append ${msg.byteLength}`)
} catch (e) {
console.error(e)
}
} else {
console.log("save file empty")
}
})
tts.on("completed", async (msg)=>{
console.log("Client recv completed:", msg)
await sleep(500)
fs.close({
fd : this.data.saveFd,
success: (res)=> {
let ctx = wx.createInnerAudioContext()
ctx.autoplay = true
ctx.src = this.data.saveFile
ctx.onPlay(() => {
console.log('start playing..')
})
ctx.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
fs.unlink({
filePath: this.data.saveFile,
success: (res)=>{
console.log(`remove ${this.data.saveFile} done`)
this.data.saveFile = null
this.data.saveFd = null
},
failed: (res)=>{
console.log("remove failed:" + res.errMsg)
}
})
})
ctx.onEnded((res)=>{
console.log("play done...")
fs.unlink({
filePath: this.data.saveFile,
success: (res)=>{
console.log(`remove ${this.data.saveFile} done`)
this.data.saveFile = null
this.data.saveFd = null
},
failed: (res)=>{
console.log("remove failed:" + res.errMsg)
}
})
})
},
fail : (res)=>{
console.log("saved file error:" + res.errMsg)
}
})
})
tts.on("closed", () => {
console.log("Client recv closed")
})
tts.on("failed", (msg)=>{
console.log("Client recv failed:", msg)
})
this.data.tts = tts
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
textInput: function(e) {
this.setData({
ttsText:e.detail.value
})
},
onTtsStart: function() {
if (!this.data.ttsText || !this.data.tts) {
console.log("text empty")
wx.showToast({
title: "文本为空",
icon: "error",
duration: 1000,
mask: true
})
return
}
if (this.data.ttsStart) {
wx.showToast({
title: "正在合成请稍候",
icon: "error",
duration: 1000,
mask: true
})
return
} else {
this.data.ttsStart = true
}
console.log("try to synthesis:" + this.data.ttsText)
let save = formatTime(new Date()) + ".wav"
let savePath = wx.env.USER_DATA_PATH + "/" + save
console.log(`save to ${savePath}`)
fs.open({
filePath:savePath,
flag : "a+",
success: async (res)=> {
console.log(`open ${savePath} done`)
this.data.saveFd = res.fd
this.data.saveFile = savePath
let param = this.data.tts.defaultStartParams()
param.text = this.data.ttsText
param.voice = "aixia"
try {
await this.data.tts.start(param)
console.log("tts done")
this.data.ttsStart = false
} catch(e) {
console.log("tts start error:" + e)
}
},
fail: (res)=> {
console.log(`open ${savePath} failed: ${res.errMsg}`)
}
})
}
})