1. 实现方式说明
本文采用两种方式集成,一是Activity集成,播放的时候需要跳转到新的Activity;二是直接在模块里面集成语音合成需要的相关代码,可以理解为用js代码请求,用adroid代码播放。
第二种是第一种方式的升级,也是在开发中发现可以不用Activity也可以实现。开发中学习了一些安卓的知识,也比较有意思,故把两种实现方式都放出来。
2. 需求场景
需求是将一个长文本切分成多份,实时的播报出来,腾讯云的流式语音合成可以很好的实现需求。如果直接生成长文本的语音,需要等待腾讯的回调,客户端无法即时的知道是否已经生成完毕;而使用流式语音合成,传入文本参数后,就可以实时播报。
腾讯云对于长文本语音合成的说明:
支持长文本语音合成、实时语音合成、基础语音合成三种合成方式。长文本语音合成与基础语音合成为非流式,整个文本合成语音后再下发,长文本语音合成可以一次性合成较长文本,适合阅读播报、新闻媒体等场景。流式语音合成(实时语音合成)为一边合成声音,一边下发声音,适合语音机器人等实时性要求较高的场景。
3. 安卓集成
3.1. 说明
腾讯云提供了一个官方的demo,官方demo可以直接运行,为了能够快速的集成tts实现需求, 决定将tt功能放到activity里,需要使用的时候,调起activity。官方demo里面的activity是LongTextTtsActivity
,我们直接使用即可,下面的章节,我会逐渐对LongTextTtsActivity进行补充说明。
3.2. 添加安卓原生模块
想要调起一个新的acvitity,需要从安卓代码使用startActivity调起,添加一个原生模块,就可以使用js代码调起了。如果添加原生模块,可以参考react native的官方文档,这里直接贴上代码。
playLongText
方法支持传入title 、content,在通过intent传到LongTextTtsActivity里
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
/**
* @author cauyyl
* @date 2022-08-30
*/
public class TTSModule extends ReactContextBaseJavaModule {
private static final String TAG = "tts";
private static ReactApplicationContext context;
public static Callback ttsCallBack;
public TTSModule(ReactApplicationContext reactContext) {
super(reactContext);
context = reactContext;
}
@Override
public String getName() {
return "TTS";
}
@ReactMethod
public void playLongText(String title, String content, Callback callback) {
ttsCallBack=callback;
// ReactApplicationContext context = getReactApplicationContext();
Intent intent = new Intent(context, LongTextTtsActivity.class);
intent.putExtra("title", title);
intent.putExtra("content", content);
context.startActivityForResult(intent, 123, new Bundle());
}
}
3.3. Activity的实现
在腾讯云提供的demo中,已经实现了一个具有UI的Activity,直接把demo里面的相关文件都粘贴到项目中,
LongTextTtsActivity.java
MyCrashHandler.java
SpinnerItem.java
LongTextTtsActivity
已经支持输入文本,然后播放文本的内容,本次需求是从原生模块传递内容进行播报,因此需要接收一下content,在开始播放的事件中,将文本内容改成从Intent传递过来的内容,附上代码示例。
Intent intent = getIntent(); //定义接收数据的Intent
String titleText;
titleText = intent.getStringExtra("title");
String ttsText;
ttsText = intent.getStringExtra("content");
/**直接鉴权**/
mTtsController.init(this,11111111L
, "secretKey"
, "token");
/**使用临时密钥鉴权
* * 1.通过sts 获取到临时证书 (secretId secretKey token) ,此步骤应在您的服务器端实现,见https://cloud.tencent.com/document/product/598/33416
* 2.通过临时密钥调用接口
* **/
// mTtsController.init(this, Long.valueOf(DemoConfig.apppId)
// , "临时secretId"
// , "临时secretKey"
// ,"对应的token");
requestAudioFocus(mTtsController);
if (mTtsController == null){
return;
}
//设置语速
mTtsController.setVoiceSpeed(tts_speed);
//设置音色
mTtsController.setVoiceType(tts_voice);
//设置语言
mTtsController.setVoiceLanguage(tts_language);
//设置ProjectId 不设置默认使用0,说明:项目功能用于按项目管理云资源,可以对云资源进行分项目管理,详情见 https://console.cloud.tencent.com/project
mTtsController.setProjectId(0);
start(ttsText);//如果入参文本比较长,建议放在子线程