Skip to content

Repository files navigation

PLCameraStreamingKit

PLCameraStreamingKit 是一个适用于 iOS 的 RTMP 直播推流 SDK,可高度定制化和二次开发。特色是支持 iOS Camera 画面捕获并进行 H.264 硬编码,以及支持 iOS 麦克风音频采样并进行 AAC 硬编码;同时,还根据移动网络环境的多变性,实现了一套可供开发者灵活选择的编码参数集合。借助 PLCameraStreamingKit,开发者可以快速构建一款类似 MeerkatPeriscope 的手机直播应用。

功能特性

  • 采集模块源码开放
  • 支持硬件编码
  • 多码率可选
  • 支持 H.264 视频编码
  • 支持 AAC 音频编码
  • 支持前后摄像头
  • 支持自动对焦
  • 支持手动调整对焦点
  • 支持闪光灯操作
  • 支持多分辨率编码
  • 支持 HeaderDoc 文档
  • 支持构造带安全授权凭证的 RTMP 推流地址
  • 支持 ARMv7, ARM64, i386, x86_64 架构
  • 支持 RTMP 协议直播推流
  • 支持音视频配置分离
  • 支持推流时可变码率
  • 提供发送 buffer
  • 支持 Zoom 操作
  • 支持音频 Mute 操作
  • 支持视频 Orientation 操作
  • 支持自定义 DNS 解析
  • 支持弱网丢帧策略

内容摘要

快速开始

先来看看 PLCameraStreamingKit 接入的步骤

配置工程

  • 配置你的 Podfile 文件,添加如下配置信息
pod 'PLCameraStreamingKit'
  • 安装 CocoaPods 依赖
pod install

pod update
  • Done! 运行你工程的 workspace

示例代码

在需要的地方添加

#import<PLCameraStreamingKit/PLCameraStreamingKit.h>

PLCameraStreamingSession 是核心类,你只需要关注并使用这个类就可以完成通过摄像头推流、预览的工作。如果你只需要做纯音频推流,那么你可以使用 PLAudioStreamingSession

推流前务必要先检查摄像头 / 麦克风的授权,并记得设置预览界面,StreamingSession 的创建需要 Stream 对象

// streamJSON 是从服务端拿回的//// 从服务端拿回的 streamJSON 结构如下:// @{@"id": @"stream_id",// @"title": @"stream_title",// @"hub": @"hub_name",// @"publishKey": @"publish_key",// @"publishSecurity": @"dynamic", // or static// @"disabled": @(NO),// @"profiles": @[@"480p", @"720p"], // or empty Array []// @"hosts": @{// ...// }NSDictionary *streamJSON;
PLStream *stream = [PLStream streamWithJSON:streamJSON];
// 授权后执行void (^permissionBlock)(void) = ^{
PLVideoStreamingConfiguration *videoConfiguration = [[PLVideoStreamingConfiguration defaultConfiguration]; PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfiguration defaultConfiguration];
self.session = [[PLCameraStreamingSession alloc] initWithVideoConfiguration:videoConfiguration
audioConfiguration:audioConfiguration
stream:stream
videoOrientation:AVCaptureVideoOrientationPortrait];
self.session.delegate = self;
self.session.previewView = self.view;
};
void (^noPermissionBlock)(void) = ^{ // 处理未授权情况 };// 检查摄像头是否有授权
PLAuthorizationStatus status = [PLCameraStreamingSession cameraAuthorizationStatus];
if (PLAuthorizationStatusNotDetermined == status) {
[PLCameraStreamingSession requestCameraAccessWithCompletionHandler:^(BOOL granted) {
// 回调确保在主线程,可以安全对 UI 做操作
granted ? permissionBlock() : noPermissionBlock();
}];
} elseif (PLAuthorizationStatusAuthorized == status) {
permissionBlock();
} else {
noPermissionBlock();
}

推流操作

// 开始推流,无论 security policy 是 static 还是 dynamic,都无需再单独计算推流地址
[self.session startWithCompleted:^(BOOL success) {
// 这里的代码在主线程运行,所以可以放心对 UI 控件做操作if (success) {
// 连接成功后的处理// 成功后,在这里才可以读取 self.session.pushURL,start 失败和之前不能确保读取到正确的 URL
} else {
// 连接失败后的处理
}
}];
// 停止推流
[self.session stop];

销毁推流 session

