361 lines
6.8 KiB
Markdown
361 lines
6.8 KiB
Markdown
# SellyCloudSDK
|
||
|
||
# 📘 SellyRTC iOS SDK 接入文档
|
||
|
||
本文档介绍如何使用 **SellyRTCSession** 快速集成一对一或多人音视频通话功能,包括基本接入、音视频控制、数据处理、事件回调、统计与 Token 更新机制。
|
||
|
||
---
|
||
|
||
## 📑 目录
|
||
1. [准备工作](#准备工作)
|
||
2. [快速开始](#快速开始)
|
||
- 创建 Session
|
||
- 设置本地/远端画面
|
||
- 配置视频参数
|
||
- 加入频道
|
||
- 结束通话
|
||
3. [常用功能](#常用功能)
|
||
- 开关音视频
|
||
- 切换摄像头
|
||
- 静音远端
|
||
- 音频输出控制
|
||
- 发送自定义消息
|
||
- Token 更新
|
||
4. [视频/音频帧处理](#视频音频帧处理)
|
||
5. [事件回调 (Delegate)](#事件回调-delegate)
|
||
6. [通话统计](#通话统计)
|
||
7. [Token 过期机制](#token-过期机制)
|
||
8. [常见问题](#常见问题)
|
||
|
||
---
|
||
|
||
# 🔧 准备工作
|
||
|
||
确保已正确集成 `SellyRTC.framework` 并导入头文件:
|
||
|
||
```objc
|
||
#import <SellyRTC/SellyRTC.h>
|
||
```
|
||
|
||
---
|
||
|
||
# 🚀 快速开始
|
||
|
||
## 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.
|