七牛雲直播 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 就能夠查看接口和類的相關信息,減小沒必要要的麻煩。

相關文章
相關標籤/搜索