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