声网预研

7 阅读14分钟

概念及流程

实时视频概念

首先,你需要了解以下有关音视频实时互动的基础概念:

  • 频道:用于传输数据的通道,在同一个频道内的用户可以进行实时互动。
  • 主播:可以在频道内发布音视频,同时也可以订阅其他主播发布的音视频。
  • 观众:可以在频道内订阅音视频,不具备发布音视频权限。

基本工作流程:

  1. 所有用户调用 joinChannel 加入频道,并根据需要设置用户角色:
    • 互动直播:如果用户需要在频道中发流,则设为主播;如果用户只需要收流,则设为观众。
    • 视频通话:将所有的用户角色都为主播。
  1. 加入频道后,不同角色的用户具备不同的行为:
    • 所有用户默认都可以接收频道中的音视频流。
    • 主播可以在频道内发布音视频流。
    • 观众如果需要发流,可在频道内调用 setClientRole 方法修改用户角色,使其具备发流权限。

声网RTC方案有两个重要概念:频道及角色,频道控制手机与设备加入同一个频道实现连接,角色控制音视频流的发送权,类似于MQTT聊天室,两台设备都订阅同一个主题即可发消息互动。

直播流程

直播

流程

方案

IPC场景只涉及 IPC设备端发送视频,APP端接收。

建立连接需要先唤醒设备,下发视频连接所需参数。

RTC数据:channelId、token、appId,uid,video_type(=live),参数及规则由服务器提供。

需要服务器提供开始直播的接口,下发数据给APP和设备。

  • App发起唤醒,服务器下发唤醒指令
  • App发起直播连接(ESN,...),服务器下发RTC数据给设备,并返回RTC数据给App
  • 设备作为主播加入该频道
  • App拿到RTC数据后,App作为观众加入该频道
  • 接收加入频道成功的事件,连接建立完成
  • 开始实时音视频互动
  • App发起对讲,先设置用户角色为主播,再发送音频
  • App结束连接,App退出频道,释放RTC
  • 设备等所有App用户退出频道,再退出频道,释放RTC

连接并发数量

RTC SDK 对实时音视频并发频道数量无限制,支持单个频道内百万用户同时在线。

默认情况下,SDK 在单个频道内支持最多 17 位用户同时发送音视频流,32 位用户同时发送纯音频流。需要注意的是,如果频道内已有 17 位用户发送视频流,即使这些用户没有发送音频,也只能再有 15 位用户发送音频流

App指定设备端音频编码

音频编码支持情况

回声消除、降噪

EMMC回放

官网没有回放API,需要定义方案各端(App&服务器&设备)自行实现:

回放的视频连接流程与直播类似,主要是需要告诉设备播放某个视频,参数:start_time(视频的起始时间戳)

RTC数据:channelId、token、appId,uid,video_type(=playback),start_time,参数及规则由服务器提供。

需要服务器提供开始直播的接口,下发数据给APP和设备。

  • App发起唤醒,服务器下发唤醒指令
  • App发起回放连接(ESN,start_time,...),服务器下发RTC数据给设备,并返回RTC数据给App
  • 设备作为主播加入该频道
  • App拿到RTC数据后,作为观众加入该频道
  • App接收加入频道成功的事件,连接建立完成
  • App渲染音视频画面
  • App结束连接,App退出频道,释放RTC
  • 设备等所有App用户退出频道,再退出频道,释放RTC

视频功能需求支持情况

SDK支持的功能:

  • 视频直播
    • 支持一对多视频,百万级同时在线,需要处理连接数量限制(3个?)
    • 默认使用声网内置播放器即可,不需要进行音视频流处理
    • 支持自定义渲染视频画面(原生可以复用KIoTVideo视频渲染)
    • 支持音视频流拦截处理
  • 切换清晰度
    • 方案1:支持同源多流 setSimulcastConfig
    • 方案2:多路分辨率视频流 【ABR 支持根据收流端的订阅设置发布指定层级的视频流。默认不开启,如需要请联系技术支持
    • 方案:通过自定义消息通知设备切换清晰度
  • 对讲
    • 支持多路对讲,需要处理对讲数量限制(1对1?)
    • 默认使用声网内置采集即可,支持设置音频采集格式aac、g711、opus等
    • 采样数据大小为 20ms 一帧
    • 也支持自定义采集音频(原生可以复用KIoTVideo音频采集)
  • 变声

