实时语音
  • iOS
  • Android
  • macOS
  • Windows
  • Linux
  • Web
  • 小程序
  • Flutter
  • Electron
  • Unreal Engine
  • Unity3D
  • uni-app
  • React Native : JavaScript
  • Cocos Creator
  • 产品简介
  • 下载
  • 快速开始
    • 跑通示例源码
    • 集成 SDK
    • 实现音频通话
    • 实时音视频 SDK 与实时语音 SDK 差异
  • 通信能力
  • 房间能力
  • 音频能力
  • 直播能力
  • 其他能力
  • 客户端 API
  • 服务端 API
  • 常见错误码
  • 常见问题
  • 文档中心
  • 实时语音
  • 快速开始
  • 实现流程

实现音频通话

更新时间:2023-12-07 15:10

1 功能简介

本文将介绍如何快速实现一个简单的实时音视频通话。

相关概念解释:

  • ZEGO Express SDK:由 ZEGO 提供的实时音视频 SDK,能够为开发者提供便捷接入、高清流畅、多平台互通、低延迟、高并发的音视频服务。
  • 推流:把采集阶段封包好的音视频数据流推送到 ZEGO 实时音视频云的过程。
  • 拉流:从 ZEGO 实时音视频云将已有音视频数据流拉取播放的过程。
  • 房间:是 ZEGO 提供的音视频空间服务,用于组织用户群,同一房间内的用户可以互相收发实时音视频及消息。
    1. 用户需要先登录某个房间,才能进行推流、拉流操作。
    2. 用户只能收到自己所在房间内的相关消息(用户进出、音视频流变化等)。

更多相关概念请参考 术语说明

2 前提条件

在实现基本的音频通话功能之前,请确保:

SDK 同时也支持 Token 鉴权,若您对项目安全性有更高要求,建议您升级鉴权方式,详情请参考 如何从 AppSign 鉴权升级为 Token 鉴权

3 使用步骤

以用户 A 拉取用户 B 的流为例,流程如下图:

/Pics/Common/ZegoExpressEngine/common_usage_new.png

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

时序图

3.1 创建引擎

1. 创建引擎

调用 createEngineWithProfile 接口,将申请到的 AppID 和 AppSign 传入参数 “appID” 和 “appSign”,创建引擎。

如果需要注册回调方法,开发者可根据实际需要,实现 ZegoEventListener 中的某些方法,创建引擎后可通过调用 on 接口设置回调。

SDK 同时也支持 Token 鉴权,若您需要升级鉴权方式,可参考 如何从 AppSign 鉴权升级为 Token 鉴权

// 导入
import ZegoExpressEngine from 'zego-express-engine-reactnative';

// 采用通用场景
const profile = {
appID : xxx,
// AppSign 仅满足简单的鉴权需求,如果需要升级为更加安全的鉴权方式,请参考[如何从 AppSign 鉴权升级为 Token 鉴权](https://doc-zh.zego.im/faq/token_upgrade?product=ExpressVideo&platform=all)
// AppSign 可通过[控制台](https://console.zego.im/dashboard)获取,格式为 @"39011cbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
appSign: '39011cbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
scenario : 0
};

ZegoExpressEngine.createEngineWithProfile(profile)

2. 关闭摄像头

Express React Native SDK 不提供裁剪了视频模块的纯音频包,因此 React Native “实时语音” SDK 实际上是 “实时音视频” SDK。

若要实现纯音频场景,请在创建引擎后调用 enableCamera 关闭摄像头,以避免启动引擎的视频模块。摄像头关闭后,将不需要再申请摄像头权限,并且不会推视频流。

ZegoExpressEngine.instance().enableCamera(false); // 关闭摄像头

更多信息请参考文档 实时音视频 SDK 与实时语音 SDK 的差异

若您对 Express React Native SDK 包体大小有较高要求,可联系技术支持进行定制裁包,关于 SDK 包大小数据请参考 概述 文档。

3.2 登录房间

1. 登录

传入用户 ID 参数 “userID” 创建 ZegoUser 用户对象后,调用 loginRoom 接口,传入房间 ID 参数 “roomID” 和用户参数 “user”,登录房间。如果房间不存在,调用该接口时会创建并登录此房间。

  • 同一个AppID内,需保证 “roomID” 全局唯一。
  • 同一个AppID内,需保证 “userID” 全局唯一,建议开发者将其设置为一个有意义的值,可将 “userID” 与自己业务账号系统进行关联。
let roomConfig = {};
// 如果您使用 appsign 的方式鉴权,token 参数不需填写;如果需要使用更加安全的 鉴权方式: token 鉴权,请参考[如何从 AppSign 鉴权升级为 Token 鉴权](https://doc-zh.zego.im/faq/token_upgrade?product=ExpressVideo&platform=all)
// roomConfig.token = "xxxx";
// 只有传入 “isUserStatusNotify” 参数取值为 “true” 的 ZegoRoomConfig,才能收到 onRoomUserUpdate 回调。
roomConfig.isUserStatusNotify = true;
// 登录房间
// 开始登录房间
ZegoExpressEngine.instance().loginRoom('room1', {'userID': 'id1', 'userName': 'user1'}, roomConfig);

2. 监听登录房间后的事件回调

