APP收款语音播报功能讲解
一、背景
比起主动扫码能确定收款多少与是否到账,扫二维码支付场景不能直接确认,需要核对客户付款截屏,目前微信、支付宝在扫二维码支付后,均支持收款方自动播报收款到账信息,为了秦丝APP有更好体验,也需要加入该功能。
二、方案
目前实现的收款语音播报功能采用片段组合读音的方案,简单的解释就是根据收款的金额,提取相应数值语音播报,分别包括0-9,十-亿及一些单位或者标注发音等19个语音文件。
比起传统语音合成方案,无需幅度增加app的大小,灵活控制语速。
三、实现
1、触发:在收到收款单号推送后,请求收款金额
2、解析:根据收款金额,解析成一个语音文件对象的数组
以999999.99为例,拆解小数点左右两边部分后分开解析,小数点左边部分又以万为单位拆分,先解析万以内数字,然后再讲万以上的部分又当成万以内的解析加万语音片段,亿、兆类似。小数点后面的部分则从不加单位解析。
// 获取数字转语音文件的队列
function getArrayByNumber(num) {
num = num + "";
if (/^(0|[1-9]\d*)(.\d*[1-9])?$/.test(num)) {
var nums = num.split("."), pointAfter = nums[1], flag = 0;
num = Number(nums[0]);
num = dealNum(num);
num.unshift(unitsOther.get);
if(pointAfter) {
nums = pointAfter.split('');
num.push(unitsOther.point);
nums.map(function (val) {
num.push(units[Number(val)]);
});
num.push(unitsOther.yuan);
} else {
num.push(unitsOther.yuan);
num.push(unitsOther.it);
}
return num;
} else {
return [audios.zero];
}
}
// 获取万以上的解析数组
function dealNum(num) {
var currNum, level = 0;
var arr = [],arrTemp, addZero;
if(num === 0){
return [units[0]];
}
while (num > 0) {
currNum = num % WAN;
if (currNum) {
if (addZero) {
arr.unshift(units[0]);
}
if (level === 2) {
arr = [unitsUpWan[2]].concat(arr);
} else if (level) {
arr = [unitsUpWan[1]].concat(arr);
}
arrTemp = dealNumInWan(currNum);
addZero = arrTemp[0];
arr = arrTemp[1].concat(arr);
}
level++;
num = Math.floor(num / WAN);
}
return arr;
}
// 获取万以内的解析数组
function dealNumInWan(num) {
var zero, firstIsZero = num / QIAN < 1 && num > 0;
var arr = [], currNum, unit = 0;
while (num > 0) {
currNum = num % SHI;
if (currNum) {
zero === undefined && (zero = false);
if (unit) {
if (zero) {
arr.unshift(units[0]);
zero = false;
}
arr.unshift(unitsInWan[unit]);
}
arr.unshift(units[currNum]);
} else {
zero === false && (zero = true);
}
unit++;
num = Math.floor(num / SHI);
}
return [firstIsZero, arr];
}
Audio 对象是一个语音文件对象,每个语音对应有个对象,里面有文件的路径与播放时长,时长是自己设置的每个语音对应有个对象,里面有文件的路径与播放时长,时长是自己设置,时间极短的语音如果有了延时就不会连续播放,时间duration这里需要稍微根据实际情况进行调整
// 语音文件路径与语音文件需用时间的钩子
var audios = {
zero: {
src: "media/0.wav",
duration: 800
},
one: {
src: "media/1.wav",
duration: 800
},
two: {
src: "media/2.wav",
duration: 800
},
three: {
src: "media/3.wav",
duration: 800
}
……
nine: {
src: "media/9.wav",
duration: 800
},
point: {
src: "media/point.wav",
duration: 800
},
ten: {
src: "media/ten.wav",
duration: 700
},
hd: {
src: "media/hd.wav",
duration: 700
},
td: {
src: "media/td.wav",
duration: 700
},
ttd: {
src: "media/ttd.wav",
duration: 700
},
hm: {
src: "media/hm.wav",
duration: 700
},
yuan: {
src: "media/yuan.wav",
duration: 700
},
it: {
src: "media/it.wav",
duration: 700
},
get: {
src: "media/get.wav",
duration: 1800
}
};
// 数字转换成语音文件的数组方案
var unitsInWan = ["", audios.ten, audios.hd, audios.td];
var unitsUpWan = ["", audios.ttd, audios.hm, audios.ttd];
var units = [audios.zero, audios.one, audios.two, audios.three, audios.four, audios.five, audios.six, audios.seven, audios.eight, audios.nine];
var unitsOther = {
"point": audios.point,
"yuan": audios.yuan,
"it": audios.it,
"get": audios.get
};
3、播报:递归方式逐个播放片段
function startAAudio(number, index, audiosArr) {
audiosArr || (audiosArr = getArrayByNumber(number));
realMedia = new Media(extUrl + audiosArr[index].src);
setTimeout(function () {
realMedia.stop();
realMedia.release();
index++;
if (audiosArr[index]) {
startAAudio(number, index, audiosArr);
} else {
realMedia = undefined;
if(number = audioList.shift()) { // 如果有队列中有新的语音则播放下一则语音
setTimeout(function () { // 连续收款加点时间间隔
startAAudio(number, 0);
},2000);
}
}
}, audiosArr[index].duration);
realMedia.play();
}
注意
需要用到媒体播放插件cordova-plugin-media

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
VISTA 与输入法程式介面
原文:VISTA 与输入法程式介面 VISTA与输入法程式介面 文/黄忠成 近日,我所兼职顾问的公司开始将旧有的 Win32 程式及新开发的 .NET 应用程式移转到 VISTA 系统上测试,由于我们的应用程式多半是商用套装软体, 相当然尔对于以程式切换输入法的需求是一定存在的,对于客户来说,在焦点移往该输入中文的栏位时,由系统自动为其切换适当的输入法是种便利的设计! 只是这些原本在 Windows XP/2000/2003 上运作的相当正常的程式,到了 VISTA 后,却不约而同出现了同样的问题,那就是自动切换输入法的功能全部失效了, 这不只出现在旧有的 Win32 应用程式,连新开发的 .NET Framework 2.0 应用程式也无法幸免!当工程师们向我询问关于此问题的解决办法时,我直觉的认为, 这可能是 VISTA 在输入法的程式介面上做了变动,也就是旧有的 API 已经失去功能,由另外一种介面来取代了!只是,我毫无头绪,不知该如何去找出这个 新介面是什么,更别谈说提出一个可以解决此问题的办法了。我与多数设计师一样,立刻就打开 google ,企图在搜寻引擎上找到一...
-
下一篇
Python3 与 NetCore 基础语法对比(Function专栏)
Jupyter最新排版:https://www.cnblogs.com/dotnetcrazy/p/9175950.html 昨晚开始写大纲做demo,今天牺牲中午休息时间码文一篇,希望大家点点赞 O(∩_∩)O NetCore:https://github.com/lotapp/BaseCode/tree/master/netcore/1_POP/6func Python:https://github.com/lotapp/BaseCode/tree/master/python/1.POP/4.func_IO 在线演示:http://nbviewer.jupyter.org/github/lotapp/BaseCode/tree/master/python/notebook/1.POP/4.func 在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/master 主要是普及一下Python基础语法,对比着Net,新手更容易上手。对比学习很有意思的,尤其是一些底层和思路 本来感觉函数要说的地方没多少,细细一规划,发现~还是单独拉出一篇说说吧...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- CentOS8编译安装MySQL8.0.19
- MySQL数据库在高并发下的优化方案
- CentOS7,8上快速安装Gitea,搭建Git服务器