PLCameraStreamingKit 包括摄像头、麦克风等设备相关的资源获取,也包括音视频数据的编码处理和发送。git
PLCameraStreamingKit代码下载地址:https://github.com/pili-engineering/PLCameraStreamingKitgithub
系统要求: iOS7 及以上版本json
直接在Podfile中添加缓存
pod 'PLCameraStreamingKit'
而后安全
pod install
或者服务器
pod update
运行你工程的 Workspace,就集成完毕了。网络
详情请访问:http://blog.csdn.net/kivenhehaoyu/article/details/51051279session
在 AppDelegate.m
中进行 SDK 初始化,若是不进行SDK初始化那么将在核心类 PLStreamingSession
初始化阶段报错。app
#import <PLStreamingKit/PLStreamingEnv.h> - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [PLStreamingEnv initEnv]; // Override point for customization after application launch. return YES; }
在须要的地方添加ide
#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": @{ // ... // } //服务器拿回来的streamJSON是NSString型的json对象,此地须要的是NSDictionary类型的,能够用一下方法转类型 //+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString { // if (jsonString == nil) { // return nil; // } // // NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; // NSError *err; // NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData // options:NSJSONReadingMutableContainers // error:&err]; // if(err) { // NSLog(@"json解析失败:%@",err); // return nil; // } // return dic; //} NSDictionary *streamJSON; PLStream *stream = [PLStream streamWithJSON:streamJSON]; // 受权后执行 void (^permissionBlock)(void) = ^{ PLVideoCaptureConfiguration *videoCaptureConfiguration = [self.videoCaptureConfigurations defaultConfiguration]; PLAudioCaptureConfiguration *audioCaptureConfiguration = [PLAudioCaptureConfiguration defaultConfiguration]; PLVideoStreamingConfiguration *videoStreamingConfiguration = [self.videoStreamingConfigurations defaultConfiguration]; PLAudioStreamingConfiguration *audioStreamingConfiguration = [PLAudioStreamingConfiguration defaultConfiguration]; self.session = [[PLCameraStreamingSession alloc] initWithVideoCaptureConfiguration:videoCaptureConfiguration audioCaptureConfiguration:audioCaptureConfiguration videoStreamingConfiguration:videoStreamingConfiguration audioStreamingConfiguration:audioStreamingConfiguration stream:stream videoOrientation:orientation]; 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(); }]; } else if (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 */ extern NSString *kPLVideoStreamingQualityLow1; /*! * @abstract Video streaming quality low 2 * * @discussion 具体参数 fps: 15, profile level: baseline31, video bitrate: 264Kbps */ extern NSString *kPLVideoStreamingQualityLow2; /*! * @abstract Video streaming quality low 3 * * @discussion 具体参数 fps: 15, profile level: baseline31, video bitrate: 350Kbps */ extern NSString *kPLVideoStreamingQualityLow3; /*! * @abstract Video streaming quality medium 1 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 512Kbps */ extern NSString *kPLVideoStreamingQualityMedium1; /*! * @abstract Video streaming quality medium 2 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 800Kbps */ extern NSString *kPLVideoStreamingQualityMedium2; /*! * @abstract Video streaming quality medium 3 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 1000Kbps */ extern NSString *kPLVideoStreamingQualityMedium3; /*! * @abstract Video streaming quality high 1 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 1200Kbps */ extern NSString *kPLVideoStreamingQualityHigh1; /*! * @abstract Video streaming quality high 2 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 1500Kbps */ extern NSString *kPLVideoStreamingQualityHigh2; /*! * @abstract Video streaming quality high 3 * * @discussion 具体参数 fps: 30, profile level: baseline31, video bitrate: 2000Kbps */ extern NSString *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:30 videoMaxKeyframeInterval:90 videoBitrate:1200 * 1000 videoProfileLevel:AVVideoProfileLevelH264Main32]];
Quality | FPS | ProfileLevel | Video BitRate(Kbps) |
---|---|---|---|
kPLVideoStreamingQualityLow1 | 12 | Baseline 31 | 150 |
kPLVideoStreamingQualityLow2 | 15 | Baseline 31 | 264 |
kPLVideoStreamingQualityLow3 | 15 | Baseline 31 | 350 |
kPLVideoStreamingQualityMedium1 | 30 | Baseline 31 | 512 |
kPLVideoStreamingQualityMedium2 | 30 | Baseline 31 | 800 |
kPLVideoStreamingQualityMedium3 | 30 | Baseline 31 | 1000 |
kPLVideoStreamingQualityHigh1 | 30 | Baseline 31 | 1200 |
kPLVideoStreamingQualityHigh2 | 30 | Baseline 31 | 1500 |
kPLVideoStreamingQualityHigh3 | 30 | Baseline 31 | 2000 |
// 音频推流质量 /*! * @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];
Quality | Audio Samplerate(MHz)) | Audio BitRate(Kbps) |
---|---|---|
kPLAudioStreamingQualityHigh1 | 44 | 96 |
kPLAudioStreamingQualityHigh2 | 44 | 128 |
在建立好编码配置对象后,就能够用它来初始化 PLCameraStreamingSession
了。
实现 PLCameraStreamingSessionDelegate
或 PLAudioStreamingSessionDelegate
的回调方法,能够及时的得知流状态的变动及推流错误
- (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 @protocol PLStreamingSendingBufferDelegate <NSObject> - (void)streamingSessionSendingBufferDidEmpty:(id)session; - (void)streamingSessionSendingBufferDidFull:(id)session; @end // StreamingSession 中的 buffer 相关内容 @interface PLCameraStreamingSession (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];
配置你的 Podfile 文件,添加以下配置
use_frameworks! pod 'PLCameraStreamingKit', :podspec =>'https://raw.githubusercontent.com/pili-engineering/PLCameraStreamingKit/master/PLCameraStreamingKitForSwift.podspec' pod 'PLStreamingKit'
pod install 或 pod update 安装依赖;
打开你工程的 workspace,在 Pods 工程中选中 PLCameraStreamingKit TARGETS,右侧 Tab 选择 "Build Phases",在 "Link Binary With Libraries" 中将 <工程目录>/Pods/PLStreamingKit/Pod/Library/lib/ 中的libPLStreamingKit.a 库加入;
在 Objective-C bridging header 中加入一行
#import <PLStreamingKit/PLStreamingKit.h>
Objective-C bridging header 一般以 ProjectName-Bridging-Header.h 命名,若是没有 Objective-C bridging header,能够在 Swift 工程中新建一个 Objective-C File,Xcode 会弹出对话框询问是否配置 Objective-C bridging header,确认后,Xcode 会帮你建立好 Objective-C bridging header;
Done!如今在须要的地方 import PLCameraStreamingKit 就可使用了。
PLCameraStreamingKit 使用 HeaderDoc 注释来作文档支持。开发者无需单独查阅文档,直接经过 Xcode 就能够查看接口和类的相关信息,减小没必要要的麻烦。