最簡單的iOS 推流程式碼,視訊捕獲,軟編碼(faac,x264),硬編碼(aac,h264),美顏,flv編碼,rtmp協議,陸續更新程式碼解析,你想學的知識這裡都有,願意懂直播技術的同學快來看!!
原始碼:https://github.com/hardman/AWLive
上一篇文章介紹瞭如何使用系統方法捕獲視訊資料,但是更多的時候,為了使用美顏濾鏡,我們會選擇GPUImage來獲取視訊資料。
GPUImage是一個可以為錄製視訊新增實時濾鏡的一個著名第三方庫。
該框架大概原理是,使用OpenGL著色器對視訊影像進行顏色處理,然後存到frameBuffer,之後可以對此資料再次處理。重複上述過程,即可達到多重濾鏡效果。
具體實現不細說,這裡簡要介紹一下GPUImage的使用,如何美顏,如何獲取音視訊資料。
使用GPUImage
GPUImage的主要程式碼在 AWGPUImageAVCapture 這個類中。
初始化AWAVCaptureManager物件時將captureType設為AWAVCaptureTypeGPUImage,就會自動呼叫AWGPUImageAVCapture類來捕獲視訊資料。
程式碼在 onInit 方法中:
-(void)onInit{
//攝像頭初始化
// AWGPUImageVideoCamera 繼承自 GPUImageVideoCamera。繼承是為了獲取音訊資料,原始碼中,預設情況下音訊資料傳送給了 audioEncodingTarget。
// 這個東西一看型別是GPUImageMovieWriter,應該是檔案寫入功能。果斷覆蓋掉processAudioSampleBuffer方法,拿到音訊資料後自己處理。
// 音訊就這樣可以了,GPUImage主要工作還是在視訊處理這裡。
// 設定預覽解析度 self.captureSessionPreset是根據AWVideoConfig的設定,獲取的解析度。設定前置、後置攝像頭。
_videoCamera = [[AWGPUImageVideoCamera alloc] initWithSessionPreset:self.captureSessionPreset cameraPosition:AVCaptureDevicePositionFront];
//開啟捕獲聲音
[_videoCamera addAudioInputsAndOutputs];
//設定輸出影像方向,可用於橫屏推流。
_videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
//映象策略,這裡這樣設定是最自然的。跟系統相機預設一樣。
_videoCamera.horizontallyMirrorRearFacingCamera = NO;
_videoCamera.horizontallyMirrorFrontFacingCamera = YES;
//設定預覽view
_gpuImageView = [[GPUImageView alloc] initWithFrame:self.preview.bounds];
[self.preview addSubview:_gpuImageView];
//初始化美顏濾鏡
_beautifyFilter = [[GPUImageBeautifyFilter alloc] init];
//相機獲取視訊資料輸出至美顏濾鏡
[_videoCamera addTarget:_beautifyFilter];
//美顏後輸出至預覽
[_beautifyFilter addTarget:_gpuImageView];
// 到這裡我們已經能夠開啟相機並預覽了。
// 因為要推流,除了預覽之外,我們還要擷取到視訊資料。這就需要使用GPUImage中的GPUImageRawDataOutput,它能將美顏後的資料輸出,便於我們處理後傳送出去。
// AWGPUImageAVCaptureDataHandler繼承自GPUImageRawDataOutput,從 newFrameReadyAtTime 方法中就可以獲取到美顏後輸出的資料。
// 輸出的圖片格式為BGRA。
_dataHandler = [[AWGPUImageAVCaptureDataHandler alloc] initWithImageSize:CGSizeMake(self.videoConfig.width, self.videoConfig.height) resultsInBGRAFormat:YES capture:self];
[_beautifyFilter addTarget:_dataHandler];
// 令AWGPUImageAVCaptureDataHandler實現AWGPUImageVideoCameraDelegate協議,並且讓camera的awAudioDelegate指向_dataHandler物件。
// 將音訊資料轉到_dataHandler中處理。然後音視訊資料就可以都在_dataHandler中處理了。
_videoCamera.awAudioDelegate = _dataHandler;
//開始捕獲視訊
[self.videoCamera startCameraCapture];
//修改幀率
[self updateFps:self.videoConfig.fps];
}
複製程式碼
美顏濾鏡使用的是:https://github.com/Guikunzhi/BeautifyFaceDemo 感謝Guikunzhi的分享。想了解美顏詳細演算法的同學,可以自行學習。
AWGPUImageAVCaptureDataHandler中音視訊處理方法:
// 獲取到音訊資料,通過sendAudioSampleBuffer傳送出去
-(void)processAudioSample:(CMSampleBufferRef)sampleBuffer{
if(!self.capture || !self.capture.isCapturing){
return;
}
[self.capture sendAudioSampleBuffer:sampleBuffer];
}
// 獲取到視訊資料,轉換格式後,使用sendVideoYuvData 傳送出去。
-(void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex{
[super newFrameReadyAtTime:frameTime atIndex:textureIndex];
if(!self.capture || !self.capture.isCapturing){
return;
}
// GPUImage獲取到的資料是BGRA格式。
// 而各種編碼器最適合編碼的格式還是yuv(NV12格式)。
// 所以在此將BGRA格式的視訊資料轉成yuv格式。(後面會介紹yuv和pcm格式)
// 將bgra轉為yuv
int width = imageSize.width;
int height = imageSize.height;
int w_x_h = width * height;
// 1幀yuv資料長度為 寬x高 * 3 / 2
int yuv_len = w_x_h * 3 / 2;
uint8_t *yuv_bytes = malloc(yuv_len);
//使用libyuv庫,做格式轉換。libyuv中的格式都是大端(高位存高位,低位存低位),而iOS裝置是小端(高位存低位,低位存高位),小端為BGRA,則大端為ARGB,所以這裡使用ARGBToNV12。
//self.rawBytesForImage就是美顏後的圖片資料,格式是BGRA。
//關於大端小端,請自行baidu。
//NV12格式介紹請看下一篇文章:[1小時學會:最簡單的iOS直播推流(五)yuv、pcm資料的介紹和獲取](http://www.jianshu.com/p/d5489a8fe2a9)
[self lockFramebufferForReading];
ARGBToNV12(self.rawBytesForImage, width * 4, yuv_bytes, width, yuv_bytes + w_x_h, width, width, height);
[self unlockFramebufferAfterReading];
NSData *yuvData = [NSData dataWithBytesNoCopy:yuv_bytes length:yuv_len];
//將獲取到的yuv420資料傳送出去
[self.capture sendVideoYuvData:yuvData];
}
複製程式碼
至此,已經成功使用GPUImage獲取視訊,美顏,格式轉換,準備傳送資料。還是很簡單的。
我們現在能夠使用2種方法來獲取音訊資料,接下來會介紹音視訊編碼相關內容。
文章列表
- 1小時學會:最簡單的iOS直播推流(一)專案介紹
- 1小時學會:最簡單的iOS直播推流(二)程式碼架構概述
- 1小時學會:最簡單的iOS直播推流(三)使用系統介面捕獲音視訊
- 1小時學會:最簡單的iOS直播推流(四)如何使用GPUImage,如何美顏
- 1小時學會:最簡單的iOS直播推流(五)yuv、pcm資料的介紹和獲取
- 1小時學會:最簡單的iOS直播推流(六)h264、aac、flv介紹
- 1小時學會:最簡單的iOS直播推流(七)h264/aac 硬編碼
- 1小時學會:最簡單的iOS直播推流(八)h264/aac 軟編碼
- 1小時學會:最簡單的iOS直播推流(九)flv 編碼與音視訊時間戳同步
- 1小時學會:最簡單的iOS直播推流(十)librtmp使用介紹
- 1小時學會:最簡單的iOS直播推流(十一)sps&pps和AudioSpecificConfig介紹(完結)