setAudioEffectPreset

    • VOICE_CHANGER_EFFECT_UNCLE:大叔音
    • VOICE_CHANGER_EFFECT_OLDMAN:老年音 / 老爷爷音
    • VOICE_CHANGER_EFFECT_BOY:男孩音 / 正太音
    • VOICE_CHANGER_EFFECT_SISTER:姐姐音
    • VOICE_CHANGER_EFFECT_GIRL:女孩音 / 萝莉音
    • VOICE_CHANGER_EFFECT_PIGKING:猪王音 / 猪八戒音(偏搞怪)
    • VOICE_CHANGER_EFFECT_HULK:绿巨人音 / 浩克音
  • 录屏(app本地录屏)

startRecording

    • 支持录制Mp4
    • 支持设置录制时长
  • 截图 (app本地截图)

takeSnapshot

    • 支持设置截图时机(编码前、后)
  • 码率

onRemoteVideoStats(RemoteVideoStats stats)

SDK不支持的功能,需自行开发实现:

  • 视频回放
    • 类似直播流程,三端实现
  • 视频画面模式切换
    • 服务器给设置接口,通知设备切换画面
  • 视频主副摄切换
    • App开发适配
  • 视频画面旋转、缩放
    • App开发适配,原生可以用KIoTVideo的渲染视图方案

传输自定义数据

自定义数据流,可以满足一些场景的协议数据交互

createDataStream 后,可以使用 sendStreamMessage 向频道内的所有用户发送数据流消息。

限制:

  • 该方法仅适用于主播角色。
  • 每个频道内的客户端实例最多可同时拥有 5 个数据通道,所有数据通道共享的总包比特率上限为 30 KB/s。
  • 每个数据通道每秒最多可发送 60 个数据包,每个数据包最大为 1 KB。
API描述
createDataStream [1/2]创建一个数据流,用于提升数据传输的可靠性和顺序性。
createDataStream [2/2]创建一个数据流。
createDataStreamEx [2/2]创建一个数据流。
sendStreamMessage发送数据流消息。
sendStreamMessageEx发送数据流消息。
onStreamMessage远端用户发送数据流时的回调。
onStreamMessageErroronStreamMessageError回调:本地用户未收到远端用户发送的数据流时触发。

播放器格式及协议

声网的媒体播放器支持

视频编码格式

  • H.263、H.264、H.265、MPEG4、MPEG2、RMVB、Theora、VP3、VP8、AVS、WMV

音频编码格式

  • WAV、MP2、MP3、AAC、OPUS、FLAC、Vorbis、AMR-NB、AMR-WB、WMA v1、WMA v2

容器格式

  • WAV、FLAC、OGG、MOV、ASF、FLV、MP3、MP4、MPEG-TS、Matroska (MKV)、AVI、ASS、CONCAT、DTS、AVS

支持的协议

  • HTTP、HTTPS、RTMP、HLS、RTP、RTSP

官方API Demo

Android

github.com/Shengwang-C…

IOS

github.com/Shengwang-C…

RN

github.com/AgoraIO-Ext…

相关API

