GPUImage录像的一些备忘

From: http://www.hudongdong.com/ios/530.html

GPUImage在加滤镜、图像处理上面集成的很完善,现在在使用的时候碰到的一些问题做下总结备忘,这些都是弄了很长时间才找到原因,如果碰到相似的可以节省下时间。当然简单的使用也可以看这个文章《IOS使用GPUImage滤镜初级试水

1、摄像头左右相反

使用GPU录像的时候,如果前置摄像头在左右是相反的,那么需要设置下镜像设置了

//如果是调用前置摄像头就发现成的像是左右相反了,就看下是不是开启了镜像
self.videoCamera.horizontallyMirrorFrontFacingCamera = YES;
self.videoCamera.horizontallyMirrorRearFacingCamera = NO;

2、开始录像的时候会图像会高亮下

如果录像的额时候,图像高亮下,可以在初始化GPUImageVideoCamera的时候,加上

[m_videoCamera addAudioInputsAndOutputs];

这个是为camera的增加的声音输入,但是这个如果是在一个界面的时候,频繁的增加有可能会造成录制的画面卡顿,所以可以在界面初始化Viewdidload的时候,初始化camera的时候加上这个代码。

3、第一帧偶尔黑屏

如果第一帧黑屏,应该是在开始录制等时间的问题,可以把要使用的视频第一帧裁减掉,裁剪视频的方案晚点会写成一个总结。

4、暂停/重录视频

如果仅仅是暂停录制,不暂停摄像头画面

//录制暂停
[m_movieWriter setPaused:true];
//录制继续
[m_movieWriter setPaused:false];

如果是暂停录制,并且也要暂停摄像头画面

//录制暂停
[m_movieWriter setPaused:true];
//摄像头暂停
[m_videoCamera pauseCameraCapture];
//录制继续
[m_movieWriter setPaused:false];
//摄像头继续
[m_videoCamera resumeCameraCapture];

5、暂停又重录会黑屏或者最后几秒有画面没声音

可以进入GPUImageMovieWriter.m中,在

- (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;

把里面的一段函数先注销掉

if (offsetTime.value > 0) {
     CFRelease(audioBuffer);
     audioBuffer = [self adjustTime:audioBuffer by:offsetTime];
     CFRetain(audioBuffer);
}

6、视频录制的代码

6.1、设置变量

//摄像头
    GPUImageVideoCamera *m_videoCamera;
    GPUImageFilter *m_customFilter;
    GPUImageView *m_filteredVideoView;
    //录制
    GPUImageMovieWriter *m_movieWriter;
    NSMutableDictionary * videoSettings; //字面意思.视频设置
    NSDictionary * audioSettings; //声音设置

6.2、初始化摄像头

m_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1280x720 cameraPosition:AVCaptureDevicePositionBack];
//    [m_videoCamera setFrameRate:60];
    //前置摄像头
    m_videoCamera.horizontallyMirrorFrontFacingCamera = YES;
    m_videoCamera.horizontallyMirrorRearFacingCamera = NO;
    m_videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
    [m_videoCamera addAudioInputsAndOutputs];
//    m_customFilter = [[AmomoFilter alloc] init];
    m_customFilter = [[GPUImageFilter alloc] init];

    m_filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0,0.0,JLXScreenSize.width,JLXScreenSize.height)];
    // Add the view somewhere so it's visible
    [self.view addSubview:m_filteredVideoView];

    //添加滤镜
    [m_videoCamera addTarget:m_customFilter];
    [m_customFilter addTarget:m_filteredVideoView];
    [m_videoCamera startCameraCapture];

6.3、初始化movieWriter

