实时字幕

实时字幕是在AI通话期间,可以在终端UI上实时展示用户和AI智能体的聊天内容。通过阅读本文,您可以了解如何从RTC自定义消息通道中获取实时字幕内容。

前提条件

解析RTC自定义消息

您需要对RTC自定义消息通道中的消息体进行解析,来获取实时字幕内容。系统内置消息字段如下:

字段名称

描述

type

消息类型:

  • type=1002,表示AI智能体实时字幕

  • type=1003,表示终端用户实时字幕

senderId

发送消息的智能体Id

receiverId

接收人的UserId,在这里为空字符串

data

具体的消息内容,无内容该字段可以为空

text

  • type=1002时,表示AI智能体生成的具体文本

  • type=1003时,表示终端用户说话识别出的具体文本

end

  • type=1002时,智能体回答较长时,字幕会拆分为多次发送,当end=true时表示是这次回答的的最后一句

  • type=1003时:

    • end=true,表示文本为这句话的最终识别结果

    • end=false,表示文本在不断识别中的中间结果

sentenceId

  • type=1002时,表示回应对应sentenceId语音输入的的LLM内容

  • type=1003时,表示当前文本属于的句子ID

AI机器人实时字幕消息体如下:

{
  "type": 1002,
  "senderId": "robot_1",    // 发送消息的智能体id
  "receiverId": "",   			// 无需指定接收人Id,一般情况下为空
  "data": {
    "text": "这是AI机器人产生的文本内容",  // AI智能体生成的具体文本
    "end": false,                      // 这次返回的文本是否是最后一句
    "sentenceId": 1            		 // 表示回应对应sentenceId语音输入的的llm内容
  }
}

终端用户实时字幕消息体如下:

{
  "type": 1003,
  "senderId": "robot_1",    // 发送消息的智能体id
  "receiverId": "",   			// 无需指定接收人Id,一般情况下为空
  "data": {
    "text": "这是终端用户说话识别到的目前文本内容",  // 终端用户说话识别出的具体文本
    "end": false,                       // 当前文本是否为这句话的最终结果
    "sentenceId": 1                     // 当前文本属于的句子ID
  }
}

IOS

从RTC自定义消息通道中获取实时字幕的示例代码如下:

private var lastRobotSentenceId: Int? = nil
private var robotSpeakingText: String? = nil
public func onDataChannelMessage(_ uid: String, controlMsg: AliRtcDataChannelMsg) {    
    if controlMsg.type != .custom {
        return
    }

    let dataDict = (try? JSONSerialization.jsonObject(with: controlMsg.data, options: .allowFragments)) as? [String : Any]
    guard let dataDict = dataDict else {
        return
    }
    debugPrint("onDataChannelMessage:\(dataDict)")
    if dataDict["type"] as? Int32 == 1002 {
        let senderId = dataDict["senderId"] as? String
        let receiverId = dataDict["receiverId"] as? String
        let data = dataDict["data"] as? [String: Any]
        if let data = data {
            let text = data["text"] as? String
            let end = data["end"] as? Bool
            let sentenceId = data["sentenceId"] as? Int
            if sentenceId == lastRobotSentenceId {
                self.robotSpeakingText?.append(text ?? "") 
            }
            else {
                self.lastRobotSentenceId = sentenceId
                self.robotSpeakingText = text ?? ""
            }
            if end == true {
                DispatchQueue.main.async {
                    debugPrint("Received Robot Speaking Text: \(self.robotSpeakingText!)")
                    // 更新你的UI状态

                }
            }
        }
        if let text = data?["text"] as? String {
            
            DispatchQueue.main.async {
                // 更新你的UI状态
                debugPrint("Received Robot Speaking Text: \(text)")
            }
        }
    }
    else if dataDict["type"] as? Int32 == 1003 {
        let senderId = dataDict["senderId"] as? String
        let receiverId = dataDict["receiverId"] as? String
        let data = dataDict["data"] as? [String: Any]
        if let text = data?["text"] as? String {
            if data?["end"] as? Bool == true {
                DispatchQueue.main.async {
                    debugPrint("Received ASR Text: \(text)")
                    // 更新你的UI状态
                }
            }
        }
    }
}

Android

从RTC自定义消息通道中获取实时字幕的示例代码如下:

private int mSentenceId = -1;
private String mRobotSpeakingText = "";

aliRtcEngine.setRtcEngineNotify( new AliRtcEngineNotify() {
    @Override
    public void onDataChannelMessage(String uid, AliRtcEngine.AliRtcDataChannelMsg msg) {
        super.onDataChannelMessage(uid, msg);
        if (msg.type == AliEngineDataMsgCustom) {
            try {
                String dataStr = new String(msg.data);
                JSONObject jsonObject = new JSONObject(dataStr);
                int msgType = jsonObject.optInt("type");
                String senderId = jsonObject.optString("senderId");
                String receiverId = jsonObject.optString("receiverId");
                JSONObject dataJson = jsonObject.optJSONObject("data");
                if (null != dataJson) {
                    if (msgType == 1002) {
                        // 机器人的话
                        String text = dataJson.optString("text");
                        // 当前文本是否为这句话的最终结果
                        boolean end = dataJson.optBoolean("end");
                        // 表示回应对应sentenceId语音输入的的llm内容
                        int sentenceId = dataJson.optInt("sentenceId");
                        if (sentenceId == mSentenceId) {
                            mRobotSpeakingText += text;
                        }
                        else {
                            mRobotSpeakingText = text;
                            mSentenceId = sentenceId;
                        }
                        if (end) {
                            System.out.println(mRobotSpeakingText);
                            // TODO 机器人字幕显示
                        }
                        
                    } else if (msgType == 1003) {
                        // ASR识别出的具体文本
                        String text = dataJson.optString("text");
                        // 当前文本是否为这句话的最终结果
                        boolean end = dataJson.optBoolean("end");
                        // 当前文本属于的句子ID
                        int sentenceId = dataJson.optInt("sentenceId");
                        if (end) {
                            System.out.println(text);
                            // TODO ASR字幕显示
                        }
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
});