接入语音翻译SDK,快速实现实时语音识别和文本翻译识别功能

本文介绍如何接入 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”。

接入语音翻译SDK,快速实现实时语音识别和文本翻译识别功能

2. 选一个 EmptyActivity 项目。

接入语音翻译SDK,快速实现实时语音识别和文本翻译识别功能

3. 填写项目的存储路径和项目名称,“minimum SDK” 选择 “API 26”。

接入语音翻译SDK,快速实现实时语音识别和文本翻译识别功能

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 的接口对接,主播与观众之间的通信方式。

在实现实时语音识别功能之前,请确保:

流程图

接入语音翻译SDK,快速实现实时语音识别和文本翻译识别功能

实现流程

请您根据自己的业务需要,选择实现相关的内容识别传译功能。

1 初始化 Express SDK

  1. 创建界面。根据场景需要,为您的项目展示实时传译的用户界面,推荐您在项目中添加如下元素:
    • 主播的视频窗口
    • 语音识别结果的窗口
    • 识别结果翻译后的窗口
    • 设置项(服务商,语言等)
  2. 创建引擎。调用 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

(1)

相关推荐

发表回复

登录后才能评论