# SellyRTC Android SDK 接入文档 本文档用于指导 **Android App 开发者** 快速接入 SellyRTC,完成一对一或多人实时音视频通话能力。 SDK 核心以 `InteractiveRtcEngine` 为中心,通过 `InteractiveRtcEngineEventHandler` 回调通话状态、用户事件、音视频状态及异常。 --- ## 目录 1. 准备工作 2. 快速开始 3. 基础通话流程 4. 常用功能 5. 屏幕分享 6. 视频帧前后处理 7. 事件回调(EventHandler) 8. 通话统计 9. Token 机制 10. 常见问题(FAQ) --- ## 准备工作 ### 1. 环境要求 - Android 8.0+(Demo `minSdk` 为 26) - 需真机运行(摄像头 / 麦克风) ### 2. 权限配置(AndroidManifest.xml) ```xml ``` --- ## 快速开始 ### 1. 创建引擎 ```kotlin val appId = getString(R.string.signaling_app_id) val token = getString(R.string.signaling_token).takeIf { it.isNotBlank() } val kiwiRsName = getString(R.string.signaling_kiwi_rsname).trim() val rtcEngine = InteractiveRtcEngine.create( InteractiveRtcEngineConfig( context = applicationContext, appId = appId, defaultToken = token, kiwiRsName = kiwiRsName ) ).apply { setEventHandler(eventHandler) setClientRole(InteractiveRtcEngine.ClientRole.BROADCASTER) setVideoEncoderConfiguration( InteractiveVideoEncoderConfig( width = 640, height = 480, fps = 20, minBitrateKbps = 150, maxBitrateKbps = 850 ) ) setDefaultAudioRoutetoSpeakerphone(true) } ``` > `InteractiveRtcEngineConfig` 与默认 token 配置见 `example/src/main/java/com/demo/SellyCloudSDK/interactive/InteractiveLiveActivity.kt`。 ### 2. 设置本地/远端画布 ```kotlin val localRenderer = SurfaceViewRenderer(this) rtcEngine.setupLocalVideo(InteractiveVideoCanvas(localRenderer, userId)) ``` ```kotlin val remoteRenderer = SurfaceViewRenderer(this) rtcEngine.setupRemoteVideo(InteractiveVideoCanvas(remoteRenderer, remoteUserId)) ``` ### 3. 加入通话 ```kotlin val options = InteractiveChannelMediaOptions(callType = CallType.ONE_TO_ONE) rtcEngine.joinChannel( token = token, channel = callId, userId = userId, options = options, tokenSecret = tokenSecret, tokenExpiresAtSec = tokenExpiresAtSec, tokenTtlSeconds = tokenTtlSeconds ) ``` 结束通话: ```kotlin rtcEngine.leaveChannel() ``` 销毁引擎: ```kotlin InteractiveRtcEngine.destroy(rtcEngine) ``` ### 4. 进阶配置(Demo 未覆盖) #### 4.1 InteractiveRtcEngineConfig 高级字段 ```kotlin val config = InteractiveRtcEngineConfig( context = applicationContext, appId = appId, defaultCallType = CallType.ONE_TO_ONE, defaultToken = token, kiwiRsName = kiwiRsName, signalingUrlPrefix = "https://", signalingUrlSuffix = "/signaling" ) ``` #### 4.2 InteractiveChannelMediaOptions 订阅控制 ```kotlin val options = InteractiveChannelMediaOptions( callType = CallType.GROUP, autoSubscribeAudio = true, autoSubscribeVideo = false ) ``` #### 4.3 InteractiveVideoEncoderConfig 更多参数 可选项(按需设置): - `codecType`:编码类型 - `bitrateMode`:码率控制模式 - `minBitrateKbps` / `maxBitrateKbps`:码率范围 - `orientationMode`:画面方向策略 - `degradationPreference`:弱网降级策略 - `mirrorMode`:镜像策略 --- ## 基础通话流程 1. 创建 `InteractiveRtcEngine` 2. 设置 `EventHandler` 3. 配置 `InteractiveVideoEncoderConfig` 4. 设置本地画布 `setupLocalVideo` 5. `joinChannel` 加入频道 6. `onUserJoined` 后设置远端画布 7. 通话中进行音视频控制 8. `leaveChannel` 并释放资源 --- ## 常用功能 ### 本地音视频控制 ```kotlin rtcEngine.enableLocalVideo(true) rtcEngine.enableLocalAudio(false) ``` ### 切换摄像头 ```kotlin rtcEngine.switchCamera() ``` ### 音频输出(扬声器 / 听筒) ```kotlin rtcEngine.setDefaultAudioRoutetoSpeakerphone(true) ``` ### 发送自定义消息 ```kotlin rtcEngine.sendMessage("hello") { error -> // error == null 表示成功 } ``` ### 按用户静音远端音频/视频 ```kotlin rtcEngine.muteRemoteAudioStream(remoteUserId, true) rtcEngine.muteRemoteVideoStream(remoteUserId, true) ``` ### 全量静音远端音视频(Demo 未覆盖) ```kotlin rtcEngine.muteAllRemoteAudioStreams(true) rtcEngine.muteAllRemoteVideoStreams(true) ``` ### 清理远端画布(Demo 未覆盖) ```kotlin rtcEngine.clearRemoteVideo(remoteUserId) ``` ### 向指定用户发送消息(Demo 未覆盖) ```kotlin rtcEngine.sendMessage("hello", targetUserId) { error -> // error == null 表示成功 } ``` --- ## 屏幕分享 ```kotlin val started = rtcEngine.startScreenShare( resultCode = resultCode, data = data, width = 720, height = 1280, fps = 15 ) ``` ```kotlin rtcEngine.stopScreenShare() ``` ```kotlin val isSharing = rtcEngine.isScreenSharing() ``` > Android 14+ 屏幕捕获需要前台服务(Demo 使用 `InteractiveForegroundService` 处理)。 --- ## 视频帧前后处理 ```kotlin rtcEngine.setCaptureVideoFrameInterceptor { frame -> // 在此处理美颜/滤镜,返回新的 frame frame } ``` ```kotlin rtcEngine.setRenderVideoFrameInterceptor { frame, userId -> // 远端渲染前处理,返回 true 表示继续渲染 true } ``` > Demo 中的美颜示例见: > `example/src/main/java/com/demo/SellyCloudSDK/beauty/FuVideoFrameInterceptor.kt` --- ## 事件回调(EventHandler) ```kotlin val eventHandler = object : InteractiveRtcEngineEventHandler { override fun onJoinChannelSuccess(channel: String, userId: String, code: Int) {} override fun onLeaveChannel(durationSeconds: Int) {} override fun onUserJoined(userId: String, code: Int) {} override fun onUserLeave(userId: String, code: Int) {} override fun onConnectionStateChanged(state: InteractiveConnectionState, reason: Int, userId: String?) {} override fun onMessageReceived(message: String, userId: String?) {} override fun onError(code: String, message: String) {} override fun onTokenWillExpire(token: String?, expiresAt: Long) {} override fun onTokenExpired(token: String?, expiresAt: Long) {} override fun onLocalVideoStats(stats: InteractiveStreamStats) {} override fun onRemoteVideoStats(stats: InteractiveStreamStats) {} override fun onDuration(durationSeconds: Long) {} override fun onRemoteVideoEnabled(enabled: Boolean, userId: String?) {} override fun onRemoteAudioEnabled(enabled: Boolean, userId: String?) {} override fun onStreamStateChanged(peerId: String, state: RemoteState, code: Int, message: String?) {} } ``` --- ## 通话统计 `InteractiveStreamStats` 常用字段: - width / height - fps - videoBitrateKbps / audioBitrateKbps - rttMs - videoCodec / audioCodec --- ## Token 机制 ### Token 来源 - 业务侧服务端生成 Token 并下发 - Demo 可在 `strings.xml` 配置 `signaling_token` 或 `signaling_secret` 进行本地生成 ### Token 过期处理 - `onTokenWillExpire` / `onTokenExpired` 回调提示即将过期或已过期 - 建议获取新 Token 并 **重新 joinChannel** Token 续期接口(Demo 未覆盖): ```kotlin rtcEngine.renewToken(newToken, expiresAtSec) ``` --- ## 更多 API 速览(含 Demo 未覆盖) 引擎创建与销毁: - `InteractiveRtcEngine.create(config)`:创建引擎 - `InteractiveRtcEngine.destroy(engine)` / `engine.destroy()`:释放引擎 通话控制: - `setEventHandler(handler)`:设置事件回调 - `setClientRole(role)`:设置角色(主播/观众) - `setVideoEncoderConfiguration(config)`:设置编码参数 - `setDefaultAudioRoutetoSpeakerphone(true/false)`:设置音频输出 - `joinChannel(...)` / `leaveChannel()`:加入 / 离开频道 本地与远端控制: - `setupLocalVideo(canvas)` / `setupRemoteVideo(canvas)`:设置画布 - `clearRemoteVideo(userId)`:清理远端画面 - `enableLocalVideo(true/false)` / `enableLocalAudio(true/false)`:开关本地音视频 - `muteRemoteAudioStream(userId, true/false)` / `muteRemoteVideoStream(userId, true/false)`:按用户静音 - `muteAllRemoteAudioStreams(true/false)` / `muteAllRemoteVideoStreams(true/false)`:全量静音 - `switchCamera()`:切换摄像头 帧处理与屏幕共享: - `setCaptureVideoFrameInterceptor(...)`:采集前帧处理 - `setRenderVideoFrameInterceptor(...)`:渲染前帧处理 - `startScreenShare(...)` / `stopScreenShare()` / `isScreenSharing()`:屏幕共享 消息与 Token: - `sendMessage(message, targetUserId, callback)`:发送消息(`targetUserId` 可为空) - `renewToken(newToken, expiresAtSec)`:续期 Token --- ## 常见问题(FAQ) ### Q:远端画面不显示? 1. 是否设置了正确的 `remoteUserId` 2. 是否在 `onUserJoined` 后调用 `setupRemoteVideo` 3. 远端是否关闭了视频 ### Q:加入频道失败? 1. 检查 `signaling_app_id` 是否正确 2. Token 是否为空或已过期 3. 网络是否受限 ### Q:屏幕分享失败? 1. 是否已获取 `MediaProjection` 授权 2. Android 14+ 是否启动前台服务