当前位置:网站首页>小程序-语音播报功能
小程序-语音播报功能
2022-08-10 14:31:00 【吟秋知忆】
功能需求
实现通过传入“语音文案自动播报”,如:“测试播报”,语音自动播报“测试播报”
方案
使用wx.playVoice播放语音文件
优点:使用简单,直接播放录制好的音频文件
缺点:只能播放录制好的语音文件
第三方语音服务 + wx.createInnerAudioContext
优点:功能强大,可定制,可以满足复杂的场景;
缺点:需要服务端对接,付费
小程序插件 + wx.createInnerAudioContext
优点:简单快捷,适用于简单场景;
缺点:功能单一,无法定制,大写英文无法识别,部分小写英文发音不准
第三方语音平台
语音平台
服务端
对接第三方平台,将转换后的语音数据交给小程序。
小程序
1.添加请求
wx.request({
url: 'https://xxxx.com',
data: { data: "待合成的语音数据"},
method: "get",
header: {
'content-type': 'application/json' // 默认值
},
dataType: "json",
success: function (res) {
const innerAudioContext = wx.createInnerAudioContext();
innerAudioContext.src = res.filename;
innerAudioContext.play();
}
})
微信插件
添加 微信同声传译
插件:在微信公众平台配置,找到设置–第三方设置–插件管理–点击添加插件搜索 微信同声传译
,点击添加引入插件:在项目根目录app.json文件中配置
"plugins": {
// 引入插件
"WechatSI": { // 自定义的名字
"version": "0.3.5", // 引入插件的版本号
"provider": "wx069ba97219f66d99" // 引入插件的appID
}
}
使用
const plugin = requirePlugin('WechatSI');
onReady() {
this.innerAudioContext = wx.createInnerAudioContext();
const that = this;
plugin.textToSpeech({
// 调用插件的方法
lang: 'zh_CN',
content: '测试语音播报',
success: function (res) {
that.playAudio(res.filename);
}
});
},
playAudio(e) {
this.innerAudioContext.src = e;
this.innerAudioContext.play();
},
封装优化
const plugin = requirePlugin('WechatSI');
import { trim, isLetter } from '@/shared/index';
class PluginService {
innerAudioContext;
audioBroadcast(content: string): Promise<any> {
return new Promise((resolve, reject) => {
this.innerAudioContext = wx.createInnerAudioContext();
plugin.textToSpeech({
// 调用插件的方法
lang: 'zh_CN',
content,
success: res => {
this.playAudio(res.filename, resolve, reject);
},
fail: reject
});
});
}
playAudio(e, resolve, reject) {
this.innerAudioContext.src = e;
this.innerAudioContext.play();
this.innerAudioContext.onStop(() => {
console.log('[ onStop ] >');
resolve({
type: 'stop'
});
});
this.innerAudioContext.onEnded(() => {
//播放结束,销毁该实例
this.innerAudioContext.destroy();
console.log('[ onEnded ] >');
resolve({
type: 'end'
});
});
this.innerAudioContext.onError(error => {
console.log('[ onError ] >', error);
this.innerAudioContext.destroy();
reject(error);
});
}
stopAudio() {
this.innerAudioContext.stop();
this.innerAudioContext.destroy();
}
}
export default new PluginService();
在shared/index中工具函数:
// 去掉字符串中所有空格(包括中间空格,需要设置第2个参数为:true)
export function trim(str: string, isGlobal = true) {
if (!str) {
return str;
}
const result = str.replace(/(^\s+)|(\s+$)/g, '');
return isGlobal ? result.replace(/\s/g, '') : result;
}
// 判断是否为字母
export function isLetter(str) {
const reg = /^[A-Za-z]+$/;
return reg.test(str);
}
// 字母转中文
export function translateAlphabet(letters) {
if (!letters || !(letters.length > 0)) {
return letters;
}
let tLetters = '';
for (const key of letters) {
tLetters += alphabetComparison(key);
}
return trim(tLetters);
}
// 字母中文读法
export function alphabetComparison(letter) {
if (!letter || !isLetter(letter)) {
return letter;
}
const letterCase = letter.toUpperCase();
const letterMap = {
A: '诶',
B: 'b',
C: '西',
D: '帝',
E: '伊',
F: 'f',
G: 'g',
H: 'h',
I: 'i',
J: 'j',
K: 'k',
L: 'l',
M: 'm',
N: 'n',
O: '欧',
P: 'p',
Q: 'q',
R: 'r',
S: '爱死',
T: 't',
U: '优',
V: 'v',
W: 'w',
X: 'x',
Y: '歪',
Z: 'z'
};
return letterMap[letterCase];
}
在页面中使用
import { pluginService, translateAlphabet } from '@util';
import { formatCabinetNo, getCacheCabinet } from '@/shared/index';
Page({
...
onLoad(e) {
// 获取订单结果类型
this.autoPlay();
},
onUnload() {
pluginService.stopAudio();
},
// 轮询播放多次
autoPlay(timerCount = 0, maxCount = 100) {
const { address, lockerName } = this.data;
console.log('timerCount:', timerCount);
if (timerCount > maxCount) {
return;
}
const tAddress = translateAlphabet(address);
console.log('[ translateAlphabet ] >', tAddress);
// '认准柜门号再存放,不要存错门'
const message = `您的柜门号是${tAddress}${lockerName},请认准柜门号存放,不要存错门`;
pluginService
.audioBroadcast(message)
.then(res => {
if (res.type !== 'stop') {
this.autoPlay(++timerCount);
}
console.log('audioBroadcast.complete', res);
})
.catch(err => {
console.log('[ audioBroadcast.err ] >', err);
this.autoPlay(timerCount);
});
}
});
注意:
语音输入配额:每个小程序250条/分钟,3w条/天。 文本翻译配额:每个小程序500次/分钟,10w次/天。 语音合成配额:每个小程序100次/分钟,2w次/天。
问题归档
在小程序onHide,onUnload函数里调用 stop
方法无效;需要同时调用destroy
方法
this.innerAudioContext.stop();
this.innerAudioContext.destroy();
经测试发现中文中的大写英文字母无法识别,部分小写英文字母发音有误
参考
关注我
利用空闲时间免费兼职(无门槛,长期有效),请联系我(PS:关注公众号后,点击“联系我”获取联系方式)~
边栏推荐
- NAACL 2022 | 简单且高效!随机中间层映射指导的知识蒸馏方法
- 王学岗—————————哔哩哔哩直播-手写哔哩哔哩硬编码录屏推流(硬编)(26节课)
- usb转rs485测试软件,usb转rs485「建议收藏」
- 字节终面:CPU 是如何读写内存的?
- awk的简单使用
- 注意力模型---Attention Model
- Lack of comparators, op amps come to the rescue!(Op amp is recorded as a comparator circuit)
- 学习MySQL 临时表
- systemui屏蔽通知栏
- Classifying irises using decision trees
猜你喜欢
IT小白怎么系统的php学习
Classifying irises using decision trees
PyTorch multi-machine multi-card training: DDP combat and skills
Alibaba的秒杀系统—千亿级并发设计手册上线了
基于ArcGIS水文分析、HEC-RAS模拟技术在洪水危险性及风险评估
面试面到了一个腾讯30k出来的,有见识到何为精通MySQL调优
八大排序总是忘?快来这里~
机器学习总结(一)
Error: Rule can only have one resource source (provided resource and test + include + exclude)
Unfinished mathematics test paper ----- test paper generator (Qt includes source code)
随机推荐
mysql进阶(三十三)MySQL数据表添加字段
关于已拦截跨源请求CORS 头缺少 ‘Access-Control-Allow-Origin‘问题解决
基于ArcGIS水文分析、HEC-RAS模拟技术在洪水危险性及风险评估
学习MySQL 临时表
Using data intelligence, Amazon cloud technology helps companies build endogenous brand growth
E. Cross Swapping(并查集变形/好题)
强意识 压责任 安全培训筑牢生产屏障
Summary of tensorflow installation stepping on the pit
"Thesis Reading" PLATO: Pre-trained Dialogue Generation Model with Discrete Latent Variable
numpy.meshgrid()理解
SWIG教程《四》-go语言的封装
Circle 创始人回应美财政部禁止 Tornado :隐私与安全之间关系紧张
redhat替换yum源时redhat.repo无法删除或无法禁用的问题解决方法
使用决策树对鸢尾花进行分类
[Gazebo Introductory Tutorial] Lecture 3 Static/Dynamic Programming Modeling of SDF Files
PCL 最小二乘拟合空间曲线
重要通知 | “移动云杯”算力网络应用创新大赛初赛延期!!
Error: Rule can only have one resource source (provided resource and test + include + exclude)
C#实现访问OPC UA服务器
池化技术有多牛?来,告诉你阿里的Druid为啥如此牛逼!