本文档将介绍如何在您的 Harmony 项目中集成 ARTC SDK, 快速实现一个简单的纯音频互动App,适用于语音通话、语聊房等场景。
功能介绍
在开始前,您需要了解以下有关音视频实时互动的基本概念:
ARTC SDK:阿里云实时音视频产品,帮助开发中快速实现实时音视频互动的SDK。
频道:房间的概念,在同一个频道内的用户可以进行实时互动。
主播:可在频道内发布音视频流,并可订阅其他主播发布的音视频流。
观众:可在频道内订阅音视频流,不能发布音视频流。
下图展示了实现音频通话及语聊房的基本流程:
用户需要先调用
joinChannel加入频道,才能进行推流、拉流:普通纯音频通话场景:所有用户都是主播角色,可以进行推流和拉流;
语聊房场景:需要在频道内推流的用户设置主播角色;如果用户只需要拉流,不需要推流,则设置观众角色;
通过
setClientRole为用户设置不同的角色。
加入频道后,不同角色的用户有不同的推拉流行为:
所有频道内的用户都可以接收相同频道内的音视频流;
主播角色可以在频道内推音视频流;
观众如果需要推流,需要调用
setClientRole方法,将用户角色切换成主播,便可以推流。
前提条件
在运行示例项目之前,请确保开发环境满足以下要求:
开发工具:DevEco Studio 5.0.3.900 Release 或以上版本;获取配套 API Version 12的 HarmonyOS NEXT SDK 或以上版本。
测试设备:获取配套 API Version 12的 HarmonyOS NEXT 5.0.0.102 操作系统或以上版本,支持音视频的鸿蒙设备,且已开启“允许调试”选项。
网络环境:需要稳定的网络连接。
应用准备:获取实时音视频应用的AppID和AppKey,详情请参见创建应用。
示例项目
阿里云ARTC SDK提供了开源的示例项目供客户参考,您可以前往下载或查看示例源码。
实现步骤
下面将以语聊房场景为例进行演示,相关功能时序如下:
语聊房场景主要特点如下:
纯音频:频道内仅包含音频,不包含视频。
主播/观众角色:频道内角色分为主播和观众角色,主播角色可以推拉音频流,观众角色只能拉取主播推送的音频流;观众角色可以切换为主播角色。
实现纯音频互动
1. 处理权限请求
进入音频互动前,请确保已经申请了音频和网络相关权限。
2. 获取鉴权 Token
调用joinChannel加入 ARTC 频道时需要传入鉴权 Token,用于鉴权用户的合法身份,有关 Token 的介绍和生成请参考Token鉴权。
上线发布阶段:
由于Token的生成需要使用AppKey,写死在客户端存在泄露的风险,因此强烈建议线上业务通过业务Server生成下发给客户端。
开发调试阶段:
开发调试阶段,如果业务Server还没有生成Token的逻辑,可以暂时参考示例项目中的Token生成逻辑,生成临时Token。
3. 创建并初始化引擎
创建 RTC 引擎
调用
getInstance创建 RTC 引擎对象。private rtcEngine: AliRtcEngine | null | undefined; this.rtcEngine = AliRtcEngine.getInstance('', this.context);初始化引擎
调用
setChannelProfile接口设置频道为互动模式。根据业务场景中用户的角色,调用
setClientRole接口为用户设置主播/观众角色。调用
setAudioProfile接口设置音频质量与场景模式。
// 设置频道模式为互动直播模式
this.rtcEngine.setChannelProfile(AliRtcChannelProfile.AliRtcInteractiveLive);
// 设置用户角色
if (this.isAnchor) {
// 主播角色:需要推流
this.rtcEngine.setClientRole(AliRtcClientRole.AliRtcClientRoleInteractive);
} else {
// 观众角色:只拉流
this.rtcEngine.setClientRole(AliRtcClientRole.AliRtcClientRoleLive);
}
// 设置音频配置(高音质模式 + 音乐场景)
this.rtcEngine.setAudioProfile(
AliRtcAudioProfile.AliRtcHighQualityMode,
AliRtcAudioScenario.AliRtcSceneMusicMode
);实现常用回调
SDK 在运行过程中如遇到异常情况,会优先尝试内部重试机制以自动恢复。对于无法自行解决的错误,SDK 会通过预定义的回调接口通知您的应用程序。
以下是一些 SDK 无法处理、需由应用层监听和响应的关键回调:
异常发生原因
回调及参数
解决方案
说明
鉴权失败
onJoinChannel回调中的result返回AliRtcErrJoinBadToken发生错误时App需要检查Token是否正确。
在用户主动调用API时,若鉴权失败,系统将在调用API的回调中返回鉴权失败的错误信息。
鉴权将要过期
onWillAuthInfoExpire发生该异常时App需要重新获取最新的鉴权信息后,再调用
refreshAuthInfo刷新鉴权信息。鉴权过期错误在两种情况下出现:用户调用API或程序执行期间。因此,错误反馈将通过API回调或通过独立的错误回调通知。
鉴权过期
onAuthInfoExpired发生该异常时App需要重新入会。
鉴权过期错误在两种情况下出现:用户调用API或程序执行期间。因此,错误反馈将通过API回调或通过独立的错误回调通知。
网络连接异常
onConnectionStatusChange回调返回AliRtcConnectionStatusFailed。发生该异常时APP需要重新入会。
SDK具备一定时间断网自动恢复能力,但若断线时间超出预设阈值,会触发超时并断开连接。此时,App应检查网络状态并指导用户重新加入会议。
被踢下线
onByeAliRtcOnByeUserReplaced:当发生该异常时排查用户userid是否相同。AliRtcOnByeBeKickedOut:当发生该异常时,表示被业务踢下线,需要重新入会。AliRtcOnByeChannelTerminated:当发生该异常时,表示房间被销毁,需要重新入会。
RTC服务提供了管理员可以主动移除参与者的功能。
本地设备异常
onLocalDeviceException发生该异常时App需要检测权限、设备硬件是否正常。
RTC服务支持设备检测和异常诊断的能力;当本地设备发生异常时,RTC服务会通过回调的方式通知客户本地设备异常,此时,若SDK无法自行解决问题,则App需要介入以查看设备是否正常。
const listener = new AliRtcEngineEventListener()
.onJoinChannel((resultCode: number, channel: string, elapsed: string) => {
console.info(`加入频道结果: result=${resultCode}, channel=${channel}, userId=${this.UserId}, elapsed=${elapsed}`);
this.handleJoinResult(resultCode, channel);
})
.onLeaveChannel((resultCode: number) => {
console.info(`离开频道结果: result=${resultCode}`);
})
.onConnectionStatusChange((status: number, reason: number) => {
console.info(`连接状态改变: status=${status}, reason=${reason}`);
})
this.rtcEngine.setRtcEngineEventListener(listener);4. 设置推拉流属性
SDK 默认情况下会自动推送和拉取频道内的音视频流
设置为观众模式后只能拉流,
publishLocalAudioStream无效。对于主播和观众均可以设置为下面的配置。
this.rtcEngine.publishLocalAudioStream(true);
// 语聊场景不需要发布视频
this.rtcEngine.publishLocalVideoStream(false);
// 设置默认订阅所有远端音频流
this.rtcEngine.setDefaultSubscribeAllRemoteAudioStreams(true);
this.rtcEngine.subscribeAllRemoteAudioStreams(true);5. 加入频道开始纯音频互动
调用joinChannel加入频道,如果Token是单参数规则生成的,需要调用SDK单参数的joinChannelWithToken接口,如果是多参数规则生成的,需要调用SDK多参数的joinChannel接口。调用完加入频道后,可以在onJoinChannelResult回调中拿到加入频道结果,如果result为0,则表示加入频道成功,否则需要检查传进来的Token是否非法。
// 加入频道
const result = this.rtcEngine.joinChannelWithToken(this.Token, '', '', '语聊房用户');
console.info('加入频道调用结果:', result);6. 结束纯音频互动
音频互动结束,需要离开房间并销毁引擎,按照下列步骤结束音视频互动。
调用
leaveChannel离会。调用
destroy销毁引擎,并释放相关资源。
this.rtcEngine.leaveChannel();
this.hasJoined = false;
AliRtcEngine.destroyInstance();
this.rtcEngine = null;7. (可选)观众上下麦
业务场景中,如果观众角色的用户想要推流,需要调用setClientRole将观众角色切换为主播角色。
// 切换为主播角色
this.rtcEngine.setClientRole(AliRtcClientRole.AliRtcClientRoleInteractive);
// 切换为观众角色
this.rtcEngine.setClientRole(AliRtcClientRole.AliRtcClientRoleLive);相关文档
有关音频的更多操作,例如耳返、音量和说话人回调等,请参考音频常用操作和配置。
设置人声效果,例如变声、美声、混响等,请参考设置变声、混响、美声。
如果需要播放背景音乐、伴奏音乐文件等,请参考播放与推流外部输入音频(包括音效、伴奏)。