logo
当前页

展示字幕


本文介绍如何展示用户在与智能体进行语音通话的过程中的字幕。如下:

  • 用户说话内容:流式展示用户正在说的话(语音识别(ASR)的实时结果)
  • 智能体说话内容:流式展示智能体输出的内容(大语言模型(LLM)实时的输出结果)
subtitle.png

前提条件

已按照 快速开始 文档集成 ZEGO Express SDK 和 AI Agent 并实现基本的语音通话功能。

快速实现

用户与智能体进行语音对话期间,AI Agent 服务端通过 RTC 房间自定义消息下发 ASR 识别文本和 LLM 回答的文本。客户端可以监听房间自定义消息,解析对应的状态事件来渲染 UI 。

RTC 房间自定义消息的处理流程如下:

监听房间自定义消息

Untitled
import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:zego_express_engine/zego_express_engine.dart';

class YourPage extends StatefulWidget {
  const YourPage({super.key});

  @override
  State<YourPage> createState() => _YourPageState();
}

class _YourPageState extends State<YourPage> {
  @override
  void initState() {
    super.initState();

    ZegoExpressEngine.onRecvExperimentalAPI = onRecvExperimentalAPI;
  }

  @override
  void dispose() {
    super.dispose();

    ZegoExpressEngine.onRecvExperimentalAPI = null;
  }

  @override
  Widget build(BuildContext context) {
    return YourMessageView();
  }

  /// 注意!!!:通过房间自定义消息收到的数据可能会乱序,需要根据 SeqId 字段进行排序。
  void onRecvExperimentalAPI(String content) {
    try {
      /// 检查是否为房间消息
      final contentMap = jsonDecode(content);
      if (contentMap['method'] !=
          'liveroom.room.on_recive_room_channel_message') {
        return;
      }

      final params = contentMap['params'];
      if (params == null) {
        return;
      }

      final msgContent = params['msg_content'];
      if (msgContent == null) {
        return;
      }

      handleMessageContent(msgContent);
    } catch (e) {}
  }

  /// 处理消息内容
  void handleMessageContent(String msgContent) {
    final Map<String, dynamic> json = jsonDecode(msgContent);

    /// 解析基本信息
    final int timestamp = json['Timestamp'] ?? 0;
    final int seqId = json['SeqId'] ?? 0;
    final int round = json['Round'] ?? 0;
    final int cmdType = json['Cmd'] ?? 0;
    final Map<String, dynamic> data =
        json['Data'] != null ? Map<String, dynamic>.from(json['Data']) : {};

    // 根据命令类型处理消息
    switch (cmdType) {
      case 3:

        /// ASR文本
        handleRecvAsrMessage(data, seqId, round, timestamp);
        break;
      case 4:

        /// LLM文本
        handleRecvLLMMessage(data, seqId, round, timestamp);
        break;
    }
  }
}
1
Copied!

房间自定义消息协议

房间自定义消息的各字段说明如下:

字段类型描述
TimestampNumber时间戳,秒级别
SeqIdNumber包序列号,可能乱序,请根据序列号对消息进行排序。极端情况下 Id 可能不连续。
RoundNumber对话轮次,每次用户主动说话轮次增加
CmdNumber3: 语音识别(ASR)的文本
4: LLM 文本
DataObject具体内容,各Cmd对应不同Data

Cmd 不同对应的 Data 也不同,具体如下:

处理逻辑

根据 Cmd 字段判断消息类型,并根据 Data 字段获取消息内容。

使用字幕组件

您还可以直接下载字幕组件源码到您的项目中直接使用。

注意事项

  • 消息排序处理:通过房间自定义消息收到的数据可能会乱序,需要根据 SeqId 字段进行排序。
  • 流式文本处理:
  • ASR 文本每次下发的是全量文本,同一个 MessageId 的消息需要完全替换之前的内容。
  • LLM 文本每次下发的是增量文本,同一个 MessageId 的消息需要在排序后累加显示。
  • 内存管理:请及时清理已完成的消息缓存,特别是当用户进行长时间对话时。

Previous

快速发起语音通话