本文介绍如何接入 ZegoRealtimeTranslation SDK(提供语音翻译SDK),实现“边说话边输出文字”等无障碍沟通效果。ZegoRealtimeTranslation——官方名称:ZEGO 实时传译,是 ZEGO 携手智能语音行业生态服务商提供的实时语音转写及翻译服务,提供实时语音转写及翻译服务,覆盖主流语种。
集成 SDK
准备环境
以Android为例。在开始集成 ZegoRealtimeTranslation SDK 前,请确保开发环境满足以下要求:
- Android Studio 2021.2.1 或以上版本。
- Android SDK 29、Android SDK Build-Tools 29.0.2、Android SDK Platform-Tools 29.x.x 或以上版本。
- Android 8.0 或以上版本且支持音视频的 Android 设备。
- Android 设备已经连接到 Internet。
集成 SDK 步骤
1 新建项目(可选)
1. 打开 Android Studio,选择菜单 “File > New > New Project”。
2. 选一个 EmptyActivity 项目。
3. 填写项目的存储路径和项目名称,“minimum SDK” 选择 “API 26”。
4. 单击 “finish”,完成。
2 导入 SDK
1. 请 下载 最新版本的 SDK,下载完成后进行解压。
2. 打开已解压文件夹,将 zegoarealtimetranslation.aar
文件,拷贝到项目的 “libs” 目录下。
3. 添加 SDK 引用,进入到 “app” 目录,打开 “build.gradle” 文件,添加以下依赖项。
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
...
// 使用google库需加上配置
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/INDEX.LIST'
exclude 'META-INF/DEPENDENCIES'
}
...
}
...
dependencies {
...
implementation fileTree(dir:'libs', include: ['*.jar', '*.aar'])
...
// google library
implementation platform('com.google.cloud:libraries-bom:26.1.1')
implementation 'com.google.cloud:google-cloud-speech:2.5.4'
implementation 'com.google.cloud:google-cloud-translate:2.3.4'
implementation 'com.google.auth:google-auth-library-oauth2-http:1.0.0'
implementation "io.grpc:grpc-okhttp:1.33.0"
...
implementation "com.squareup.okhttp3:okhttp:4.10.0"
implementation "com.google.code.gson:gson:2.8.8"
...
}
3 设置权限
根据实际应用需要,设置应用所需权限。
进入 “app/src/main” 目录,打开 “AndroidManifest.xml” 文件,添加权限。
<!-- SDK 必须使用的权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- App 需要使用的部分权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
防止混淆代码
ZegoRealtimeTranslation SDK 内部已经做了混淆处理,外部应用无需再针对集成 ZegoRealtimeTranslation SDK 增加混淆规则。
实现语音识别
集成SDK后,可实现实时语音识别和文本翻译识别的功能,包括与 Express 的接口对接,主播与观众之间的通信方式。
在实现实时语音识别功能之前,请确保:
- 已在 ZEGO 控制台 创建项目,并申请有效的 AppID 和 AppSign,详情请参考 控制台 – 项目管理 – 项目信息。
- 已在项目中集成 ZEGO Express SDK,实现基本的实时音视频功能,详情请参考 实时音视频 – 快速开始 – 集成 SDK。
- 已开通相关权限,并获取到实时传译的 License。
流程图
实现流程
请您根据自己的业务需要,选择实现相关的内容识别传译功能。
1 初始化 Express SDK
- 创建界面。根据场景需要,为您的项目展示实时传译的用户界面,推荐您在项目中添加如下元素:
- 主播的视频窗口
- 语音识别结果的窗口
- 识别结果翻译后的窗口
- 设置项(服务商,语言等)
- 创建引擎。调用 ZEGO Express SDK 的 createEngine 接口,将申请到的 AppID 和 AppSign 分别传入参数“appID”和“appSign”,创建引擎单例对象。 注册回调,可将实现了 IZegoEventHandler 的对象传入参数 “eventHandler”。
ZegoEngineProfile zegoEngineProfile = new ZegoEngineProfile();
// 请通过 ZEGO 控制台获取,格式为:1234567890
zegoEngineProfile.appID = Config.appID;
// 请通过 ZEGO 控制台获取,格式为:"0123456789012345678901234567890123456789012345678901234567890123"(共64个字符)
zegoEngineProfile.appSign = Config.appSign;
zegoEngineProfile.application = application;
// 实时通讯场景接入
zegoEngineProfile.scenario = ZegoScenario.COMMUNICATION;
// 创建引擎
ZegoExpressEngine.createEngine(zegoEngineProfile, zegoEventHandler);
...
private IZegoEventHandler zegoEventHandler = new IZegoEventHandler() {
// 重载的方法见后面的步骤需要,在后面步骤有详细实现
...
};
2 登录房间
调用 ZEGO Express SDK 的 loginRoom
接口登录房间。roomID 和 user 的参数由开发者的本地业务生成,但是需要满足以下条件:同一个 AppID 内,需保证 “roomID” 全局唯一。
// 创建用户对象,ZegoUser 的构造方法 userWithUserID 会将 “userName” 设为与传的参数 “userID” 一样。“userID” 与 “userName” 不能为 “null”,否则会导致登录房间失败。
String roomID = "your_room_id";
ZegoUser user = new ZegoUser("your_user_id");
// 登录房间
ZegoExpressEngine.getEngine().loginRoom(roomID, user);
3 初始化 ZegoRealtimeTranslation SDK
在使用 ZegoRealtimeTranslation SDK 功能前,必须先进行初始化。
ZegoRealtimeTranslation zegoRealtimeTranslation = ZegoRealtimeTranslation.getInstance();
zegoRealtimeTranslation.init(license); // 传入申请到的license
4 开始推流
登录房间后如果是主播需要开始推流,设置声音采集的参数。同时设置声音采集的回调接口,把声音数据传给 ZegoRealtimeTranslation SDK。
engine.startPublishingStream(streamID); // streamID是流ID
// 设置采集声音的参数,必须sampleRate是16k,单声道格式。
ZegoAudioFrameParam audioFrameParam = new ZegoAudioFrameParam();
audioFrameParam.sampleRate = ZegoAudioSampleRate.ZEGO_AUDIO_SAMPLE_RATE_16K;
audioFrameParam.channel = ZegoAudioChannel.MONO;
engine.startAudioDataObserver(ZegoAudioDataCallbackBitMask.CAPTURED.value(), audioFrameParam);
// 设置接收麦克风收集到的声音数据回调,并传给ZegoRealtimeTranslation SDK.
engine.setAudioDataHandler(new IZegoAudioDataHandler() {
@Override
public void onCapturedAudioData(ByteBuffer byteBuffer, int dataLength, ZegoAudioFrameParam zegoAudioFrameParam) {
zegoRealtimeTranslation.sendSpeechPCM(byteBufferToByteArray(byteBuffer), dataLength);
}
};
// ByteBuffer转Byte数组的方法
public static byte[] byteBufferToByteArray(ByteBuffer bytes) {
int len = bytes.limit() - bytes.position();
byte[] bytes1 = new byte[len];
bytes.get(bytes1);
return bytes1;
}
5 拉流
主播和观众都需要拉流,当有流新增时,进行拉流操作。
// zegoEventHandler对应创建引擎时传的参数
private IZegoEventHandler zegoEventHandler = new IZegoEventHandler() {
...
@Override
public void onRoomStreamUpdate(String roomID, ZegoUpdateType zegoUpdateType, ArrayList<ZegoStream> arrayList, JSONObject jsonObject) {
ZegoCanvas zegoCanvas = new ZegoCanvas(textureView); // textureView是TextureView
zegoCanvas.viewMode = ZegoViewMode.ASPECT_FILL;
engine.startPlayingStream(streamID, zegoCanvas);
}
}
6 解析 SEI 信息
SEI 通道用来传识别和翻译后的文本,这里可以自己定义规则, Demo使用的规制是:
“zegoa2ti:{“username”:”小明”, “text”:”今天天气不错”, “trans”:”It’s a nice day today”}”
- “zegoa2ti:” 开头的 SEI 信息表示传的是识别中的文本。
- “zegoa2td:” 开头的 SEI 信息表示传的是识别确认最终的文本。
- 后面的内容是个json格式的字符串,包括用户名,文本和翻译的内容。
// zegoEventHandler对应创建引擎时传的参数
private IZegoEventHandler zegoEventHandler = new IZegoEventHandler() {
...
@Override
public void onPlayerRecvSEI(String streamID, byte[] bytes) {
String str = new String(data, StandardCharsets.UTF_8);
// 根据自定义规则处理文本
if (str.startWith("zegoa2ti") {
...
} else if (str.startWith("zegoa2td") {
...
} else {
// 其他用途的SEI
}
}
}
...
// json定义的数据类
public static class RecognizeModel{
@SerializedName("username")
public String userName;
@SerializedName("text")
public String text;
@SerializedName("trans")
public String translateText;
}
7 设置实时传译的参数并开启服务
开启实时传译前需要设置参数,包括服务提供商,源语言和目标语言。
zegoRealtimeTranslation.enableTranslate(true); // 如果不需要翻译可以设置为false
zegoRealtimeTranslation.enableInterimTranslation(true);// 如果不需要中间结果翻译可以设置为false,开启会增加很多翻译请求量
zegoRealtimeTranslation.setSpeechToTextService(ZegoRTServiceProvider.Iflytek); // 设置语音识别使用的服务提供商
zegoRealtimeTranslation.setTextTranslationService(ZegoRTServiceProvider.Iflytek); // 设置翻译使用的服务提供商
zegoRealtimeTranslation.setSourceSpeechLanguage(ZegoSpeechLanguage.zh_CN); // 设置语音识别的语言
zegoRealtimeTranslation.setTargetTranslationLanguage(ZegoTranslationLanguage.en); // 设置翻译的目标语言
zegoRealtimeTranslation.setRealtimeTranslationHandler(new IZegoRealtimeTranslationHandler() {
@Override
public void onRecognizingText(String sttText) {
RecognizeModel recognizeModel = new RecognizeModel();
recognizeModel.userName = viewModel.userName; // 自己的用户名
recognizeModel.text = sttText;
if (!TextUtils.isEmpty(sttText)) {
// 把识别的文本显示出来
}
// 把识别结果通过SEI通道发送出去
engine.sendSEI(("zegoa2ti:" + gson.toJson(recognizeModel)).getBytes(StandardCharsets.UTF_8));
}
@Override
public void onRecognizingTranslatedText(String translateText) {
RecognizeModel recognizeModel = new RecognizeModel();
recognizeModel.userName = viewModel.userName; // 自己的用户名
recognizeModel.translateText = translateText;
if (!TextUtils.isEmpty(translateText)) {
// 把翻译的文本显示出来
}
// 把识别结果通过SEI通道发送出去
engine.sendSEI(("zegoa2ti:" + gson.toJson(recognizeModel)).getBytes(StandardCharsets.UTF_8));
}
@Override
public void onRecognizedText(String sttText) {
RecognizeModel recognizeModel = new RecognizeModel();
recognizeModel.userName = viewModel.userName; // 自己的用户名
recognizeModel.text = sttText;
if (!TextUtils.isEmpty(sttText)) {
// 把识别的文本显示出来
}
// 把识别结果通过SEI通道发送出去
engine.sendSEI(("zegoa2td:" + gson.toJson(recognizeModel)).getBytes(StandardCharsets.UTF_8));
}
@Override
public void onRecognizedTranslatedText(String translateText) {
RecognizeModel recognizeModel = new RecognizeModel();
recognizeModel.userName = viewModel.userName; // 自己的用户名
recognizeModel.translateText = translateText;
if (!TextUtils.isEmpty(translateText)) {
// 把翻译的文本显示出来
}
// 把识别结果通过SEI通道发送出去
engine.sendSEI(("zegoa2td:" + gson.toJson(recognizeModel)).getBytes(StandardCharsets.UTF_8));
}
@Override
public void onError(int error) {
// 处理出错情况
}
});
// 开始识别
int ret = zegoRealtimeTranslation.startRealtimeTranslation();
// 在适当的时机,停止实时传译
zegoRealtimeTranslation.stopRealtimeTranslation();
8 资源回收
退出房间。主持人调用 ZEGO Express SDK 的 logoutRoom
接口,退出房间。
// 退出房间
ZegoExpressEngine.getEngine().logoutRoom();
反初始化 ZegoRealtimeTranslation SDK。
zegoRealtimeTranslation.unInit();
销毁引擎。如果退出房间,不需要使用到引擎资源,可以调用 ZEGO Express SDK 的 destroyEngine
接口,销毁引擎。
ZegoExpressEngine.destroyEngine{ };
文本翻译识别的实现流程基本跟语音识别相似,这里不做详细介绍了,可以参考 文档 实现。
本文为原创稿件,版权归作者所有,如需转载,请注明出处:https://www.nxrte.com/jishu/42109.html