[self.session destroy];

编码参数

移动端因网络环境不稳定及用户电量宝贵等原因,并不建议直接使用最高码率和分辨率来做推流,以最佳编码参数来做设置可以带来更好的推流效果和用户体验。

如果你不能确定该如何配置各个编码参数,也不用担心,PLCameraStreamingKit 提供了一个编码配置的类来帮你快速完成配置,你可以通过使用 SDK 预先定义好的 quality 来构建编码推流配置。

视频编码参数

// 视频推流质量/*! * @abstract Video streaming quality low 1 * * @discussion 具体参数 fps: 12, profile level: baseline31, video bitrate: 150Kbps*/externNSString *kPLVideoStreamingQualityLow1;
/*! * @abstract Video streaming quality low 2 * * @discussion 具体参数 fps: 15, profile level: baseline31, video bitrate: 264Kbps*/externNSString *kPLVideoStreamingQualityLow2;
/*! * @abstract Video streaming quality low 3 * * @discussion 具体参数 fps: 15, profile level: baseline31, video bitrate: 350Kbps*/externNSString *kPLVideoStreamingQualityLow3;
/*! * @abstract Video streaming quality medium 1 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 512Kbps*/externNSString *kPLVideoStreamingQualityMedium1;
/*! * @abstract Video streaming quality medium 2 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 800Kbps*/externNSString *kPLVideoStreamingQualityMedium2;
/*! * @abstract Video streaming quality medium 3 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 1000Kbps*/externNSString *kPLVideoStreamingQualityMedium3;
/*! * @abstract Video streaming quality high 1 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 1200Kbps*/externNSString *kPLVideoStreamingQualityHigh1;
/*! * @abstract Video streaming quality high 2 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 1500Kbps*/externNSString *kPLVideoStreamingQualityHigh2;
/*! * @abstract Video streaming quality high 3 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 2000Kbps*/externNSString *kPLVideoStreamingQualityHigh3;

需要明确以上两者,便可以直接获取到最佳的视频编码配置。

// 该方法每次都会生成一个新的配置,不是单例方法。默认情况下,对应的参数为分辨率 (320, 480), video quality PLStreamingQualityMedium1
PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration defaultConfiguration];
// 你也可以指定自己想要的分辨率和已有的 video quality 参数
PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration configurationWithVideoSize:CGSizeMake(320, 480) videoQuality:kPLVideoStreamingQualityHigh1];
// 当已有的分辨率无法满足你的需求时,你可以自己定义所有参数,但请务必确保你清楚参数的含义
PLVideoStreamingConfiguration *videoConfiguration = [[PLVideoStreamingConfiguration alloc] initWithVideoSize:CGSizeMake(width, height) videoFrameRate:30videoMaxKeyframeInterval:90videoBitrate:1200 * 1000videoProfileLevel:AVVideoProfileLevelH264Main32]];

Video Quality 具体参数

QualityFPSProfileLevelVideo BitRate(Kbps)
kPLVideoStreamingQualityLow112Baseline 31150
kPLVideoStreamingQualityLow215Baseline 31264
kPLVideoStreamingQualityLow315Baseline 31350
kPLVideoStreamingQualityMedium130Baseline 31512
kPLVideoStreamingQualityMedium230Baseline 31800
kPLVideoStreamingQualityMedium330Baseline 311000
kPLVideoStreamingQualityHigh130Baseline 311200
kPLVideoStreamingQualityHigh230Baseline 311500
kPLVideoStreamingQualityHigh330Baseline 312000

音频编码参数

// 音频推流质量
/*!
* @abstract Audio streaming quality high 1
*
* @discussion 具体参数 audio sample rate: 44MHz, audio bitrate: 96Kbps
*/
extern NSString *kPLAudioStreamingQualityHigh1;
/*!
* @abstract Audio streaming quality high 2
*
* @discussion 具体参数 audio sample rate: 44MHz, audio bitrate: 128Kbps
*/
extern NSString *kPLAudioStreamingQualityHigh2;

生成音频编码配置

// 音频配置默认使用 high2 作为质量选项
PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfiguration defaultConfiguration];
// 如果你需要自己定义音频质量
PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfiguration configurationWithAudioQuality:kPLAudioStreamingQualityHigh1];

Audio Quality 具体参数

QualityAudio Samplerate(MHz))Audio BitRate(Kbps)
kPLAudioStreamingQualityHigh14496
kPLAudioStreamingQualityHigh244128

