本文将详细介绍如何使用ZEGO SDK结合微信小程序能力,快速实现低延迟、高稳定的一对一/多人实时音视频通话。相比微信原生<live-pusher>/<live-player>组件,即构封装的<zego-pusher>与<zego-player>组件更简洁、兼容性更好,适合快速落地在线客服、视频问诊、在线会议、社交互动等场景。

一、典型应用场景

小程序音视频通话无需用户下载额外App,触达率高,适配多行业高频需求,核心典型场景如下:

  1. 一对一社交互动:陌生人匹配聊天、好友视频通话、情侣互动等,依托小程序轻量化特性,无需跳转,点击即可发起通话,提升用户留存。

  2. 在线咨询服务:电商客服视频答疑、教育机构试听课、心理咨询视频沟通、房产/汽车远程带看等,实现“面对面”高效沟通,提升转化。

  3. 医疗健康场景:在线问诊、远程复诊、慢病随访等,患者无需到院,通过小程序即可与医生实时视频沟通,降低就医成本。

  4. 多人协同场景:小型团队会议、线上班会、家庭视频团聚等,支持多人同时接入,低延迟不卡顿,适配轻量化协同需求。

  5. 合规审核场景:实名认证视频核验、企业资质视频审核、网约车司机人脸核验等,通过实时音视频完成身份确认,保障合规性。

二、实现微信小程序音视频通话的前提条件

在开始开发前,请确保完成以下准备:

  • 已在项目中集成 ZEGO SDK(建议 2.10.0 及以上版本),参考官方集成文档完成引入。

  • 已在ZEGO 控制台创建项目,获取有效的AppID、Server地址与Token(用于鉴权)。

  • 微信小程序基础库 ≥ 2.10.0,微信 App 版本 ≥ 7.0.9。

  • 已在微信公众平台完成类目与权限开通(社交-直播、教育、医疗等合规类目),并开启实时播放音视频流、实时录制音视频流权限。

三、ZEGO音视频SDK实现流程

用户通过 ZEGO Express SDK 进行视频通话的基本流程为:

用户 A、B 加入房间,用户 B 预览并将音视频流推送到 ZEGO 云服务(推流),用户 A 收到用户 B 推送音视频流的通知之后,在通知中播放用户 B 的音视频流(拉流)

3.1 配置微信小程序后台

在初始化 SDK 前,需要在微信公众平台中进行如下配置:

  • 服务器域名配置:在“小程序后台 > 开发管理 > 开发设置 > 服务器域名”中,按照协议分类,将即构 Server 地址、LogUrl、以及用户业务需要用到的地址填到指定的“socket合法域名”或“request合法域名”中,详情请参考 控制台 - 项目信息。

注意

  • 控制台提供的 Server 地址格式为:wss://xxxxxxxxxx.com/ws。在 微信公众平台 填写时,不能直接复制原地址,需要删除原地址的 “/ws”,应填入地址的格式为:wss://xxxxxxxxxx.com。

  • 控制台提供的 LogUrl 地址格式为:https://xxxxxxxxxx.com/httplog。在 微信公众平台 填写时,不能直接复制原地址,需要删除原地址的 “/httplog”,应填入地址的格式为:https://xxxxxxxxxx.com。

  • 如果您使用 3.0.0 或以上版本(包括 3.6.0 及以上版本)的 SDK,还需要添加一些 socket 域名,详情请参考 3.0.0 及以上版本升级指南。

  • 如果您使用 3.6.0 或以上版本的 SDK,还需要添加一些 request 域名,详情请参考 3.6.0 及以上版本升级指南。

  • 相关功能开启:在“小程序后台 > 开发管理 > 接口设置 > 接口权限”中,打开 实时播放音视频流 和 实时录制音视频流 功能开关。

  • 由于使用摄像头或者麦克风涉及到用户隐私,请参考微信官方文档 配置小程序用户隐私保护指引 补充相应用户隐私保护指引。否则,当您的项目部署到正式环境时,将无法推流。

3.2 初始化

1.创建界面

根据场景需要,为您的项目创建视频通话的用户界面。我们推荐您在项目中添加如下元素:

  • 本地预览窗口

  • 远端视频窗口

  • 结束按钮

参考界面代码:

<view wx:if="{{canShow== 1}}" class="">
  <view class="containerBase">
          <zego-pusher id="zegoPusher" pusher="{{pusher}}" />
        <zego-player wx:for="{{zegoPlayerList}}" wx:key="id" id="{{item.componentID}}" playerId="{{item.playerId}}"
                        playerList="{{playerList}}" />
  </view>
  <view class="index-container">
    <view class='input-container'>
      <input value="{{roomID}}" bindinput="bindKeyInput" placeholder="请输入房间 ID" placeholder-style='color: #b3b3b3; font-size: 14px;' class="room-input" />
      <text class="tip"></text>
    </view>
    <view class="button-container">
      <button bindtap="openRoom" data-role="1" data-option="videoAndAudio" hover-class="none" class="openRoom">
        加入房间(推流)
      </button>
      <button bindtap="logout" hover-class="none">退出房间</button>
    </view>
  </view>
