版本记录
| 版本号 | 时间 |
|---|---|
| V1.0 | 2017.09.05 |
前言
GPUImage是直接利用显卡实现视频或者图像处理的技术。感兴趣可以看上面几篇文章。
1. GPUImage解析(一) —— 基本概览(一)
2. GPUImage解析(二) —— 基本概览(二)
3. GPUImage解析(三) —— 基本概览(三)
4. GPUImage解析(四) —— 安装方法及框架介绍
5. GPUImage解析(五) —— 框架中的几个基类
6. GPUImage解析(六) —— 一个简单的实例(一)
7. GPUImage解析(七) —— 一个简单的实例结合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一个简单的实例之多滤镜视频采集存储(三)
9. GPUImage解析(九) —— 一个简单的实例之GPUImageTiltShiftFilter滤镜处理(四)
功能要求
实时更改滤镜GPUImageSepiaFilter的intensity值,达到实时更改视频的效果,并实现了存储。
功能实现
下面还是直接看代码。
1. JJGPUImageSliderRecordVC.m
#import "JJGPUImageSliderRecordVC.h"
#import "GPUImage.h"
#import "Masonry.h"
#import <AssetsLibrary/AssetsLibrary.h>
@interface JJGPUImageSliderRecordVC ()
@property (nonatomic, strong) GPUImageVideoCamera *videoCamera;
@property (nonatomic, strong) GPUImageSepiaFilter *sepiaFilter;
@property (nonatomic, strong) GPUImageView *imageView;
@property (nonatomic, strong) UIButton *recordButton;
@property (nonatomic, strong) UILabel *timeDisplayLabel;
@property (nonatomic, assign) NSInteger timeValue;
@property (nonatomic, strong) UISlider *slider;
@property (nonatomic, strong) GPUImageMovieWriter *movieWriter;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation JJGPUImageSliderRecordVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupUI];
[self setupConfiguratuon];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.navigationController.navigationBarHidden = NO;
}
#pragma mark - Object Private Function
- (void)setupUI
{
//实例化GPUImageView
self.imageView = [[GPUImageView alloc] initWithFrame:self.view.frame];
[self.view addSubview:self.imageView];
//按钮实例化
self.recordButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.recordButton setTitle:@"录制" forState:UIControlStateNormal];
[self.recordButton setTitle:@"结束" forState:UIControlStateSelected];
[self.recordButton addTarget:self action:@selector(recordButtonDidClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.recordButton];
[self.recordButton sizeToFit];
[self.recordButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.imageView.mas_bottom).offset(-50);
make.centerX.equalTo(self.imageView);
}];
//显示时间label实例化
self.timeDisplayLabel = [[UILabel alloc] init];
self.timeDisplayLabel.hidden = YES;
self.timeDisplayLabel.textColor = [UIColor redColor];
self.timeDisplayLabel.font = [UIFont systemFontOfSize:16.0];
[self.view addSubview:self.timeDisplayLabel];
[self.timeDisplayLabel sizeToFit];
[self.timeDisplayLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.imageView);
make.bottom.equalTo(self.recordButton.mas_top).offset(-15.0);
}];
//滑动条
self.slider = [[UISlider alloc] init];
[self.slider addTarget:self action:@selector(sliderDidSlide:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:self.slider];
[self.slider mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.recordButton.mas_top).offset(-40.0);
make.centerX.equalTo(self.slider);
make.height.equalTo(@30);
make.width.equalTo(@(self.view.bounds.size.height));
}];
}
- (void)setupConfiguratuon
{
//实例化GPUImageVideoCamera
self.videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
self.videoCamera.outputImageOrientation = [UIApplication sharedApplication].statusBarOrientation;
//实例化
self.sepiaFilter = [[GPUImageSepiaFilter alloc] init];
[self.videoCamera addTarget:self.sepiaFilter];
[self.sepiaFilter addTarget:self.imageView];
[self.videoCamera startCameraCapture];
}
#pragma mark - Action && Notification
- (void)recordButtonDidClick:(UIButton *)button
{
button.selected = !button.selected;
NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie4.m4v"];
NSURL *movieURL = [NSURL fileURLWithPath:savePath];
if (button.selected) {
unlink([savePath UTF8String]);
self.movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)];
self.movieWriter.encodingLiveVideo = YES;
[self.sepiaFilter addTarget:self.movieWriter];
self.videoCamera.audioEncodingTarget = self.movieWriter;
[self.movieWriter startRecording];
self.timeValue = 0;
self.timeDisplayLabel.hidden = NO;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerWork:) userInfo:nil repeats:YES];
}
else {
self.timeDisplayLabel.hidden = YES;
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
[self.sepiaFilter removeTarget:self.movieWriter];
self.videoCamera.audioEncodingTarget = nil;
[self.movieWriter finishRecording];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(savePath))
{
[library writeVideoAtPathToSavedPhotosAlbum:movieURL completionBlock:^(NSURL *assetURL, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"保存失败");
}
else {
NSLog(@"保存成功");
}
});
}];
}
}
}
- (void)timerWork:(NSTimer *)timer
{
NSLog(@"%ld", self.timeValue);
self.timeDisplayLabel.text = [NSString stringWithFormat:@"录制时间:%ld", self.timeValue ++];
[self.timeDisplayLabel sizeToFit];
}
- (void)sliderDidSlide:(UISlider *)slider
{
NSInteger factor = 5;
[self.sepiaFilter setIntensity:slider.value * factor];
}
@end
下面看输出结果
2017-09-05 16:32:53.614617+0800 JJOC[2153:1364795] 0
2017-09-05 16:32:54.614526+0800 JJOC[2153:1364795] 1
2017-09-05 16:32:55.614576+0800 JJOC[2153:1364795] 2
2017-09-05 16:32:56.614534+0800 JJOC[2153:1364795] 3
2017-09-05 16:32:57.615191+0800 JJOC[2153:1364795] 4
2017-09-05 16:32:58.614548+0800 JJOC[2153:1364795] 5
2017-09-05 16:32:59.614562+0800 JJOC[2153:1364795] 6
2017-09-05 16:33:00.614702+0800 JJOC[2153:1364795] 7
2017-09-05 16:33:01.619716+0800 JJOC[2153:1364795] 8
2017-09-05 16:33:02.614597+0800 JJOC[2153:1364795] 9
2017-09-05 16:33:03.614647+0800 JJOC[2153:1364795] 10
2017-09-05 16:33:04.852523+0800 JJOC[2153:1364795] 保存成功
功能效果
下面我们就看一下功能实现的效果。




由于简书最多只能上传5M,所以gif我只是录制的一部分,大家凑合着看吧,其实还是可以看到效果的,滤镜效果发生了改变,为了效果明显,在代码中我将slider的值乘以5作为了滤镜强度因子的数值。
后记
未完,待续~~

