Files
SellyCloudSDK_Android_demo/docs/SellySDK_音视频通话接入文档_Android.md
2026-01-15 14:24:31 +08:00

9.1 KiB
Raw Blame History

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

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

快速开始

1. 创建引擎

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. 设置本地/远端画布

val localRenderer = SurfaceViewRenderer(this)
rtcEngine.setupLocalVideo(InteractiveVideoCanvas(localRenderer, userId))
val remoteRenderer = SurfaceViewRenderer(this)
rtcEngine.setupRemoteVideo(InteractiveVideoCanvas(remoteRenderer, remoteUserId))

3. 加入通话

val options = InteractiveChannelMediaOptions(callType = CallType.ONE_TO_ONE)
rtcEngine.joinChannel(
    token = token,
    channel = callId,
    userId = userId,
    options = options,
    tokenSecret = tokenSecret,
    tokenExpiresAtSec = tokenExpiresAtSec,
    tokenTtlSeconds = tokenTtlSeconds
)

结束通话:

rtcEngine.leaveChannel()

销毁引擎:

InteractiveRtcEngine.destroy(rtcEngine)

4. 进阶配置Demo 未覆盖)

4.1 InteractiveRtcEngineConfig 高级字段

val config = InteractiveRtcEngineConfig(
    context = applicationContext,
    appId = appId,
    defaultCallType = CallType.ONE_TO_ONE,
    defaultToken = token,
    kiwiRsName = kiwiRsName,
    signalingUrlPrefix = "https://",
    signalingUrlSuffix = "/signaling"
)

4.2 InteractiveChannelMediaOptions 订阅控制

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 并释放资源

常用功能

本地音视频控制

rtcEngine.enableLocalVideo(true)
rtcEngine.enableLocalAudio(false)

切换摄像头

rtcEngine.switchCamera()

音频输出(扬声器 / 听筒)

rtcEngine.setDefaultAudioRoutetoSpeakerphone(true)

发送自定义消息

rtcEngine.sendMessage("hello") { error ->
    // error == null 表示成功
}

按用户静音远端音频/视频

rtcEngine.muteRemoteAudioStream(remoteUserId, true)
rtcEngine.muteRemoteVideoStream(remoteUserId, true)

全量静音远端音视频Demo 未覆盖)

rtcEngine.muteAllRemoteAudioStreams(true)
rtcEngine.muteAllRemoteVideoStreams(true)

清理远端画布Demo 未覆盖)

rtcEngine.clearRemoteVideo(remoteUserId)

向指定用户发送消息Demo 未覆盖)

rtcEngine.sendMessage("hello", targetUserId) { error ->
    // error == null 表示成功
}

屏幕分享

val started = rtcEngine.startScreenShare(
    resultCode = resultCode,
    data = data,
    width = 720,
    height = 1280,
    fps = 15
)
rtcEngine.stopScreenShare()
val isSharing = rtcEngine.isScreenSharing()

Android 14+ 屏幕捕获需要前台服务Demo 使用 InteractiveForegroundService 处理)。


视频帧前后处理

rtcEngine.setCaptureVideoFrameInterceptor { frame ->
    // 在此处理美颜/滤镜,返回新的 frame
    frame
}
rtcEngine.setRenderVideoFrameInterceptor { frame, userId ->
    // 远端渲染前处理,返回 true 表示继续渲染
    true
}

Demo 中的美颜示例见:
example/src/main/java/com/demo/SellyCloudSDK/beauty/FuVideoFrameInterceptor.kt


事件回调EventHandler

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_tokensignaling_secret 进行本地生成

Token 过期处理

  • onTokenWillExpire / onTokenExpired 回调提示即将过期或已过期
  • 建议获取新 Token 并 重新 joinChannel

Token 续期接口Demo 未覆盖):

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+ 是否启动前台服务