# SellyCloudSDK # 📘 SellyRTC iOS SDK 接入文档 本文档介绍如何使用 **SellyRTCSession** 快速集成一对一或多人音视频通话功能,包括基本接入、音视频控制、数据处理、事件回调、统计与 Token 更新机制。 --- ## 📑 目录 1. [准备工作](#准备工作) 2. [快速开始](#快速开始) - 创建 Session - 设置本地/远端画面 - 配置视频参数 - 加入频道 - 结束通话 3. [常用功能](#常用功能) - 开关音视频 - 切换摄像头 - 静音远端 - 音频输出控制 - 发送自定义消息 - Token 更新 4. [视频/音频帧处理](#视频音频帧处理) 5. [事件回调 (Delegate)](#事件回调-delegate) 6. [通话统计](#通话统计) 7. [Token 过期机制](#token-过期机制) 8. [常见问题](#常见问题) --- # 🔧 准备工作 确保已正确集成 `SellyRTC.framework` 并导入头文件: ```objc #import ``` --- # 🚀 快速开始 ## 1. 创建 Session ```objc // YES = 单聊(P2P) NO = 多人会议 self.session = [[SellyRTCSession alloc] initWithType:YES]; self.session.delegate = self; ``` ⚠️ `init` 和 `new` 已禁用,必须使用 `initWithType:`。 --- ## 2. 设置本地 & 远端画布 ```objc // 本地视频 SellyRtcVideoCanvas *local = [SellyRtcVideoCanvas new]; local.view = self.localView; [self.session setLocalCanvas:local]; // 远端视频(多人时 userId 必填) SellyRtcVideoCanvas *remote = [SellyRtcVideoCanvas new]; remote.view = self.remoteView; remote.userId = @"remoteUser"; [self.session setRemoteCanvas:remote]; ``` > 多人会议:可多次调用 `setRemoteCanvas:`。 > SDK 根据 `canvas.userId` 将对应远端视频渲染到指定 view。 --- ## 3. 配置视频参数(可选) 必须在加入频道前配置: ```objc SellyRTCVideoConfiguration *config = [SellyRTCVideoConfiguration defaultConfig]; config.width = 720; config.height = 1280; config.frameRate = 24; self.session.videoConfig = config; ``` --- ## 4. 加入频道 / 发起通话 ```objc [self.session startWithChannelId:@"room123" token:@"xxxx-token"]; ``` --- ## 5. 结束通话 ```objc [self.session end]; ``` --- # 🎛 常用功能 ## 开/关本地视频 ```objc [self.session enableLocalVideo:NO]; [self.session enableLocalVideo:YES]; ``` ## 开/关本地音频采集 ```objc [self.session enableLocalAudio:NO]; [self.session enableLocalAudio:YES]; ``` ## 切换前后摄像头 ```objc [self.session switchCamera]; ``` ## 静音远端音频 ```objc // P2P 模式 userId 可传 nil [self.session muteRemoteAudioStream:nil mute:YES]; ``` ## 控制音频输出(扬声器/听筒) ```objc [self.session setAudioOutput:AVAudioSessionPortOverrideSpeaker]; ``` 如有耳机 / 蓝牙设备,建议外部使用 `AVRoutePickerView`。 ## 发送自定义消息 ```objc [self.session sendMessage:@"Hello World" completion:^(NSError *error) { if (error) NSLog(@"发送失败: %@", error); }]; ``` ## 更新 Token ```objc [self.session renewToken:newToken]; ``` --- # 🎥 视频 / 音频帧处理 ## 视频采集前处理(美颜、滤镜、自定义 GPU) ```objc - (CVPixelBufferRef)rtcSession:(SellyRTCSession *)session onCaptureVideoFrame:(CVPixelBufferRef)pixelBuffer { // 1. 执行美颜、贴纸、旋转等处理 // 2. 返回处理后的 pixelBuffer return pixelBuffer; } ``` ## 远端视频解码后回调(AI 分析、自定义渲染) ```objc - (BOOL)rtcSession:(SellyRTCSession *)session onRenderVideoFrame:(SellyRTCVideoFrame *)videoFrame userId:(NSString *)userId { // 返回 YES:继续渲染 // 返回 NO:丢弃该帧 return YES; } ``` --- # 📡 事件回调 (Delegate) ```objc #pragma mark - SellyRTCSessionDelegate ``` ## 通话错误(不可恢复) ```objc - (void)rtcSession:(SellyRTCSession *)session onError:(NSError *)error; ``` ## 远端启用/关闭音视频 ```objc - (void)rtcSession:(SellyRTCSession *)session videoEnabled:(BOOL)enabled userId:(NSString *)userId; - (void)rtcSession:(SellyRTCSession *)session audioEnabled:(BOOL)enabled userId:(NSString *)userId; ``` ## 收到消息 ```objc - (void)rtcSession:(SellyRTCSession *)session didReceiveMessage:(NSString *)message userId:(NSString *)userId; ``` ## 连接状态变化 ```objc - (void)rtcSession:(SellyRTCSession *)session connectionStateChanged:(SellyRTCConnectState)state userId:(NSString *)userId; ``` 连接状态包括: ``` Disconnected Connecting Connected Reconnecting Failed ``` ## 用户加入/离开 ```objc - (void)rtcSession:(SellyRTCSession *)session onUserJoined:(NSString *)userId; - (void)rtcSession:(SellyRTCSession *)session onUserLeave:(NSString *)userId; ``` ## 通话时长 ```objc - (void)rtcSession:(SellyRTCSession *)session onDuration:(NSInteger)duration; ``` --- # 📊 通话统计信息 ```objc - (void)rtcSession:(SellyRTCSession *)session onStats:(SellyRTCP2pStats *)stats userId:(NSString *)userId; ``` 可获取: - 上下行码率 - 帧率 - 丢包率 - RTT - 解码帧数等 --- # 🔑 Token 过期机制 ## Token 即将过期 ```objc - (void)rtcSession:(SellyRTCSession *)session tokenWillExpire:(NSString *)token; ``` 业务应立即向服务器请求新 Token: ```objc [self.session renewToken:newToken]; ``` ## Token 已过期(通话仍继续) ```objc - (void)rtcSession:(SellyRTCSession *)session tokenExpired:(NSString *)token; ``` ⚠️ 过期后通话不受影响,但**断网重连会失败**,务必及时更新 Token。 --- # ❓ 常见问题 ### Q1:多人远端画面如何渲染? 重复调用: ```objc SellyRtcVideoCanvas *canvas = [SellyRtcVideoCanvas new]; canvas.view = remoteViewX; canvas.userId = @"userX"; [self.session setRemoteCanvas:canvas]; ``` SDK 会根据 `userId` 做路由。 --- ### Q2:远端画面不显示? 检查: - remoteCanvas.view 是否正确添加 - remoteCanvas.userId 是否一致 - 是否重复 addSubview 覆盖 - 是否调用了 `setRemoteCanvas:` --- ### Q3:如何做画中画 (PiP)? 将本地 + 远端视频放入一个 containerView: ```text [container addSubview:remoteView] [container addSubview:localView] // 小窗 ``` 并使用: ```objc AVPictureInPictureControllerContentSource *source = [[AVPictureInPictureControllerContentSource alloc] initWithActiveVideoCallSource:sampleBufferLayer contentView:container]; ``` --- # 🎉 完成 您已完成 SellyRTC 的全部集成内容。 如需更多帮助,可继续咨询:"" ## Author Caleb, liaoqiang1123@gmail.com ## License SellyCloudSDK is available under the MIT license. See the LICENSE file for more info.