first commit
This commit is contained in:
commit
aea14e50f0
|
@ -0,0 +1,83 @@
|
|||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Cordova template
|
||||
# gitignore template for the Cordova framework
|
||||
# website: https://cordova.apache.org/
|
||||
#
|
||||
# Recommended template: Node.gitignore
|
||||
|
||||
# App platform binaries and built files
|
||||
/platforms
|
||||
|
||||
# Optional to ignore plugin Git clones
|
||||
#/plugins
|
||||
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/chineseTTS.iml" filepath="$PROJECT_DIR$/.idea/chineseTTS.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "chinesetts",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "KeiferJu <jkf19980216@163.com> (myllcn.com)",
|
||||
"license": "MIT"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<plugin id="cordova-plugin-chinese-tts" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<name>chineseTTS</name>
|
||||
<js-module name="ChineseTTS" src="www/chineseTTS.js">
|
||||
<clobbers target="cordova.plugins.chineseTTS"/>
|
||||
</js-module>
|
||||
<platform name="android">
|
||||
<config-file parent="/*" target="res/xml/config.xml">
|
||||
<feature name="ChineseTTS">
|
||||
<param name="android-package" value="com.smartmapx.tts.ChineseTTS"/>
|
||||
</feature>
|
||||
</config-file>
|
||||
<config-file parent="/*" target="AndroidManifest.xml"></config-file>
|
||||
<source-file src="src/android/ChineseTTS.java" target-dir="src/com/smartmapx/tts"/>
|
||||
<source-file src="src/android/FileUtils.java" target-dir="src/com/smartmapx/tts"/>
|
||||
<source-file src="src/android/OfflineResource.java" target-dir="src/com/smartmapx/tts"/>
|
||||
<source-file src="src/android/SpeechUtilOffline.java" target-dir="src/com/smartmapx/tts"/>
|
||||
<source-file src="src/android/libs/usc.jar" target-dir="libs"/>
|
||||
<source-file src="src/android/libs/armeabi/libyzstts.so" target-dir="src/main/jniLibs/armeabi"/>
|
||||
<source-file src="src/android/libs/armeabi/libuscasr.so" target-dir="src/main/jniLibs/armeabi"/>
|
||||
<source-file src="src/android/assets/backend_lzl" target-dir="src/main/assets"/>
|
||||
<source-file src="src/android/assets/frontend_model" target-dir="src/main/assets"/>
|
||||
<config-file target="AndroidManifest.xml" parent="/manifest">
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
</config-file>
|
||||
<framework src="com.hjq:xxpermissions:6.0"/>
|
||||
</platform>
|
||||
</plugin>
|
|
@ -0,0 +1,111 @@
|
|||
package com.smartmapx.tts;
|
||||
|
||||
import org.apache.cordova.CordovaPlugin;
|
||||
import org.apache.cordova.CallbackContext;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.Manifest;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.hjq.permissions.OnPermission;
|
||||
import com.hjq.permissions.Permission;
|
||||
import com.hjq.permissions.XXPermissions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class echoes a string called from JavaScript.
|
||||
*/
|
||||
|
||||
public class ChineseTTS extends CordovaPlugin {
|
||||
|
||||
private Context context;
|
||||
|
||||
@Override
|
||||
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||
|
||||
if (action.equals("init")) {
|
||||
this.init();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (action.equals("speak")) {
|
||||
String message = args.getString(0);
|
||||
this.speak(message, callbackContext);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化引擎
|
||||
*
|
||||
* @param
|
||||
*/
|
||||
private void init() {
|
||||
context = this.cordova.getActivity();
|
||||
permissionRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 讲话
|
||||
*
|
||||
* @param message
|
||||
* @param callbackContext
|
||||
*/
|
||||
private void speak(String message, CallbackContext callbackContext) {
|
||||
if (message != null && message.length() > 0) {
|
||||
SpeechUtilOffline.getInstance(context).play(message, SpeechUtilOffline.PLAY_MODE.QUEUED);
|
||||
} else {
|
||||
callbackContext.error("信息为空.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 运行时权限--
|
||||
*/
|
||||
public void permissionRequest() {
|
||||
// Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
// Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
// Manifest.permission.READ_PHONE_STATE,
|
||||
// Manifest.permission.RECEIVE_BOOT_COMPLETED
|
||||
|
||||
if (XXPermissions.isHasPermission(context, Permission.WRITE_EXTERNAL_STORAGE) && XXPermissions.isHasPermission(context, Permission.ACCESS_FINE_LOCATION) && XXPermissions.isHasPermission(context, Permission.READ_PHONE_STATE)) {
|
||||
|
||||
} else {
|
||||
XXPermissions.with(this.cordova.getActivity())
|
||||
// 可设置被拒绝后继续申请,直到用户授权或者永久拒绝
|
||||
.constantRequest()
|
||||
// 支持请求6.0悬浮窗权限8.0请求安装权限
|
||||
.permission(Permission.WRITE_EXTERNAL_STORAGE, Permission.ACCESS_FINE_LOCATION, Permission.READ_PHONE_STATE)
|
||||
// 不指定权限则自动获取清单中的危险权限
|
||||
// .permission(Permission.Group.STORAGE, Permission.Group.CALENDAR)
|
||||
.request(new OnPermission() {
|
||||
|
||||
@Override
|
||||
public void hasPermission(List<String> granted, boolean isAll) {
|
||||
if (isAll) {
|
||||
Toast.makeText(context, "权限获取成功,正在初始化语音包", Toast.LENGTH_SHORT).show();
|
||||
SpeechUtilOffline.getInstance(context).play("语音包初始化完成", SpeechUtilOffline.PLAY_MODE.QUEUED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noPermission(List<String> denied, boolean quick) {
|
||||
Toast.makeText(context, "权限获取失败,语音包初始化失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package com.smartmapx.tts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 文件操作类
|
||||
*
|
||||
* @author KeiferJu
|
||||
* @date 2019/8/
|
||||
*/
|
||||
public final class FileUtils {
|
||||
private static final String LOGTAG ="/ing/tts";
|
||||
private static FileUtils fileUtils = new FileUtils();
|
||||
|
||||
private FileUtils() {
|
||||
}
|
||||
|
||||
public static FileUtils getInstance() {
|
||||
return fileUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SDCARD根路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static StringBuffer getRootDir() throws Exception {
|
||||
return new StringBuffer().append(Environment
|
||||
.getExternalStorageDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存在SDCARD上文件的绝对路径
|
||||
*
|
||||
* @param mContext
|
||||
* @param folderName
|
||||
*/
|
||||
public static StringBuffer getExternalFileAbsoluteDir(Context mContext,
|
||||
String folderName, String fileName) throws Exception {
|
||||
StringBuffer stringBuffer = getRootDir().append(File.separator);
|
||||
stringBuffer.append(getExternalFilesDir(mContext, folderName));
|
||||
if (fileName != null) {
|
||||
if (0 == fileName.indexOf(File.separator)) {
|
||||
stringBuffer.append(fileName);
|
||||
} else {
|
||||
stringBuffer.append(File.separator);
|
||||
stringBuffer.append(fileName);
|
||||
}
|
||||
}
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取SDCARD上应用存储路径
|
||||
*
|
||||
* @param mContext
|
||||
* @param folderName
|
||||
* @return
|
||||
*/
|
||||
private static StringBuffer getExternalFilesDir(Context mContext,
|
||||
String folderName) throws Exception {
|
||||
String packageName = mContext.getPackageName();
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
stringBuffer.append("Android").append(File.separator).append("data")
|
||||
.append(File.separator).append(packageName);
|
||||
if (folderName != null) {
|
||||
if (0 == folderName.indexOf(File.separator)) {
|
||||
stringBuffer.append(folderName);
|
||||
} else {
|
||||
stringBuffer.append(File.separator);
|
||||
stringBuffer.append(folderName);
|
||||
}
|
||||
}
|
||||
Log.d(LOGTAG, "FileUtils getExternalFilesDir "
|
||||
+ stringBuffer.toString());
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建一个临时目录,用于复制临时文件,如assets目录下的离线资源文件
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
|
||||
public static String createTmpDir(Context context) {
|
||||
String sampleDir = "/ing/tts";
|
||||
String tmpDir = Environment.getExternalStorageDirectory().toString() + sampleDir;
|
||||
if (!FileUtils.makeDir(tmpDir)) {
|
||||
tmpDir = context.getExternalFilesDir(sampleDir).getAbsolutePath();
|
||||
if (!FileUtils.makeDir(sampleDir)) {
|
||||
throw new RuntimeException("create model resources dir failed :" + tmpDir);
|
||||
}
|
||||
}
|
||||
return tmpDir;
|
||||
}
|
||||
|
||||
public static boolean makeDir(String dirPath) {
|
||||
File file = new File(dirPath);
|
||||
if (!file.exists()) {
|
||||
return file.mkdirs();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* assets文件2 sdcard
|
||||
* @param assets
|
||||
* @param source
|
||||
* @param dest
|
||||
* @param isCover
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void copyFromAssets(AssetManager assets, String source, String dest, boolean isCover) throws IOException {
|
||||
File file = new File(dest);
|
||||
if (isCover || (!isCover && !file.exists())) {
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
is = assets.open(source);
|
||||
String path = dest;
|
||||
fos = new FileOutputStream(path);
|
||||
byte[] buffer = new byte[1024];
|
||||
int size = 0;
|
||||
while ((size = is.read(buffer, 0, 1024)) >= 0) {
|
||||
fos.write(buffer, 0, size);
|
||||
}
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.smartmapx.tts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
import java.io.IOException;
|
||||
|
||||
import static android.content.ContentValues.TAG;
|
||||
|
||||
/**
|
||||
* 离线文件
|
||||
*
|
||||
* @author ing
|
||||
* @date 2018/3/27
|
||||
*/
|
||||
public class OfflineResource {
|
||||
|
||||
|
||||
private AssetManager assets;
|
||||
private String destPath;
|
||||
|
||||
private String backFilename;
|
||||
private String modelFilename;
|
||||
|
||||
public OfflineResource(Context context) throws IOException {
|
||||
this.assets = context.getAssets();
|
||||
this.destPath = FileUtils.createTmpDir(context);
|
||||
setOfflineVoiceType();
|
||||
}
|
||||
|
||||
public String getModelFilename() {
|
||||
return modelFilename;
|
||||
}
|
||||
|
||||
public String getBackFilename() {
|
||||
return backFilename;
|
||||
}
|
||||
|
||||
public void setOfflineVoiceType() throws IOException {
|
||||
String back = "backend_lzl";
|
||||
String model = "frontend_model";
|
||||
backFilename = copyAssetsFile(back);
|
||||
modelFilename = copyAssetsFile(model);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String copyAssetsFile(String sourceFilename) throws IOException {
|
||||
String destFilename = destPath + "/" + sourceFilename;
|
||||
FileUtils.copyFromAssets(assets, sourceFilename, destFilename, false);
|
||||
Log.i(TAG, "Assets to sdcard successed:" + destFilename);
|
||||
return destFilename;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package com.smartmapx.tts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.unisound.client.SpeechConstants;
|
||||
import com.unisound.client.SpeechSynthesizer;
|
||||
import com.unisound.client.SpeechSynthesizerListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 离线语音
|
||||
*
|
||||
* @author KeiferJu
|
||||
* @date 2019/8/15
|
||||
*/
|
||||
public class SpeechUtilOffline {
|
||||
public static final String appKey = "_appKey_";
|
||||
public static final String secret = "_secret_";
|
||||
private static SpeechUtilOffline instance;
|
||||
private SpeechSynthesizer mTTSPlayer;
|
||||
private boolean isSpeaking = false;
|
||||
private List<SpeechItem> speechList = new ArrayList<>();
|
||||
private boolean released = false;
|
||||
protected OfflineResource offlineResource;
|
||||
|
||||
private SpeechUtilOffline(Context context) {
|
||||
init(context);
|
||||
released = false;
|
||||
}
|
||||
|
||||
public static SpeechUtilOffline getInstance(Context context) {
|
||||
if (instance == null) {
|
||||
instance = new SpeechUtilOffline(context);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 初始化引擎
|
||||
*
|
||||
*/
|
||||
private void init(final Context context) {
|
||||
try {
|
||||
offlineResource = new OfflineResource(context);
|
||||
} catch (IOException e) {
|
||||
Log.e("ing","offlineResouce failed , error msg : "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 初始化语音合成对象
|
||||
mTTSPlayer = new SpeechSynthesizer(context, appKey, secret);
|
||||
// 设置本地合成
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_SERVICE_MODE, SpeechConstants.TTS_SERVICE_MODE_LOCAL);
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_VOICE_PITCH, 50);//音调
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_VOICE_SPEED, 52);//语速
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_VOICE_VOLUME, 100);//音量
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_STREAM_TYPE, AudioManager.STREAM_NOTIFICATION);
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_FRONTEND_MODEL_PATH, offlineResource.getModelFilename());
|
||||
// 设置后端模型
|
||||
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_BACKEND_MODEL_PATH, offlineResource.getBackFilename());
|
||||
// 设置回调监听
|
||||
mTTSPlayer.setTTSListener(new SpeechSynthesizerListener() {
|
||||
|
||||
@Override
|
||||
public void onEvent(int type) {
|
||||
switch (type) {
|
||||
case SpeechConstants.TTS_EVENT_INIT:
|
||||
// 初始化成功回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_SYNTHESIZER_START:
|
||||
// 开始合成回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_SYNTHESIZER_END:
|
||||
// 合成结束回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_BUFFER_BEGIN:
|
||||
// 开始缓存回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_BUFFER_READY:
|
||||
// 缓存完毕回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_PLAYING_START:
|
||||
// 开始播放回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_PLAYING_END:
|
||||
// 播放完成回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_PAUSE:
|
||||
// 暂停回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_RESUME:
|
||||
// 恢复回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_STOP:
|
||||
// 停止回调
|
||||
break;
|
||||
case SpeechConstants.TTS_EVENT_RELEASE:
|
||||
// 释放资源回调
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int type, String errorMSG) {
|
||||
// 语音合成错误回调
|
||||
Log.e("ing","TTS onError __ type : "+ type +" errorMsg : " +errorMSG );
|
||||
}
|
||||
});
|
||||
// 初始化合成引擎
|
||||
mTTSPlayer.init("");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止播放
|
||||
*
|
||||
*/
|
||||
public void stop() {
|
||||
mTTSPlayer.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放
|
||||
*
|
||||
*/
|
||||
public void play(String content) {
|
||||
playImmediately(content);
|
||||
}
|
||||
|
||||
public void play(String content, PLAY_MODE playMode) {
|
||||
switch (playMode) {
|
||||
case QUEUED: {
|
||||
playQueued(content);
|
||||
break;
|
||||
}
|
||||
case IMMEDIATELY: {
|
||||
playImmediately(content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpeech() {
|
||||
if (!isSpeaking) {
|
||||
if (speechList.size() > 0) {
|
||||
speak(speechList.remove(speechList.size() - 1).content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void speak(String content) {
|
||||
mTTSPlayer.playText(content);
|
||||
}
|
||||
|
||||
public void playQueued(String content) {
|
||||
speechList.add(new SpeechItem(content, PLAY_MODE.QUEUED));
|
||||
updateSpeech();
|
||||
}
|
||||
|
||||
public void playImmediately(String content) {
|
||||
speak(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放资源
|
||||
*
|
||||
*/
|
||||
public void release() {
|
||||
// 主动释放离线引擎
|
||||
if (released) {
|
||||
return;
|
||||
}
|
||||
if (mTTSPlayer != null) {
|
||||
mTTSPlayer.stop();
|
||||
mTTSPlayer.release(SpeechConstants.TTS_RELEASE_ENGINE, null);
|
||||
}
|
||||
instance = null;
|
||||
released = true;
|
||||
}
|
||||
|
||||
|
||||
public enum PLAY_MODE {
|
||||
QUEUED,
|
||||
IMMEDIATELY
|
||||
}
|
||||
|
||||
private class SpeechItem {
|
||||
public String content;
|
||||
public PLAY_MODE playMode;
|
||||
|
||||
public SpeechItem(String content, PLAY_MODE mode) {
|
||||
this.content = content;
|
||||
this.playMode = mode;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,9 @@
|
|||
var exec = require('cordova/exec');
|
||||
|
||||
exports.init = function (arg0, success, error) {
|
||||
exec(success, error, 'ChineseTTS', 'init', [arg0]);
|
||||
}
|
||||
|
||||
exports.speak = function (arg0, success, error) {
|
||||
exec(success, error, 'ChineseTTS', 'speak', [arg0]);
|
||||
}
|
Loading…
Reference in New Issue