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

PLCameraStreamingKit 包括摄像头、麦克风等装备相干的资本猎取,也包括音视频数据的编码处置惩罚和发送。

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

体系请求: iOS7 及以上版本

PLCameraStreamingKit代码集成

CocoaPods的要领

直接在Podfile中增加

pod 'PLCameraStreamingKit'

然后

pod install

或许

pod update

运转你工程的 Workspace,就集成终了了。

非Cocoapods集成

详情请接见:http://blog.csdn.net/kivenhehaoyu/article/details/51051279

疾速接入项目

示例代码

AppDelegate.m 中举行 SDK 初始化,假如不举行SDK初始化那末将在中心类 PLStreamingSession 初始化阶段报错。

#import <PLStreamingKit/PLStreamingEnv.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [PLStreamingEnv initEnv];
    // Override point for customization after application launch.
    return YES;
}

在须要的处所增加

#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 详细参数

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
@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 就能够检察接口和类的相干信息,削减不必要的贫苦。

    原文作者:jemygraw
    原文地址: https://segmentfault.com/a/1190000005824547
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