Android语音播报商家收款及相关TTS语音文件合成
程序员文章站
2022-04-30 09:25:04
...
主要思路: 1.处理需要播报的金额 2.合成语音文件,对金额播报
其实很简单,两行代码直接搞定
List<String> list = new VoiceTemplate()
.prefix("success")
.numString(money)
.suffix("yuan")
.gen();
VoiceSpeaker.getInstance().speak(list);
步骤1.对播报的金额通过小数点判断,拆解为整数和小数部分
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
public class VoiceTemplate {
private static final String DOT = ".";
private String numString;
private String prefix;
private String suffix;
private static final char[] NUM = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
private static final char[] CHINESE_UNIT = {'元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟'};
public VoiceTemplate() {
}
public VoiceTemplate prefix(String prefix) {
this.prefix = prefix;
return this;
}
public VoiceTemplate suffix(String suffix) {
this.suffix = suffix;
return this;
}
/**
* 处理执行的金额,目前只支持亿级别,想支持更大数据,自己改
*
* @param numString
* @return
*/
public VoiceTemplate numString(String numString) {
this.numString = numString;
return this;
}
public List<String> gen() {
return genVoiceList();
}
private List<String> genVoiceList() {
List<String> result = new ArrayList<>();
if (!TextUtils.isEmpty(prefix)) {
result.add(prefix);
}
if (!TextUtils.isEmpty(numString)) {
result.addAll(genReadableMoney(numString));
}
if (!TextUtils.isEmpty(suffix)) {
result.add(suffix);
}
return result;
}
/**
* 处理小数点之前和之后的数据
*
* @param numString
* @return
*/
private List<String> genReadableMoney(String numString) {
List<String> result = new ArrayList<>();
if (!TextUtils.isEmpty(numString)) {
if (numString.contains(DOT)) {
String integerPart = numString.split("\\.")[0];
String decimalPart = numString.split("\\.")[1];
List<String> intList = readIntPart(integerPart);
List<String> decimalList = readDecimalPart(decimalPart);
result.addAll(intList);
if (!decimalList.isEmpty()) {
result.add("dot");
result.addAll(decimalList);
}
} else {
result.addAll(readIntPart(numString));
}
}
return result;
}
private List<String> readDecimalPart(String decimalPart) {
List<String> result = new ArrayList<>();
if (!"00".equals(decimalPart)) {
char[] chars = decimalPart.toCharArray();
for (char ch : chars) {
result.add(String.valueOf(ch));
}
}
return result;
}
private List<String> readIntPart(String integerPart) {
List<String> result = new ArrayList<>();
String intString = readInt(Integer.parseInt(integerPart));
int len = intString.length();
for (int i = 0; i < len; i++) {
char current = intString.charAt(i);
if (current == '拾') {
result.add("ten");
} else if (current == '佰') {
result.add("hundred");
} else if (current == '仟') {
result.add("thousand");
} else if (current == '万') {
result.add("ten_thousand");
} else if (current == '亿') {
result.add("billion");
} else {
result.add(String.valueOf(current));
}
}
return result;
}
/**
* 返回关于钱的中文式大写数字,支仅持到亿
*/
public static String readInt(int moneyNum) {
String res = "";
int i = 0;
if (moneyNum == 0) {
return "0";
}
if (moneyNum == 10) {
return "拾";
}
if (moneyNum > 10 && moneyNum < 20) {
return "拾" + moneyNum % 10;
}
while (moneyNum > 0) {
res = CHINESE_UNIT[i++] + res;
res = NUM[moneyNum % 10] + res;
moneyNum /= 10;
}
return res.replaceAll("0[拾佰仟]", "0")
.replaceAll("0+亿", "亿").replaceAll("0+万", "万")
.replaceAll("0+元", "元").replaceAll("0+", "0")
.replace("元", "");
}
}
步骤2.播报金额及相关TTS文件合成
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class VoiceSpeaker {
private static VoiceSpeaker sInstance;
private ExecutorService service;
private VoiceSpeaker() {
service = Executors.newCachedThreadPool();
}
public static synchronized VoiceSpeaker getInstance() {
if (sInstance == null) {
sInstance = new VoiceSpeaker();
}
return sInstance;
}
public void speak(final List<String> list) {
if (service != null) {
service.execute(new Runnable() {
@Override
public void run() {
start(list);
}
});
}
}
/**
* android自带MediaPlayer进行语音播报,简单方便
* @param list
*/
private void start(final List<String> list) {
synchronized (this) {//防止混合播报
final CountDownLatch latch = new CountDownLatch(1);
MediaPlayer player = new MediaPlayer();
if (list != null && list.size() > 0) {
final int[] counter = {0};
String path = String.format("sound/tts_%s.mp3", list.get(counter[0]));
AssetFileDescriptor fd = null;
try {
//加载合成好的本地TTS语音文件
fd = getAssetFileDescription(path);
player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.reset();
counter[0]++;
if (counter[0] < list.size()) {
try {
AssetFileDescriptor fileDescriptor =getAssetFileDescription(String.format("sound/tts_%s.mp3", list.get(counter[0])));
mp.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
latch.countDown();
}
} else {
mp.release();
latch.countDown();
}
}
});
} catch (IOException e) {
e.printStackTrace();
latch.countDown();
} finally {
if (fd != null) {
try {
fd.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
try {
latch.await();
this.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 资源管理器加载对应语音文件
* @param filename
* @return
* @throws IOException
*/
public static AssetFileDescriptor getAssetFileDescription(String filename) throws IOException {
AssetManager manager = BaseApp.getContext().getAssets();
return manager.openFd(filename);
}
}
getContext全局均可使用
public class BaseApp extends MultiDexApplication {
private static Application instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static Application getContext() {
return instance;
}
}
步骤3.来 来 来,注意了,敲黑板了,上面是代码部分,下面进行语音合成,不过也是很easy的啦
百度合成TT文件:http://ai.baidu.com/tech/speech/tts 语速 音色等相关因素自己根据喜好和需求来自定义,你看多简单,将合成好的tts文件放在项目中,如下所示
如何合成所需要的语音文件
上一篇: 自己动手装一台Windows+CentOS双系统的主机
下一篇: Android中文TTS语音合成