-(void)initcustomWriter
{
    oldVideoPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie4.mov"];
    unlink([oldVideoPath UTF8String]); // 如果已经存在文件,AVAssetWriter会有异常,删除旧文件
    NSURL *movieURL = [JLXNetTools conVertToURL:oldVideoPath];

    //视频设置
    videoSettings = [[NSMutableDictionary alloc] init];
    [videoSettings setObject:AVVideoCodecH264 forKey:AVVideoCodecKey];
    [videoSettings setObject:[NSNumber numberWithInteger:720] forKey:AVVideoWidthKey]; //视频的宽度,这里最好是定义imageCamera时候的宽度
    [videoSettings setObject:[NSNumber numberWithInteger:1280] forKey:AVVideoHeightKey]; //视频的高度.同上

    //音频设置
    AudioChannelLayout channelLayout;
    memset(&channelLayout, 0, sizeof(AudioChannelLayout));
    channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
    audioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                     [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                     [ NSNumber numberWithInt: 2 ], AVNumberOfChannelsKey,
                     [ NSNumber numberWithFloat: 16000.0 ], AVSampleRateKey,
                     [ NSData dataWithBytes:&channelLayout length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
                     [ NSNumber numberWithInt: 32000 ], AVEncoderBitRateKey,
                     nil];

    m_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(720, 1280) fileType:AVFileTypeQuickTimeMovie outputSettings:videoSettings];
//    [m_movieWriter setHasAudioTrack:YES audioSettings:audioSettings];
    [m_movieWriter setHasAudioTrack:true];
    m_videoCamera.audioEncodingTarget = m_movieWriter; //设置声音
//    m_movieWriter.assetWriter.movieFragmentInterval = kCMTimeInvalid; //Couldn't write a frame
    m_movieWriter.encodingLiveVideo = YES;
    [m_customFilter addTarget:m_movieWriter];
}

6.4、开始录制

[m_movieWriter startRecording];

6.5、结束录制

[m_movieWriter finishRecordingWithCompletionHandler:^{
   }];
[m_customFilter removeTarget:m_movieWriter];
m_videoCamera.audioEncodingTarget = nil;

6.6、暂停/重录视频

如果仅仅是暂停录制,不暂停摄像头画面

//录制暂停
[m_movieWriter setPaused:true];
//录制继续
[m_movieWriter setPaused:false];

如果是暂停录制,并且也要暂停摄像头画面

//录制暂停
[m_movieWriter setPaused:true];
//摄像头暂停
[m_videoCamera pauseCameraCapture];
//录制继续
[m_movieWriter setPaused:false];
//摄像头继续
[m_videoCamera resumeCameraCapture];

6.7、取消录制

[m_movieWriter cancelRecording];

七、视频滤镜

7.1、一个滤镜

    //添加滤镜
m_customFilter = [[GPUImageFilter alloc] init];
[m_videoCamera addTarget:m_customFilter];
[m_customFilter addTarget:m_filteredVideoView];
[m_customFilter addTarget:m_movieWriter];

7.2、多个滤镜

多个滤镜需要使用滤镜组

//漫画
    GPUImageSketchFilter *disFilter = [[GPUImageSketchFilter alloc] init];
    //褐色
    GPUImageSepiaFilter* sepiaFilter = [[GPUImageSepiaFilter alloc] init];

    filterGroup = [[GPUImageFilterGroup alloc] init];
    [filterGroup addFilter:disFilter];
    [filterGroup addFilter:sepiaFilter];

    //先后顺序
    [disFilter addTarget:sepiaFilter];

    //开始的滤镜
    [filterGroup setInitialFilters:[NSArray arrayWithObject:disFilter]];
    [filterGroup setTerminalFilter:sepiaFilter];

    [filterGroup addTarget:m_filteredVideoView];
    [m_videoCamera addTarget:filterGroup];

    [filterGroup addTarget:m_movieWriter];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