可根据实际应用需要,在登录房间后监听想要关注的事件通知,比如房间状态更新、用户状态更新、流状态更新等。

  • roomStateUpdate:房间状态更新回调,登录房间后,当房间连接状态发生变更(如出现房间断开,登录认证失败等情况),SDK 会通过该回调通知。

  • roomUserUpdate:用户状态更新回调,登录房间后,当房间内有用户新增或删除时,SDK 会通过该回调通知。

    只有调用 loginRoom 接口登录房间时传入 ZegoRoomConfig 配置,且 “isUserStatusNotify” 参数取值为 “true” 时,用户才能收到 roomUserUpdate 回调。

  • roomStreamUpdate:流状态更新回调,登录房间后,当房间内有用户新推送或删除音视频流时,SDK 会通过该回调通知。

  • 只有调用 loginRoom 接口登录房间时传入 ZegoRoomConfig 配置,且 “isUserStatusNotify” 参数取值为 “true” 时,用户才能收到 roomUserUpdate 回调。
  • 通常情况下,如果某个用户想要播放其他用户推送的视频,可以在收到流状态更新(新增)的回调中,调用 startPlayingStream 接口拉取远端推送的音视频流。
// 以下为常用的房间相关回调

ZegoExpressEngine.instance().on('roomStateUpdate', (roomID, state, errorCode, extendedData) => {
  // 房间状态更新回调,登录房间后,当房间连接状态发生变更(如出现房间断开,登录认证失败等情况),SDK会通过该回调通知
}); ;


ZegoExpressEngine.instance().on('roomUserUpdate', (roomID, updateType, userList) => {
  // 用户状态更新,登录房间后,当房间内有用户新增或删除时,SDK会通过该回调通知
});

ZegoExpressEngine.instance().on('roomStreamUpdate', (roomID, updateType, streamList) => {
  // 流状态更新,登录房间后,当房间内有用户新推送或删除音视频流时,SDK会通过该回调通知
});

3.3 推流

1. 开始推流

调用 startPublishingStream 接口,传入流 ID 参数 “streamID”,向远端用户发送本端的音视频流。

同一个 AppID 内,需保证 “streamID” 全局唯一。如果同一个 AppID 内,不同用户各推了一条 “streamID” 相同的流,会导致后推流的用户推流失败。

/** 开始推流 */
ZegoExpressEngine.instance().startPublishingStream("streamID");

2. 监听推流后的事件回调

根据实际应用需要,在推流后监听想要关注的事件通知,比如推流状态更新等。

PublisherStateUpdate:推流状态更新回调,调用推流接口成功后,当推流状态发生变更,如出现网络中断导致推流异常等情况,SDK 在重试推流的同时,会通过该回调通知。

    ZegoExpressEngine.instance().on("PublisherStateUpdate", (streamID, state, errorCode, extendedData) => {
    // 调用推流接口成功后,当推流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试推流的同时,会通过该回调通知
    //....
});

3.4 拉流

1. 开始拉流

调用 startPlayingStream 接口,根据传入的流 ID 参数 “streamID”,拉取远端推送的音视频流。

远端用户推送的 “streamID” 可以从 onRoomStreamUpdate 回调中获取。

需保证 “streamID” 全局唯一。


// 开始拉流
ZegoExpressEngine.instance().startPlayingStream("streamID");

2. 监听拉流后的事件回调

根据实际应用需要,在拉流后监听想要关注的事件通知,比如拉流状态更新等。

PlayerStateUpdate:拉流状态更新回调,调用拉流接口成功后,当拉流状态发生变更,如出现网络中断导致推流异常等情况,SDK 在重试拉流的同时,会通过该回调通知。

ZegoExpressEngine.instance().on("PlayerStateUpdate", (streamID, state, errorCode, extendedData) => {
    /** 调用拉流接口成功后,当拉流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试拉流的同时,会通过该回调通知 */
    //....
});

3.5 体验实时音视频功能

在真机中运行项目,运行成功后,可以看到本端视频画面。

为方便体验,ZEGO 提供了一个 Web 端调试示例 ,在该页面下,输入相同的 AppID、RoomID,输入不同的 UserID、以及对应的 Token,即可加入同一房间与真机设备互通。当成功开始音视频通话时,可以听到远端的音频,看到远端的视频画面。

3.6 停止推拉流

1. 停止推流

调用 stopPublishingStream 接口停止发送本地的音视频流,结束通话。

/** 停止推流 */
ZegoExpressEngine.instance().stopPublishingStream();

2. 停止拉流

调用 stopPlayingStream 接口,停止拉取远端的音视频流。

如果开发者通过 roomStreamUpdate 回调收到了音视频流 “减少” 的通知,请及时调用 stopPlayingStream 接口停止拉流,避免拉到空流、产生额外的成本;或者,开发者可以根据自己的业务需求,选择合适的时机,主动调用 stopPlayingStream 接口停止拉流。

// 停止拉流
ZegoExpressEngine.instance().stopPlayingStream("streamID");

3. 退出房间

调用 logoutRoom 接口退出房间,本端会收到 onRoomStateUpdate 回调通知调用结果,并停止其所有推拉流以及本地预览。

// 退出房间
ZegoExpressEngine.instance().logoutRoom('room1');

3.7 销毁引擎

调用 destroyEngine 接口销毁引擎,用于释放 SDK 使用的资源。

ZegoExpressEngine.destroyEngine();

根据实际需要,可在销毁引擎时通过 “await” 关键字,进行异步等待以确保设备硬件资源被释放完成。

本篇目录