react-native-xf-speech
请忽略本文工地散装英语:cry:
我只是一个会点rn
的前端,在安卓开发和ios开发上属于编写边学程度,所以可能会有很多bug,请酌情使用
使用前必读(before use) :warning: :warning: :warning: :warning:
for android
- 云知音官方
SDK
我只发现了32位的,并没有文档里所说的64位的,联系他们也联系不上,有64位的可以联系我。There are only 32-bit SDK - 由于只是用了32位的
SDK
所以你的项目打包不应该包含64位的,所以你需要修改项目根目录/android/app/build.greadle
。You should edit the file:project_root_dir/android/app/build.greadle
like flow to avoid mixed 32bit and 64bit sdks - 由于我不是很懂原生开发,有可能下面的并不是最佳配置,你可以使用自己的配置,并告知我
Because I'm good at native development,you can use your own configuration and tell me
......
......
splits {
abi {
reset()
// set enableSeparateBuildPerCPUArchitecture = true
// 将enableSeparateBuildPerCPUArchitecture设置为true
enable enableSeparateBuildPerCPUArchitecture
universalApk false
// delete others and "armeabi-v7a" only
// 删除其他的 只保留64位的这个
include "armeabi-v7a"
}
}
.....
.....
// 建议直接赋值粘贴这段
applicationVariants.all { variant ->
// 注意这里each改成了all
variant.outputs.all { output ->
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) {
universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
// rename apk,
// 这一段是为了将分离打包的文件重新命名 不然使用
// react-native run-android 会出错 因为它只认识app-debug
if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
File outputDirectory = new File(output.outputFile.parent);
def fileName
if (variant.buildType.name == "release") {
// release name
outputFileName = "app-release.apk"
} else {
// debug name
outputFileName = "app-debug.apk"
}
}
}
}
- 如果你有其他的库只能在64位上运行,你只能转用其他的库,这个库也就免费这一点还不错。
for IOS
- TODO
Getting started
$ npm install react-native-xf-speech --save
or
$ yarn add react-native-xf-speech
Mostly automatic installation
$ react-native link react-native-xf-speech
Manual installation
iOS
- In XCode, in the project navigator, right click
Libraries
➜ Add Files to [your project's name]
- Go to
node_modules
➜ react-native-xf-speech
and add RNXfSpeech.xcodeproj
- In XCode, in the project navigator, select your project. Add
libRNXfSpeech.a
to your project's Build Phases
➜ Link Binary With Libraries
- Run your project (
Cmd+R
)<
Android
- Open up
android/app/src/main/java/[...]/MainActivity.java
- Add
import com.xh.speech.RNXfSpeechPackage;
to the imports at the top of the file - Add
new RNXfSpeechPackage()
to the list returned by the getPackages()
method
- Append the following lines to
android/settings.gradle
:
include ':react-native-xf-speech'
project(':react-native-xf-speech').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-xf-speech/android')
- Insert the following lines inside the dependencies block in
android/app/build.gradle
:
compile project(':react-native-xf-speech')
Usage
:robot: FOR ANDROID :
- 在
你的项目根目录/android/app/src/main/
下面创建目录assets\tts
create a folder assets\tts
in project_root_dir/android/app/src/main/
- 移动仓库中model文件夹两个文件(
backend_lzl
和frontend_model
)至assets\tts
move files in this_repository/model to assets\tss
you made - 添加权限 add permission
在项目根目录/android/app/src/main/AndroidManifest.xml
中添添加
add follow code in project_root_dir/android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
请注意READ_PHONE_STATE
这个权限在高版本安卓中需要动态获取,虽然此项目会替你申请,但是你最好还是自己在合适的地方申请权限
you should ask the permission READ_PHONE_STATE
by your self in the right place although we did this
API:
initEngine
function initEngine(appkey:string, secret: string, options?: Options): Promise<void>
options 可选Optional
streamType: STREAM_TYPE,
volume: number,
pitch: number,
speed: number,
STREAM_TYPE
enum STREAM_TYPE {
SYSTEM,
RING,
MUSIC,
ALARM,
NOTIFICATION
}
import tts from 'react-native-xf-speech';
const options = {
streamType: tts.STREAM_TYPE.MUSIC,
volume: 100,
pitch: 50,
speed: 52
}
await tts.initEngine("app_key","app_secret", options)
这一步非常重要,所有的操作都应该在初始化之后,除了初始化监听函数
app_key
和app_secret
随便填好像都可以用,如果提示错误,请移步云知音官网自己申请。
Operation must be performed after initialization, except listener function
you can use any strings apply to app_key
and app_secret
,if there are any problems you need to get key and secret by yourself 云知音hompage
申请注意
- 申请通用解决方案,同时勾选离线语音合成
- 下载完成后将
USCDemo\libs\armeabi
中的文件替换掉本仓库android/libs
中的文件 - 将下载完成的sdk
USCDemo\assets\OfflineTTSModels
中的文件复制替换掉上面前面创建的assets\tts
文件夹中的文件
:warning:其他注意
- 初始化需要加载模型,需要将
assets\tts
的文件复制到存储中,所以需要几秒的时间,期间会导致app
卡顿(因为没有用单独的线程加载),所以建议使用监听函数做相应的提示
because there are no separate threads, when excuse the initEngine
function may cause application to jam. you should use initial listener - 再次提醒,一定要在初始化之后进行其他操作,不然会报错
setInitEngineListener
function setInitEngineListener(callback: (event: InitEvent) => any): void
InitEvent 事件参数
{
progress: number,
fileCount: number,
initState: INIT_ENGINE_STATE
}
INIT_ENGINE_STATE 初始化状态
enum INIT_ENGINE_STATE {
START,
PROGRESS,
FINISH,
SDK_NOT_FOUND_ERROR,
SDK_COPY_ERROR
}
初始化带监听
async function init() {
tts.setInitEngineListener(({progress, fileCount, initState}) => {
console.log(`正在复制第${fileCount}个文件`, `当前进度${progress}`)
if(initState == tts.INIT_ENGINE_STATE.FINISH) {
}else {
}
})
await tts.initEngine("123","123")
}
playText 朗读文字
function playText(text: string): void
text 需要朗读的文本
tts.playText(`啊啊啊啊嗯嗯嗯啊啊啊啊啊嗯啊啊啊啊`)
stopPlay 停止朗读
function stopPlay(): void
pause 暂停
function pause(): void
resume 恢复朗读
function resume(): void
release 释放资源
function release(): void
释放后需要重新初始化
utils 辅助函数
utils.getVolume
获取当前音量 和你初始化的输出流类型有关
function getVolume(): Promise<number>
utils.getMaxVolume
获取当前输出流最大音量
function getMaxVolume(): Promise<number>
utils.setVolume
设置音量
function setVolume(value: number, flag: VOLUME_FLAGS): void
value 设定值
flag 设定音量的一些反馈
enum VOLUME_FLAGS {
ALLOW_RINGER_MODES,
PLAY_SOUND,
REMOVE_SOUND_AND_VIBRATE,
SHOW_UI,
VIBRATE
}
async function setAndShowUI() => {
const volume = await tts.utils.getVolume()
tts.utils.setVolume(volume, tts.VOLUME_FLAGS.SHOW_UI)
}
setPlayStartListener 播放开始事件
function setPlayStartListener(callback: () => any): void
setPlayEndListener 播放结束事件
function setPlayEndListener(callback: () => any): void
setPauseListener 播放暂停事件
function setPauseListener(callback: () => any): void
setStopListener 播放停止事件
function setStopListener(callback: () => any): void
setResumeListener 恢复播放事件
function setResumeListener(callback: () => any): void
setReleaseListener 释放资源事件
function setReleaseListener(callback: () => any): void
setErrorListener 合成错误事件
function setErrorListener(callback: (event: ErrorEvent) => any): void
ErrorEvent
{
msg: string
}
:apple: FOR IOS:
TODO....