GPUImage是Brad Larson在github托管的一个开源项目,项目实现了图片滤镜、摄像头实时滤镜,该项目的优点不但在于滤镜很多,而且处理效果是基于GPU的,比使用CPU性能更高。
下载地址是:https://github.com/BradLarson/GPUImage
已有的一些filter介绍:
#import "GPUImageBrightnessFilter.h" //亮度
#import "GPUImageExposureFilter.h" //曝光
#import "GPUImageContrastFilter.h" //对比度
#import "GPUImageSaturationFilter.h" //饱和度
#import "GPUImageGammaFilter.h" //伽马线
#import "GPUImageColorInvertFilter.h" //反色
#import "GPUImageSepiaFilter.h" //褐色(怀旧)
#import "GPUImageLevelsFilter.h" //色阶
#import "GPUImageGrayscaleFilter.h" //灰度
#import "GPUImageHistogramFilter.h" //色彩直方图,显示在图片上
#import "GPUImageHistogramGenerator.h" //色彩直方图
#import "GPUImageRGBFilter.h" //RGB
#import "GPUImageToneCurveFilter.h" //色调曲线
#import "GPUImageMonochromeFilter.h" //单色
#import "GPUImageOpacityFilter.h" //不透明度
#import "GPUImageHighlightShadowFilter.h" //提亮阴影
#import "GPUImageFalseColorFilter.h" //色彩替换(替换亮部和暗部色彩)
#import "GPUImageHueFilter.h" //色度
#import "GPUImageChromaKeyFilter.h" //色度键
#import "GPUImageWhiteBalanceFilter.h" //白平横
#import "GPUImageAverageColor.h" //像素平均色值
#import "GPUImageSolidColorGenerator.h" //纯色
#import "GPUImageLuminosity.h" //亮度平均
#import "GPUImageAverageLuminanceThresholdFilter.h" //像素色值亮度平均,图像黑白(有类似漫画效果)
#import "GPUImageLookupFilter.h" //lookup 色彩调整
#import "GPUImageAmatorkaFilter.h" //Amatorka lookup
#import "GPUImageMissEtikateFilter.h" //MissEtikate lookup
#import "GPUImageSoftEleganceFilter.h" //SoftElegance lookup
#pragma mark - 图像处理 Handle Image
#import "GPUImageCrosshairGenerator.h" //十字
#import "GPUImageLineGenerator.h" //线条
#import "GPUImageTransformFilter.h" //形状变化
#import "GPUImageCropFilter.h" //剪裁
#import "GPUImageSharpenFilter.h" //锐化
#import "GPUImageUnsharpMaskFilter.h" //反遮罩锐化
#import "GPUImageFastBlurFilter.h" //模糊
#import "GPUImageGaussianBlurFilter.h" //高斯模糊
#import "GPUImageGaussianSelectiveBlurFilter.h" //高斯模糊,选择部分清晰
#import "GPUImageBoxBlurFilter.h" //盒状模糊
#import "GPUImageTiltShiftFilter.h" //条纹模糊,中间清晰,上下两端模糊
#import "GPUImageMedianFilter.h" //中间值,有种稍微模糊边缘的效果
#import "GPUImageBilateralFilter.h" //双边模糊
#import "GPUImageErosionFilter.h" //侵蚀边缘模糊,变黑白
#import "GPUImageRGBErosionFilter.h" //RGB侵蚀边缘模糊,有色彩
#import "GPUImageDilationFilter.h" //扩展边缘模糊,变黑白
#import "GPUImageRGBDilationFilter.h" //RGB扩展边缘模糊,有色彩
#import "GPUImageOpeningFilter.h" //黑白色调模糊
#import "GPUImageRGBOpeningFilter.h" //彩色模糊
#import "GPUImageClosingFilter.h" //黑白色调模糊,暗色会被提亮
#import "GPUImageRGBClosingFilter.h" //彩色模糊,暗色会被提亮
#import "GPUImageLanczosResamplingFilter.h" //Lanczos重取样,模糊效果
#import "GPUImageNonMaximumSuppressionFilter.h" //非最大抑制,只显示亮度最高的像素,其他为黑
#import "GPUImageThresholdedNonMaximumSuppressionFilter.h" //与上相比,像素丢失更多
#import "GPUImageSobelEdgeDetectionFilter.h" //Sobel边缘检测算法(白边,黑内容,有点漫画的反色效果)
#import "GPUImageCannyEdgeDetectionFilter.h" //Canny边缘检测算法(比上更强烈的黑白对比度)
#import "GPUImageThresholdEdgeDetectionFilter.h" //阈值边缘检测(效果与上差别不大)
#import "GPUImagePrewittEdgeDetectionFilter.h" //普瑞维特(Prewitt)边缘检测(效果与Sobel差不多,貌似更平滑)
#import "GPUImageXYDerivativeFilter.h" //XYDerivative边缘检测,画面以蓝色为主,绿色为边缘,带彩色
#import "GPUImageHarrisCornerDetectionFilter.h" //Harris角点检测,会有绿色小十字显示在图片角点处
#import "GPUImageNobleCornerDetectionFilter.h" //Noble角点检测,检测点更多
#import "GPUImageShiTomasiFeatureDetectionFilter.h" //ShiTomasi角点检测,与上差别不大
#import "GPUImageMotionDetector.h" //动作检测
#import "GPUImageHoughTransformLineDetector.h" //线条检测
#import "GPUImageParallelCoordinateLineTransformFilter.h" //平行线检测
#import "GPUImageLocalBinaryPatternFilter.h" //图像黑白化,并有大量噪点
#import "GPUImageLowPassFilter.h" //用于图像加亮
#import "GPUImageHighPassFilter.h" //图像低于某值时显示为黑
#pragma mark - 视觉效果 Visual Effect
#import "GPUImageSketchFilter.h" //素描
#import "GPUImageThresholdSketchFilter.h" //阀值素描,形成有噪点的素描
#import "GPUImageToonFilter.h" //卡通效果(黑色粗线描边)
#import "GPUImageSmoothToonFilter.h" //相比上面的效果更细腻,上面是粗旷的画风
#import "GPUImageKuwaharaFilter.h" //桑原(Kuwahara)滤波,水粉画的模糊效果;处理时间比较长,慎用
#import "GPUImageMosaicFilter.h" //黑白马赛克
#import "GPUImagePixellateFilter.h" //像素化
#import "GPUImagePolarPixellateFilter.h" //同心圆像素化
#import "GPUImageCrosshatchFilter.h" //交叉线阴影,形成黑白网状画面
#import "GPUImageColorPackingFilter.h" //色彩丢失,模糊(类似监控摄像效果)
#import "GPUImageVignetteFilter.h" //晕影,形成黑色圆形边缘,突出中间图像的效果
#import "GPUImageSwirlFilter.h" //漩涡,中间形成卷曲的画面
#import "GPUImageBulgeDistortionFilter.h" //凸起失真,鱼眼效果
#import "GPUImagePinchDistortionFilter.h" //收缩失真,凹面镜
#import "GPUImageStretchDistortionFilter.h" //伸展失真,哈哈镜
#import "GPUImageGlassSphereFilter.h" //水晶球效果
#import "GPUImageSphereRefractionFilter.h" //球形折射,图形倒立
#import "GPUImagePosterizeFilter.h" //色调分离,形成噪点效果
#import "GPUImageCGAColorspaceFilter.h" //CGA色彩滤镜,形成黑、浅蓝、紫色块的画面
#import "GPUImagePerlinNoiseFilter.h" //柏林噪点,花边噪点
#import "GPUImage3x3ConvolutionFilter.h" //3x3卷积,高亮大色块变黑,加亮边缘、线条等
#import "GPUImageEmbossFilter.h" //浮雕效果,带有点3d的感觉
#import "GPUImagePolkaDotFilter.h" //像素圆点花样
#import "GPUImageHalftoneFilter.h" //点染,图像黑白化,由黑点构成原图的大致图形
#pragma mark - 混合模式 Blend
#import "GPUImageMultiplyBlendFilter.h" //通常用于创建阴影和深度效果
#import "GPUImageNormalBlendFilter.h" //正常
#import "GPUImageAlphaBlendFilter.h" //透明混合,通常用于在背景上应用前景的透明度
#import "GPUImageDissolveBlendFilter.h" //溶解
#import "GPUImageOverlayBlendFilter.h" //叠加,通常用于创建阴影效果
#import "GPUImageDarkenBlendFilter.h" //加深混合,通常用于重叠类型
#import "GPUImageLightenBlendFilter.h" //减淡混合,通常用于重叠类型
#import "GPUImageSourceOverBlendFilter.h" //源混合
#import "GPUImageColorBurnBlendFilter.h" //色彩加深混合
#import "GPUImageColorDodgeBlendFilter.h" //色彩减淡混合
#import "GPUImageScreenBlendFilter.h" //屏幕包裹,通常用于创建亮点和镜头眩光
#import "GPUImageExclusionBlendFilter.h" //排除混合
#import "GPUImageDifferenceBlendFilter.h" //差异混合,通常用于创建更多变动的颜色
#import "GPUImageSubtractBlendFilter.h" //差值混合,通常用于创建两个图像之间的动画变暗模糊效果
#import "GPUImageHardLightBlendFilter.h" //强光混合,通常用于创建阴影效果
#import "GPUImageSoftLightBlendFilter.h" //柔光混合
#import "GPUImageChromaKeyBlendFilter.h" //色度键混合
#import "GPUImageMaskFilter.h" //遮罩混合
#import "GPUImageHazeFilter.h" //朦胧加暗
#import "GPUImageLuminanceThresholdFilter.h" //亮度阈
#import "GPUImageAdaptiveThresholdFilter.h" //自适应阈值
#import "GPUImageAddBlendFilter.h" //通常用于创建两个图像之间的动画变亮模糊效果
#import "GPUImageDivideBlendFilter.h" //通常用于创建两个图像之间的动画变暗模糊效果
Author

陈昭

Posted on

2017-05-11

Updated on

2021-12-27

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

Kommentare

You forgot to set the shortname for Disqus. Please set it in _config.yml.