# 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 ``` ### 3.2 权限配置(Info.plist) 推流场景必须配置以下权限: ```xml NSCameraUsageDescription 需要访问摄像头用于直播 NSMicrophoneUsageDescription 需要访问麦克风用于直播 ``` > 仅拉流播放场景不需要麦克风权限,请避免触发采集相关接口。 --- ## 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