</view>
<view class="settings">
  <button wx:if="{{canShow==0}}" open-type="openSetting" bindopensetting="settingCallback">
    授权使用摄像头和麦克风
  </button>
</view>

2.创建引擎

创建 ZegoExpressEngine 引擎实例,将申请到的 AppID 传入参数 “appID”,将获取到的 Server 地址传入参数 “server”。

// 初始化实例,server 参数可直接填空字符串
zg = new ZegoExpressEngine(appID, server);

注意

若使用 3.6.0 及以上版本 SDK,server 参数可填写控制台获取的Server 地址或者直接填空字符串。

3.设置回调

创建引擎后,开发者可根据实际需要,通过引擎实例的 on 方法设置回调。

注意

为避免错过事件通知,建议在创建引擎后立即监听回调

zg.on('roomStateUpdate', (roomID, state, errorCode, extendedData) => {
    if (state == 'DISCONNECTED') {
        // 与房间断开了连接
  // ...
    }

    if (state == 'CONNECTING') {
        // 与房间尝试连接中
  // ...
    }

    if (state == 'CONNECTED') {
        // 与房间连接成功
  // ...
    }
})

3.3 登录房间

1. 获取登录 Token

登录房间需要用于验证身份的 Token,获取方式请参考 用户权限控制。如需快速调试,建议使用控制台生成的临时 Token,生成临时 Token 的具体操作请参考 控制台 - 项目管理。

2. 登录房间

您可以调用 SDK 的 loginRoom 接口,传入房间 ID 参数 “roomID”、“token” 和用户参数 “user”,登录房间。如果房间不存在,调用该接口时会创建并登录此房间。

您可通过监听 roomStateUpdate 回调实时监控自己在本房间内的连接状态,具体请参考 常见通知回调 中的“我在房间内的连接状态变化通知”。

roomID 和 user 的参数由您本地生成,但是需要满足以下条件:

  • 同一个 AppID 内,需保证 “roomID” 全局唯一。

  • 同一个 AppID 内,需保证 “userID” 全局唯一,建议开发者将 “userID” 与自己业务的账号系统进行关联。

  • “userID” 必须与生成 token 时传入的 userID 保持一致,否则登录失败。

注意

为避免错过任何通知,建议在登录房间前先设置监听回调(如房间状态、用户状态、流状态、推拉流状态等),具体请参考 常见通知回调。

// 登录房间,成功则返回 true
const result = await zg.loginRoom(roomID, token, {
    userID: "user1", // userID,需用户自己定义,保证全局唯一,建议设置为业务系统中的用户唯一标识
    userName: "user1_name" // userName 用户名
}, {
    userUpdate: true // 是否接收用户进出房间的回调,设置为 true 才能接收到房间内其他用户进出房间的回调
});

3.4 初始化小程序组件实例

调用 initContext 接口初始化小程序组件。

组件中用于存储推流属性 pusher 和拉流属性列表 playerList 的两个字段需要传给 SDK,SDK 后续将通过传入的两个字段对相应的推拉流作状态及视图更新处理。

  • pusher 字段中的属性值请参考 ZegoWxPusherAttributes。

  • playerlist 字段中的属性值请参考 ZegoWxPlayerAttributes。

zg.initContext({
    wxContext: this,
    pushAtr: "pusher", // pushAtr 配置的变量名,必须与传给 <zego-pusher> 组件 pusher 属性的变量名完全一致。
    playAtr: "playerList" // playAtr 配置的变量名,必须与传给 <zego-player> 组件 playerList 属性的变量名完全一致。
})

3.4 创建对应业务场景的 WXML

1.复制组件代码到项目工程中

将示例代码 components 文件夹下的 zego-player 和 zego-pusher 两个文件夹,复制到您的业务代码 components 文件夹中。

2. 在项目 JSON 文件中引入组件

根据您的项目结构,在对应的 JSON 文件中引入 <zego-pusher> 和 <zego-player> 组件。

// 在 JSON 文件中引入组件
{
  "usingComponents": {
    "zego-pusher": "../../components/zego-pusher/zego-pusher",
    "zego-player": "../../components/zego-player/zego-player"
  }
}

3.5 在 WXML 文件中使用推拉流组件

在 WXML 文件中使用推拉流组件 <zego-pusher> 和 <zego-player> 。

// 在 WXML 文件中使用组件
// 传给 <zego-pusher> 组件 pusher 属性的变量名,必须与 initContext 配置中 pushAtr 的参数值完全一致。
  <zego-pusher id="zegoPusher" pusher="{{pusher}}" />
// 传给 <zego-player> 组件 playerList 属性的变量名,必须与 initContext 配置中 playAtr 的参数值完全一致。zegoPlayerList 见 “拉取其他用户的音视频” 章节。
  <zego-player wx:for="{{zegoPlayerList}}" wx:key="id" id="{{item.componentID}}" playerId="{{item.playerId}}" playerList="{{playerList}}" />

3.6 推送音视频流到 ZEGO 音视频云