在创建好编码配置对象后,就可以用它来初始化 PLCameraStreamingSession 了。

流状态变更及处理处理

实现 PLCameraStreamingSessionDelegatePLAudioStreamingSessionDelegate 的回调方法,可以及时的得知流状态的变更及推流错误

- (void)cameraStreamingSession:(PLCameraStreamingSession *)session streamStateDidChange:(PLStreamState)state {
// 当流状态变更为非 Error 时,会回调到这里
}
- (void)cameraStreamingSession:(PLCameraStreamingSession *)session didDisconnectWithError:(NSError *)error {
// 当流状态变为 Error, 会携带 NSError 对象回调这个方法
}
- (void)streamingSession:(PLStreamingSession *)session streamStatusDidUpdate:(PLStreamStatus *)status {
// 当开始推流时,会每间隔 3s 调用该回调方法来反馈该 3s 内的流状态,包括视频帧率、音频帧率、音视频总码率
}

变更推流质量及策略

在推流时,可以配合发送 buffer 自己设定不同的策略,来满足不同的网络环境。

使用 buffer 可用的方法

// BufferDelegate@protocolPLStreamingSendingBufferDelegate <NSObject>
- (void)streamingSessionSendingBufferDidEmpty:(id)session;
- (void)streamingSessionSendingBufferDidFull:(id)session;
@end// StreamingSession 中的 buffer 相关内容@interfacePLCameraStreamingSession (SendingBuffer)
@property (nonatomic, PL_WEAK) id<PLStreamingSendingBufferDelegate> bufferDelegate;
/// [0..1], 不可超出这个范围, 默认为 0.5@property (nonatomic, assign) CGFloat threshold;
/// Buffer 最多可包含的包数,默认为 300@property (nonatomic, assign) NSUInteger maxCount;
@property (nonatomic, assign, readonly) NSUInteger currentCount;
@end

buffer 是一个可以缓存待发送内容的队列,它按照帧数作为缓存长度的判定,可以通过 maxCount 来读取和设定,buffer 的阈值设定体现你期望的变更推流质量的策略,默认阈值为 buffer 的 50%(0.5)。

当 buffer 变为空时,会回调

- (void)streamingSessionSendingBufferDidEmpty:(id)session;

当 buffer 满时,会回调

- (void)streamingSessionSendingBufferDidFull:(id)session;

当你希望在 streamStatus 变化,buffer empty 或者 buffer full 时变化 video configuration,可以调用 session 的 reloadVideoConfiguration: 方法

[self.session reloadVideoConfiguration:newConfiguraiton];

文档支持

PLCameraStreamingKit 使用 HeaderDoc 注释来做文档支持。 开发者无需单独查阅文档,直接通过 Xcode 就可以查看接口和类的相关信息,减少不必要的麻烦。

Encode 推荐

系统要求

  • iOS Target : >= iOS 7

