1小时学会:最简单的iOS直播推流(四)如何使用GPUImage,如何美颜

最简单的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. 1小时学会:最简单的iOS直播推流(一)项目介绍
  2. 1小时学会:最简单的iOS直播推流(二)代码架构概述
  3. 1小时学会:最简单的iOS直播推流(三)使用系统接口捕获音视频
  4. 1小时学会:最简单的iOS直播推流(四)如何使用GPUImage,如何美颜
  5. 1小时学会:最简单的iOS直播推流(五)yuv、pcm数据的介绍和获取
  6. 1小时学会:最简单的iOS直播推流(六)h264、aac、flv介绍
  7. 1小时学会:最简单的iOS直播推流(七)h264/aac 硬编码
  8. 1小时学会:最简单的iOS直播推流(八)h264/aac 软编码
  9. 1小时学会:最简单的iOS直播推流(九)flv 编码与音视频时间戳同步
  10. 1小时学会:最简单的iOS直播推流(十)librtmp使用介绍
  11. 1小时学会:最简单的iOS直播推流(十一)sps&pps和AudioSpecificConfig介绍(完结)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容