必须完成初始化小程序组件实例和创建业务场景的 WXML 之后,才能调用 SDK 接口创建推流和拉流实例。

用户先获取 <zego-pusher> 组件的实例对象,再调用该对象的 startPush 方法传入 SDK 实例和 streamID 参数即可发起推流。

// 获取 <zego-pusher> 组件实例对象
const zegoPusher = this.selectComponent("#zegoPusher");
// 调用 <zego-pusher> 实例对象的 startPush 方法进行推流。zg 为 SDK 实例对象,"streamID_xxx" 为 streamID。
await zegoPusher.startPush(zg, "streamID_xxx");

注意

  • 您可通过监听 publisherStateUpdate 回调知晓推流是否成功

  • streamID 由您本地生成,但是需要保证:

    • 同一个 AppID 下,streamID 全局唯一。如果同一个 AppID 下,不同用户各推了一条 streamID 相同的流,后推流的用户推流失败。

    • streamID 长度不超过 256 字节的字符串。仅支持数字、英文字符和 "-"、"_"。

3.7 拉取其他用户的音视频

进行视频通话时,我们需要拉取到其他用户的音视频。

用户先获取 <zego-player> 组件实例对象,再调用 该对象的 startPlay 方法传入 SDK 实例和 streamID 参数即可发起拉流。

远端用户推送的 “streamID” 可以从 roomStreamUpdate 回调中获得

// 在 SDK 的回调 roomStreamUpdate 中获取拉流 streamID
// 当房间内其他用户推的流增加或减少时触发
zg.on("roomStreamUpdate", async (roomID, updateType, streamList) => {
    if (updateType === "ADD") {
      // ----- 使用 zego-player 组件的 startPlay 接口播放 -----
      for (let i = 0; i < streamList.length; i++) {
        try {
          // 设置 zego-player 组件属性
          const zegoPlayerAttr = {
            componentID: `zego-${streamList[i].streamID}`,
            playerId: streamList[i].streamID
          }
          // 添加到组件列表中
          this.data.zegoPlayerList.push(zegoPlayerAttr)
          // 更新,并渲染组件列表
          this.setData({
            zegoPlayerList:this.data.zegoPlayerList
          })

          // 在zegoPlayerList更新后, 将zg实例传入对应的流id的组件内
          const zegoPlayer = this.selectComponent(`#${zegoPlayerAttr.componentID}`)
          if (!zegoPlayer) return console.warn("未能获取到组件节点", streamList[i].streamID)

          // 开始播放
          console.warn("开始拉流", roomID, streamList[i].streamID);
          await zegoPlayer.startPlay(zg, streamList[i].streamID)
        } catch (error) {
          console.error("拉流出错,等待房间重连恢复", error)
        }
      }
    } else if (updateType === 'DELETE') {
        // 流删除,停止拉流
    }
});

注意

如果用户在音视频通话的过程中遇到相关错误,可查询 常见错误码。

3.8 停止音视频通话

停止推送和拉取音视频流

1.停止推流

用户先获取 <zego-pusher> 组件实例对象,再调用该对象的 stopPush 方法结束拉流。

// 停止推流
// 获取 <zego-pusher> 组件实例对象
const zegoPusher = this.selectComponent("#zegoPusher");
// 调用 <zego-pusher> 实例对象的 stopPush 方法停止推流。
await zegoPusher.stopPush();

2.停止拉流

用户先获取 <zego-player> 组件实例对象,再调用该对象的 stopPlay 方法结束拉流。

// 停止拉流
// 获取 <zego-player> 组件实例对象
const zegoPlayer = this.selectComponent(`#${zegoPlayerAttr.componentID}`);
// 调用 <zego-player> 实例对象的 stopPlay 方法停止拉流。
await zegoPlayer.stopPlay();

3.退出房间

调用 SDK 的 logoutRoom 接口退出房间。

zg.logoutRoom(roomID);

4.销毁引擎

如果用户彻底不使用音视频功能时,可调用 destroyEngine 接口销毁引擎,释放麦克风、摄像头、内存、CPU 等资源。

zg.destroyEngine();
zg = null;

3.9视频通话 API 调用时序

整个推拉流过程的 API 调用时序可参考下图:

四、调试与常见问题

  • 真机调试:开发者工具不支持推拉流,必须用真机预览/真机调试。

  • 域名与权限:检查 socket/request 域名、实时音视频权限、隐私协议。

  • Token 鉴权:userID 必须与生成 Token 时一致,否则登录失败。

  • streamID 唯一:同一 AppID 下不可重复,否则推流失败。

  • 互通测试:使用 ZEGO Web 端调试页,输入相同 AppID、RoomID、Token 即可与小程序互通。

五、总结

通过ZEGO SDK,只需初始化引擎 → 登录房间 → 推流 → 自动拉流四步,即可快速实现微信小程序音视频通话。即构组件封装了原生组件的复杂配置与兼容性问题,支持一对一、多人通话,延迟低、抗丢包强,可直接用于线上生产环境,适配各类音视频场景需求。

Logo

火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。

更多推荐