onConnectionLostonConnectionLost回调:当 SDK 在连接中断后 10 秒内无法重新连接到声网边缘服务器时触发
onConnectionStateChanged监控频道连接状态的变化
setVoiceConversionPreset设置 SDK 预设的变声效果。
enableVideo启用视频模块。
pushExternalAudioFrame将外部音频帧推送到 SDK。
setParameters通过配置 JSON 选项,为 SDK 提供技术预览功能或特殊定制。
setClientRole [1/2]设置客户端实例的用户角色。
onClientRoleChanged用户角色或观众延迟级别发生变化回调。
joinChannel [1/2]加入一个频道。
setChannelProfile设置频道场景。
onUserJoined远端用户或主播加入频道回调。
onUserOffline远端用户或主播离开频道时触发的回调。
leaveChannel [1/2]离开频道。
onLeaveChannel用户离开频道回调。
setVideoScenario设置视频应用场景。
setRemoteDefaultVideoStreamType [1/2]设置默认订阅的视频流类型。
setRemoteVideoStreamType [1/2]设置要订阅的视频流类型。
onFirstRemoteVideoFrame远端视频首帧显示回调。
onRemoteVideoStateChanged远端视频状态发生改变回调。
onVideoSizeChanged指定用户的视频尺寸或旋转信息发生变化回调。
setVideoRenderMode设置媒体播放器的渲染模式。
setupRemoteVideo初始化远端视频视图。
getRotationApplied回调在每次 SDK 接收到视频帧时触发,用于设置是否旋转采集的视频。
getVideoFormatPreference设置 SDK 输出的原始视频数据格式
getVideoFrameProcessMode每次 SDK 接收到视频帧时触发,并提示你设置视频帧的处理模式。
registerVideoFrameObserver注册原始视频帧观察器对象。
registerAudioFrameObserver注册音频帧观测器对象。
onPreEncodeVideoFrame每次 SDK 接收到编码前视频帧时触发该回调。
onRenderVideoFrame远端用户发送视频帧时触发的回调。
registerVideoEncodedFrameObserver注册用于接收编码后视频帧的观察器对象。
onEncodedVideoFrameReceived接收端收到远端编码视频帧回调
onPlayerEvent播放器事件回调
onPlayerStateChanged播放状态发生改变回调。
onPositionChanged播放进度回调。
createMediaRecorder创建用于音视频录制的录制器实例。
startRecording开始录制音频和视频流。
stopRecording停止录制音视频流。
onRecorderStateChanged录制状态发生变化时的回调。
setMediaRecorderObserver注册一个用于音视频录制的回调观察者。
takeSnapshot [1/2]截取指定用户的视频流快照并保存为 JPG 图像
onSnapshotTaken视频截图结果回调。
getConnectionState获取 SDK 当前的连接状态。
getNetworkType获取本地网络连接类型。
enableAudio启用音频模块。
disableAudio禁用音频模块。
enableVideo启用视频模块。
disableVideo关闭视频模块。
enableLocalAudio启用或关闭本地音频采集功能。
enableLocalVideo启用或禁用本地视频采集。
onUserEnableVideo远端用户启用或关闭视频模块的回调。

参考IPC集成方案

泛IPC集成方案.pdf

SDK错误码

错误码适用于以下平台的声网 RTC v4.x SDK:

  • 原生平台:Android、iOS、macOS、Windows、HarmonyOS NEXT。
  • 第三方框架(即基于原生平台封装的第三方平台):Electron、Unity、React Native、Flutter、Unreal。

声网 SDK 在运行过程中,可能通过如下方式返回错误码:

  • 在方法调用失败的返回值中,返回一个负数,这个负数就对应着错误码的正数。
  • 通过 onError 回调报告错误码。

通用错误码