版本历史

  • 1.6.2 (Release Notes && API Diffs)
    • 更新依赖 PLStreamingKit 的版本到 v1.1.5
    • 支持 Zoom 操作
  • 1.6.1 (Release Notes && API Diffs)
    • 更新依赖 PLStreamingKit 的版本到 v1.1.3
    • 修复调用 - (void)reloadVideoConfiguraiton 方法,fps 变更失败的问题
  • 1.6.0 (Release Notes && API Diffs)
    • 更新依赖 PLStreamingKit 的版本到 v1.1.2
    • 添加 PLStreamStatus 回调,便于客户端监控推流状态
    • 修复采集源 fps 变更失败的问题
  • 1.5.2 (Release Notes && API Diffs)
    • 更新依赖 PLStreamingKit 的版本到 v1.0.3
  • 1.5.1 (Release Notes && API Diffs)
    • 更新依赖 PLStreamingKit 的版本到 v1.0.2
    • 更改音频数据源采集部分,转换为单声道
  • 1.5.0 (Release Notes && API Diffs)
    • 编码推流改为依赖 PLStreamingKit
    • 去除 PLAudioStreamingSession 类, 建议单纯推音频的 App 直接接入 PLStreamingKit
    • 摄像头及音频采集部分开源
    • 底层添加了 HappyDNS, 解决部分地区 DNS 感染严重导致推流失败问题
    • 优化 TCP 层发包,极大程度解决了网络正常但推流中经常断开的问题
  • 1.4.16 (Release Notes && API Diffs)
    • 解决 destroy 方法可能卡死线程的问题
  • 1.4.15 (Release Notes && API Diffs)
    • 修复类库 .a 未更新问题
  • 1.4.14 (Release Notes && API Diffs)
    • 解决视频质量切换时导致 crash 的问题
    • 解决推流时触发的只有音频无视频问题
    • 解决音频采样导致的电流声
    • 解决潜在内存问题,整体提升稳定性
    • 视频编码统一 profileLevel 为 baseline31
    • 限定最高支持分辨率到 720p
  • 1.4.13 (Release Notes && API Diffs)
    • 更新 mute 行为,mute 后不会中断发包
    • 更新音频设备采样率获取途径
    • 更新底层库,避免冲突
  • 1.4.12 (Release Notes && API Diffs)
    • 添加 smoothAutoFocusEnabled 参数,确保拍摄时对焦的平滑过渡
    • 修复无网络环境或其他情况触发断流时引起的 crash
    • 修复频繁切换摄像头时引起的 crash
    • 修复内存 leak
  • 1.4.11 (Release Notes && API Diffs)
    • 修复 iPhone 6s 系列机型直播无声音问题
  • 1.4.10 (Release Notes && API Diffs)
    • 修复错误重连或者主动重连时导致 UI 卡顿的问题
  • 1.4.9 (Release Notes && API Diffs)
    • 尝试修复 iPhone 6s 音频获取不到权限的问题
    • 优化丢包策略,兼顾高延时和低带宽的情况
    • 更新 demo 为全异步请求
  • 1.4.8 (Release Notes && API Diffs)
    • 尝试修复 iPhone 6s 音频获取不到权限的问题
    • 修复弱网环境触发的内存和 CPU 占用升高的问题
  • 1.4.7 (Release Notes && API Diffs)
    • 尝试修复音频获取不到权限的问题
    • 添加关闭 SDK 渲染 preview 的接口
  • 1.4.6 (Release Notes && API Diffs)
    • 修复弱网环境下切换 VideoQuality 可能触发的 crash 问题
    • 添加 PLAudioComponentFailedToCreateNotification 通知,在音频资源被占用时,创建音频结构失败会发送这个通知
  • 1.4.5 (Release Notes && API Diffs)
    • 添加自行绘制 CMSampleBufferRef 的支持
  • 1.4.4 (Release Notes && API Diffs)
    • 为 PLCameraStreamingSession 多个属性添加 kvo 支持
    • 由时间计数改为包数计数
    • 针对弱网坏境更改丢帧策略,确保不会出现花屏和声音抖动,取而代之会出现间断的无数据,但是可以保证画面和声音的流畅
    • 发送队列的默认上下阈值更改为 0.3 和 0.7
  • 1.4.3 (Release Notes && API Diffs)
    • 优化网络层调用,添加 Disconnecting 流状态
    • 抽离可导致推流中断的错误
    • 添加错误回调,同时将错误信息返回,便于 debug 及异常处理
    • 修复 destroy 调用导致的崩溃问题
    • 支持 iOS 9 的 bitcode
  • 1.4.2 (Release Notes && API Diffs)
    • 添加 SendingBuffer 支持
    • 修复 iPhone 6s 下崩溃的问题
  • 1.4.1 (Release Notes && API Diffs)
    • 添加可以获取视频源数据的回调方法,便于开发者做滤镜等处理
    • 对自定义分辨率做了内部修正,保证宽高均为 16 倍数
  • 1.4.0 (Release Notes && API Diffs)
    • 添加音频推流的 PLAudioStreamingSession, 纯音频推流合并到 PLCameraStreamingKit
    • 添加后台推流支持,暂且只在纯音频推流中有效
  • 1.3.2 (Release Notes && API Diffs)
    • 修复直播被电话 / 闹钟中断后后续直播无声音的问题
    • 更改音频采集类型: RecordAndPlay -> Record
    • 添加对蓝牙音频设备的支持
  • 1.3.1 (Release Notes && API Diffs)
    • 修复调用 destroy 方法后,重新创建 session 进入后台触发的 crash 问题
    • 去除无用依赖, SDK 大小由 17 MB 降低为 4.7 MB
  • 1.3.0 (Release Notes && API Diffs)
    • 添加带宽质量检测机制,推流过程中可无缝切换音视频 Quality,实现码率及帧率的动态调节
    • 添加发送队列的配置及状态回调
    • 更新 Example 来简单说明如何使用发送队列和 Quality 组合推流策略
  • 1.2.8 (Release Notes && API Diffs)
    • 更新编码配置,分离音视频编码配置,便于提供更灵活的配置方案
    • 去除 SIGPIPE 断点
    • 修复 URL 错误时导致的崩溃
    • 修复创建 Session 后设置 Stream 推流失败的问题
  • 1.2.7 (Release Notes && API Diffs)
    • 修复断网后停止流时导致的 UI 卡死
    • 修复停止推流时概率出现的 crash 问题
    • 添加 - (void)destroy 方法到 PLCameraStreamingSession
    • 暂且去除 iOS 8 编码,待进一步优化后再做开放
    • 修复反复进出持有 streamingSession 的 viewController 出现 IO 错误或者 crash 的问题
  • 1.2.6 (Release Notes && API Diffs)
    • 修复 iOS 8 以下推流时,编码导致的崩溃问题
  • 1.2.5 (Release Notes && API Diffs)
    • 更新了 Quality 配置
  • 1.2.4 (Release Notes && API Diffs)
    • 添加全新的 iOS 8 硬编码器,减少编码延时
  • 1.2.3 (Release Notes && API Diffs)
    • 更新了 PLStream 类结构
    • 添加新的 session 创建接口
    • 移除 publishHost,PLStream 对象支持自动生成推流地址,请搭配服务端 SDK 至少 1.2.0 或以上版本使用
  • 1.2.2 (Release Notes && API Diffs)
    • 更新麦克风资源调用方式,添加进入后台后自动停用麦克风功能
  • 1.2.1 (Release Notes && API Diffs)
    • 修复初次授权摄像头后预览界面为黑屏的问题
  • 1.2.0 (Release Notes && API Diffs)
    • 添加了 PLStream 类,支持 Coding 协议便于打包存储
    • 更新 StreamingSession 创建方法,借助传递 PLStream 对象再无需推流时等待服务端生成推流地址
    • 完善 HeaderDoc 文档
  • 1.1.8 (Release Notes && API Diffs)
    • 添加摄像头开启和关闭的操作,便于开发者控制 AVCaptureSession
  • 1.1.7 (Release Notes && API Diffs)
    • 添加推流质量字段,方便开发者指定推流质量
    • 移除原配置中的网络选项
    • 默认情况下关闭了 PLLog
    • 添加摄像头开始运行的通知
    • 添加麦克风开始运行的通知
  • 1.1.6 (Release Notes && API Diffs)
    • 尝试修复音频变声问题
  • 1.1.5 (Release Notes && API Diffs)
    • 修复了重连后无法播放的问题
  • 1.1.4 (Release Notes && API Diffs)
    • 更新了码率和采样率。现在统一使用 128Kbps 和 44100KHZ,用以解决噪音的问题
    • 更新了网络 socket。对 socket 在调试情况下出现的 SIGPIPE 进行了处理,不会再出现
    • 更新了网络状态的返回情况。当不是主动调用 close 接口导致的断开都将以 error 状态通知 delegate
  • 1.1.3 (Release Notes && API Diffs)
    • 更新了获取视频截图的方法
    • 添加 HeaderDoc 格式注释文档
  • 1.1.2 (Release Notes && API Diffs)
    • 添加自定视频大小的编码配置
    • 添加进入后台后自动停止推流的支持
    • 添加保持常亮的开关
    • 添加获取当前录制截屏的功能
    • 修复进入后台导致崩溃的问题
    • 修复切换前置摄像头失效的问题
    • 添加 Release Notes 说明每个版本变动
    • 添加 API Diffs 说明具体修改细节
  • 1.1.1
    • 修复 release 版本无法推流的 bug
    • 内存优化,比 1.1.0 减少 6% 左右内存消耗
  • 1.1.0
    • 重构接口
    • 优化编码参数
    • 提供不同网络和分辨率下的多种配置可选
    • 添加消息通知,便于监听
    • 兼顾 arc 及非 arc 的工程
  • 1.0.0
    • 发布 CocoaPods 版本

About

Pili RTMP Streaming SDK for iOS, H.264 and AAC hardware encoding supported. Camera and Microphone as input source.

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages