412 lines
7.6 KiB
Markdown
412 lines
7.6 KiB
Markdown
# Selly Live SDK 推拉流接入文档(iOS)
|
||
|
||
> 统一 SDK 名称:**SellyCloudSDK**
|
||
> 本文档适用于 iOS 客户端,面向对外集成方与内部使用。
|
||
|
||
---
|
||
|
||
## 1. 概述
|
||
|
||
Selly Live SDK 提供完整的音视频直播能力,支持 **推流(直播发布)** 与 **拉流(直播播放)** 两大核心场景,适用于泛直播、互动直播、实时音视频等业务。
|
||
|
||
### 主要能力
|
||
|
||
- 支持 **RTMP / RTC** 推流与播放模式
|
||
- 高性能音视频采集与编码
|
||
- 灵活的视频参数配置(分辨率 / 帧率 / 码率)
|
||
- 推流状态与统计回调
|
||
- 拉流播放状态与错误回调
|
||
- 支持视频帧回调,便于接入美颜 / 滤镜 / 水印
|
||
- 基于 **Token 的安全鉴权机制**
|
||
|
||
---
|
||
|
||
## 2. 系统要求
|
||
|
||
- iOS 13.0 及以上
|
||
- Xcode 11.0 及以上
|
||
- 需在真机环境运行(音视频采集限制)
|
||
|
||
---
|
||
|
||
## 3. SDK 集成
|
||
|
||
### 3.1 引入 SDK
|
||
|
||
```objc
|
||
#import <SellyCloudSDK/SellyCloudManager.h>
|
||
```
|
||
|
||
### 3.2 权限配置(Info.plist)
|
||
|
||
推流场景必须配置以下权限:
|
||
|
||
```xml
|
||
<key>NSCameraUsageDescription</key>
|
||
<string>需要访问摄像头用于直播</string>
|
||
<key>NSMicrophoneUsageDescription</key>
|
||
<string>需要访问麦克风用于直播</string>
|
||
```
|
||
|
||
> 仅拉流播放场景不需要麦克风权限,请避免触发采集相关接口。
|
||
|
||
---
|
||
|
||
## 4. Token 鉴权机制(重点)
|
||
|
||
### 4.1 Token 基本说明
|
||
|
||
Selly Live SDK 的 **推流与拉流均采用 Token 鉴权机制**。
|
||
Token 由业务服务端生成并下发,SDK 仅负责使用 Token 建立连接。
|
||
|
||
### 4.2 Token 注入方式
|
||
|
||
Token 通过 **类属性** 注入:
|
||
|
||
| 场景 | 设置位置 |
|
||
|----|----|
|
||
| 推流 | `SellyLiveVideoPusher.token` |
|
||
| 拉流 | `SellyLiveVideoPlayer.token` |
|
||
|
||
**说明:**
|
||
|
||
- Token **不拼接到 URL**
|
||
- Token **不绑定 streamId**
|
||
- SDK 内部在建立连接时自动携带当前 Token
|
||
|
||
---
|
||
|
||
### 4.3 Token 设置时机(强约束)
|
||
|
||
#### 推流
|
||
|
||
必须在以下接口调用 **之前** 设置:
|
||
|
||
- `startLiveWithUrl:`
|
||
- `startLiveWithStreamId:`
|
||
|
||
#### 拉流
|
||
|
||
必须在以下接口调用 **之前** 设置:
|
||
|
||
- `prepareToPlay`
|
||
- `play`
|
||
|
||
> ⚠️ 在连接建立后修改 Token,不会影响当前连接。
|
||
|
||
---
|
||
|
||
### 4.4 Token 刷新机制说明
|
||
|
||
- SDK **不提供 Token 自动刷新机制**
|
||
- SDK **不会主动请求或续期 Token**
|
||
- 业务层可在任意时刻 **重新设置 token 属性**
|
||
|
||
当 Token 过期,推荐流程:
|
||
|
||
1. 业务侧向服务端获取新 Token
|
||
2. 调用 `pusher.token = newToken` / `player.token = newToken`
|
||
3. 停止并重新开始推流 / 拉流流程
|
||
|
||
---
|
||
|
||
### 4.5 Token 失效表现
|
||
|
||
| 场景 | 表现 |
|
||
|----|----|
|
||
| Token 无效 | 建立连接失败,触发错误回调 |
|
||
| Token 过期 | 推 / 拉中断,进入 Failed 状态 |
|
||
| 鉴权失败 | `onError:` 回调 |
|
||
|
||
---
|
||
|
||
## 5. 推流接入详解
|
||
|
||
### 5.1 创建推流实例
|
||
|
||
```objc
|
||
SellyLiveVideoPusher *pusher =
|
||
[[SellyLiveVideoPusher alloc] initWithLiveMode:SellyLiveMode_RTMP];
|
||
pusher.delegate = self;
|
||
```
|
||
|
||
> 必须使用 `initWithLiveMode:` 初始化。
|
||
|
||
---
|
||
|
||
### 5.2 设置推流 Token(必须)
|
||
|
||
```objc
|
||
pusher.token = pushToken;
|
||
```
|
||
|
||
---
|
||
|
||
### 5.3 视频参数配置
|
||
|
||
```objc
|
||
SellyLiveVideoConfiguration *videoConfig =
|
||
[SellyLiveVideoConfiguration defaultConfiguration];
|
||
|
||
videoConfig.videoSize = SellyRTCVideoResolution1280x720;
|
||
videoConfig.videoFrameRate = 25;
|
||
videoConfig.videoMinFrameRate = 15;
|
||
videoConfig.videoBitRate = 1000 * 1024;
|
||
videoConfig.videoMinBitRate = 500 * 1024;
|
||
videoConfig.videoMaxKeyframeInterval = 50;
|
||
videoConfig.outputImageOrientation = UIInterfaceOrientationPortrait;
|
||
```
|
||
|
||
#### 分辨率枚举
|
||
|
||
- 480x360
|
||
- 640x480
|
||
- 960x540
|
||
- 1280x720
|
||
|
||
---
|
||
|
||
### 5.4 开始采集
|
||
|
||
```objc
|
||
[pusher startRunning:AVCaptureDevicePositionFront
|
||
videoConfig:videoConfig
|
||
audioConfig:nil];
|
||
```
|
||
|
||
采集能力说明:
|
||
|
||
- 摄像头控制:`startCamera / stopCamera`
|
||
- 麦克风控制:`startMicrophone / stopMicrophone`
|
||
- 摄像头切换:`switchCameraPosition:`
|
||
|
||
---
|
||
|
||
### 5.5 开始推流
|
||
|
||
```objc
|
||
NSError *error = [pusher startLiveWithUrl:pushUrl];
|
||
if (error) {
|
||
NSLog(@"推流失败: %@", error);
|
||
}
|
||
```
|
||
|
||
或:
|
||
|
||
```objc
|
||
[pusher startLiveWithStreamId:streamId];
|
||
```
|
||
|
||
---
|
||
|
||
### 5.6 停止推流
|
||
|
||
```objc
|
||
[pusher stopLive:^(NSError * _Nullable error) {
|
||
NSLog(@"推流已停止");
|
||
}];
|
||
```
|
||
|
||
---
|
||
|
||
### 5.7 推流回调说明
|
||
|
||
#### 状态回调
|
||
|
||
```objc
|
||
- (void)pusher:(SellyLiveVideoPusher *)pusher
|
||
liveStatusDidChanged:(SellyLiveStatus)status;
|
||
```
|
||
|
||
状态枚举说明:
|
||
|
||
- Idle:未开始
|
||
- Connecting:连接中
|
||
- Publishing:推流中
|
||
- Reconnecting:重连中
|
||
- Stopped:已停止
|
||
- Failed:失败
|
||
|
||
---
|
||
|
||
#### 错误回调
|
||
|
||
```objc
|
||
- (void)pusher:(SellyLiveVideoPusher *)pusher
|
||
onError:(NSError *)error;
|
||
```
|
||
|
||
---
|
||
|
||
#### 推流统计回调
|
||
|
||
```objc
|
||
- (void)pusher:(SellyLiveVideoPusher *)pusher
|
||
onStatisticsUpdate:(SellyLivePusherStats *)stats;
|
||
```
|
||
|
||
统计字段包括:
|
||
|
||
- fps
|
||
- videoBitrate / audioBitrate
|
||
- rtt
|
||
- netSpeed
|
||
- cpu 使用率
|
||
|
||
---
|
||
|
||
### 5.8 视频帧回调(美颜 / 滤镜)
|
||
|
||
```objc
|
||
- (CVPixelBufferRef)pusher:(SellyLiveVideoPusher *)pusher
|
||
onCaptureVideoFrame:(CVPixelBufferRef)pixelBuffer;
|
||
```
|
||
|
||
> 返回值为最终用于推流的视频帧。
|
||
|
||
---
|
||
|
||
## 6. 拉流接入详解
|
||
|
||
### 6.1 创建播放器
|
||
|
||
```objc
|
||
SellyLiveVideoPlayer *player =
|
||
[[SellyLiveVideoPlayer alloc] initWithUrl:playUrl];
|
||
player.delegate = self;
|
||
```
|
||
|
||
---
|
||
|
||
### 6.2 设置拉流 Token(必须)
|
||
|
||
```objc
|
||
player.token = playToken;
|
||
```
|
||
|
||
---
|
||
|
||
### 6.3 播放流程
|
||
|
||
```objc
|
||
[player prepareToPlay];
|
||
[player play];
|
||
```
|
||
|
||
控制接口:
|
||
|
||
- pause
|
||
- stop
|
||
- isPlaying
|
||
|
||
---
|
||
|
||
### 6.4 播放回调
|
||
|
||
```objc
|
||
- (void)player:(SellyLiveVideoPlayer *)player
|
||
playbackStateChanged:(SellyPlayerState)state;
|
||
|
||
- (void)player:(SellyLiveVideoPlayer *)player
|
||
onError:(NSError *)error;
|
||
```
|
||
|
||
状态枚举:
|
||
|
||
- Idle
|
||
- Connecting
|
||
- Playing
|
||
- Paused
|
||
- Stopped
|
||
- Failed
|
||
|
||
---
|
||
|
||
## 7. 错误处理与重试建议
|
||
|
||
### Token 错误
|
||
|
||
1. 停止当前推 / 拉
|
||
2. 获取新 Token
|
||
3. 重新设置 Token
|
||
4. 重启流程
|
||
|
||
### 网络错误
|
||
|
||
- 根据 rtt / bitrate 判断弱网
|
||
- 必要时重启连接
|
||
|
||
---
|
||
|
||
## 8. 最佳实践
|
||
|
||
- 推流前先完成采集预览
|
||
- Token 即将过期前提前刷新
|
||
- 使用统计回调做质量监控
|
||
- 拉流失败避免无限重试
|
||
|
||
---
|
||
|
||
## 9. 常见问题(FAQ)
|
||
|
||
### Q1:Token 可以拼接到 URL 吗?
|
||
**A:** 不可以。
|
||
SDK 不解析 URL 中的鉴权信息,所有鉴权均通过 SDK 实例的 `token` 属性完成。
|
||
|
||
---
|
||
|
||
### Q2:运行中修改 Token 是否生效?
|
||
**A:**
|
||
运行中修改 Token **不会影响当前已建立的连接**,
|
||
**下次重连或重新启动推流 / 拉流时会使用新的 Token**。
|
||
|
||
---
|
||
|
||
### Q3:推流画面出现绿边?
|
||
**A:**
|
||
请确保视频分辨率的 **宽和高均为 2 的倍数**。
|
||
建议直接使用 SDK 提供的预设分辨率枚举,避免手动配置导致的问题。
|
||
|
||
---
|
||
|
||
### Q4:如何降低推流延迟?
|
||
**A:** 可以从以下几个方面优化:
|
||
|
||
- 减小关键帧间隔(`videoMaxKeyframeInterval`)
|
||
- 优先使用 **RTC 模式** 而非 RTMP
|
||
- 适当降低视频分辨率和码率
|
||
|
||
---
|
||
|
||
### Q5:弱网环境下如何优化推流体验?
|
||
**A:** 建议采取以下策略:
|
||
|
||
- 启用自适应码率策略(如业务支持)
|
||
- 降低初始分辨率和码率
|
||
- 将帧率控制在 **15–20 fps**
|
||
- 监听网络状态,动态调整推流配置
|
||
|
||
---
|
||
|
||
### Q6:播放器出现黑屏怎么办?
|
||
**A:** 可按以下步骤排查:
|
||
|
||
- 检查播放地址是否正确
|
||
- 确认当前网络连接正常
|
||
- 查看播放器回调中的错误信息
|
||
- 确认视频流格式是否被 SDK 支持
|
||
|
||
---
|
||
|
||
### Q7:如何实现横屏推流?
|
||
**A:**
|
||
通过设置视频输出方向即可:
|
||
|
||
```objective-c
|
||
videoConfig.outputImageOrientation = UIInterfaceOrientationLandscapeRight;
|
||
|
||
---
|
||
|
||
**文档版本:** v2.0
|
||
**最后更新:** 2025-12
|