枚举值说明
1一般性的错误(没有明确归类的错误原因)。请重新调用方法。
2方法中设置了无效的参数。例如指定的频道名中含有非法字符。请重新设置参数。
3SDK 尚未准备好。一般有以下原因:- RtcEngine 初始化失败。请重新初始化 RtcEngine
  • 调用方法时用户尚未加入频道。请检查方法的调用逻辑。
  • 调用 ratecomplain 方法时用户尚未离开频道,请检查方法的调用逻辑。
  • 音频模块未开启。
  • 程序集不完整。 | | 4 | RtcEngine 当前状态不支持该操作。一般有以下原因:- 使用内置加密时,设置的加密模式不正确。
  • 加载外部加密库失败。 请检查加密的枚举值是否正确,或重新加载外部加密库。 | | 5 | 方法调用被拒绝。一般有以下原因:- RtcEngine 初始化失败。请重新初始化 RtcEngine
  • 在加入频道时,将频道名设为空字符 ""。请重新设置频道名。
  • 多频道场景下,在调用 joinChannel 方法加入频道时,设置的频道名已存在。请重新设置频道名。
  • 多频道场景下,在调用 joinChannelEx 方法加入频道时,设置的频道名已存在。请重新设置频道名。 | | 6 | 缓冲区大小不足以存放返回的数据。 | | 7 | RtcEngine尚未初始化就调用方法。请确认在调用该方法前已创建 RtcEngine对象并完成初始化。 | | 8 | 当前状态无效。请查看 SDK 回调日志了解具体原因。 | | 9 | 没有操作权限。请检查用户是否授予了 App 音视频设备的使用权限。 | | 10 | 方法调用超时。有些方法调用需要 SDK 返回结果,如果 SDK 处理事件过长,超过 10 秒没有返回,会出现此错误。 | | 17 | 加入频道被拒绝。一般有以下原因:- 用户已经在频道中。声网推荐通过 onConnectionStateChanged 回调判断用户是否在频道中。除非收到 CONNECTION_STATE_DISCONNECTED(1) 状态,否则请勿再次调用该方法加入频道。
  • 用户在调用 startEchoTest 进行通话测试时,未调用 stopEchoTest 结束当前测试,就尝试加入频道。开始通话测试后,需要先调用 stopEchoTest 结束当前测试,再加入频道。 | | 18 | 离开频道失败。一般有以下原因:- 用户已离开频道,再次调用退出频道的方法,如 leaveChannel 时,会返回此错误。停止调用该方法即可。
  • 用户尚未加入频道,就调用 leaveChannel 等退出频道的方法。这种情况下无需额外操作。 | | 19 | 资源已被占用,不能重复使用。 | | 20 | SDK 放弃请求,可能由于请求的次数太多。 | | 21 | Windows 下特定的防火墙设置导致 RtcEngine初始化失败然后崩溃。 | | 22 | SDK 分配资源失败,可能由于 App 占用资源过多或系统资源耗尽。 | | 101 | 不是有效的 App ID。请更换有效的 App ID 重新加入频道。 | | 102 | 不是有效的频道名。可能的原因是设置的参数数据类型不正确。请更换有效的频道名重新加入频道。 | | 103 | 无法获取当前区域的服务器资源。请在初始化 RtcEngine时尝试指定其他区域。 | | 109 | 当前使用的 Token 过期,不再有效。请在服务端申请生成新的 Token,并调用 renewToken 更新 Token。废弃该错误码已废弃。请改用 onConnectionStateChanged 回调中的 CONNECTION_CHANGED_TOKEN_EXPIRED(9)。 | | 110 | Token 无效。一般有以下原因:- 在声网控制台中启用了 App 证书,但未使用 App ID + Token 鉴权。当项目启用了 App 证书,就必须使用 Token 鉴权。
  • 生成 Token 时填入的 uid 字段,和用户加入频道时填入的 uid 不一致。废弃该错误码已废弃。请改用 onConnectionStateChanged 回调中的 CONNECTION_CHANGED_INVALID_TOKEN(8)。 | | 111 | 网络连接中断。SDK 在和服务器建立连接后,失去网络连接超过 4 秒。 | | 112 | 网络连接丢失。 网络连接中断,且 SDK 无法在 10 秒内连接服务器。 | | 119 | 用户切换角色失败,请尝试重新加入频道。 | | 120 | 解密失败。可能是用户加入频道时使用了错误的密码。请检查用户加入频道时填入的密码,或引导用户尝试重新加入频道。 | | 121 | 该用户 ID 无效。 | | 123 | 此用户被服务器禁止。当用户被服务端踢出时会报告这个错误。 | | 134 | 无效的 user account,可能是因为设置了无效的参数。 |

音频相关错误码

枚举值说明
1005音频设备出现错误(未指明何种错误)。请检查音频设备是否被其他应用占用,或者尝试重新进入频道。
1008初始化播放设备出错。请检查播放设备是否被其他应用占用,或者尝试重新进入频道。
1009启动播放设备出错。请检查播放设备是否正常。
1010停止播放设备出错。
1011初始化录音设备出错。请检查录音设备是否正常,或者尝试重新进入频道。
1012启动录音设备出错。请检查录音设备是否正常。
1013停止录音设备出错。

数据流相关错误码

枚举值说明
113调用 sendStreamMessage方法时,用户不在频道内。
114调用 sendStreamMessage时,发送的数据长度大于 1024 个字节。
115调用 sendStreamMessage时,发送数据的频率超过限制(6 KB/s)。
116调用 createDataStream时,创建的数据流超过限制(5 个)。
117当发送端调用 createDataStream[1/2] 设置 reliabletrue,或调用 createDataStream[2/2] 设置DataStreamConfig.orderedtrue时,若接收端在 5 秒内未收到数据,或检测到数据丢失,将在接收端触发 onStreamMessageError回调并返回错误码 117

其他错误码

枚举值说明
130SDK 不支持将加密过的流推到 CDN 上。
1001加载媒体引擎失败。
1501没有摄像头使用权限。请检查是否已经打开摄像头权限。