七牛云直播 iOS 推流SDK PLCameraStreamingKit 接入流程

PLCameraStreamingKit 包括摄像头、麦克风等设备相关的资源获取,也包括音视频数据的编码处理和发送。git

PLCameraStreamingKit代码下载地址:https://github.com/pili-engineering/PLCameraStreamingKitgithub

系统要求: iOS7 及以上版本json

PLCameraStreamingKit代码集成

CocoaPods的方法

直接在Podfile中添加缓存

pod 'PLCameraStreamingKit'

而后安全

pod install

或者服务器

pod update

运行你工程的 Workspace,就集成完毕了。网络

非Cocoapods集成

详情请访问: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]];

Video Quality 具体参数

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];

Audio Quality 具体参数

Quality Audio Samplerate(MHz)) Audio BitRate(Kbps)
kPLAudioStreamingQualityHigh1 44 96
kPLAudioStreamingQualityHigh2 44 128

在建立好编码配置对象后,就能够用它来初始化 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
@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];

集成到 Swift 工程

  • 配置你的 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 就能够查看接口和类的相关信息,减小没必要要的麻烦。

相关文章
相关标签/搜索