版本記錄
| 版本號(hào) | 時(shí)間 |
|---|---|
| V1.0 | 2017.09.05 |
前言
GPUImage是直接利用顯卡實(shí)現(xiàn)視頻或者圖像處理的技術(shù)。感興趣可以看上面幾篇文章。
1. GPUImage解析(一) —— 基本概覽(一)
2. GPUImage解析(二) —— 基本概覽(二)
3. GPUImage解析(三) —— 基本概覽(三)
4. GPUImage解析(四) —— 安裝方法及框架介紹
5. GPUImage解析(五) —— 框架中的幾個(gè)基類
6. GPUImage解析(六) —— 一個(gè)簡(jiǎn)單的實(shí)例(一)
7. GPUImage解析(七) —— 一個(gè)簡(jiǎn)單的實(shí)例結(jié)合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一個(gè)簡(jiǎn)單的實(shí)例之多濾鏡視頻采集存儲(chǔ)(三)
9. GPUImage解析(九) —— 一個(gè)簡(jiǎn)單的實(shí)例之GPUImageTiltShiftFilter濾鏡處理(四)
功能要求
實(shí)時(shí)更改濾鏡GPUImageSepiaFilter的intensity值,達(dá)到實(shí)時(shí)更改視頻的效果,并實(shí)現(xiàn)了存儲(chǔ)。
功能實(shí)現(xiàn)
下面還是直接看代碼。
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
{
//實(shí)例化GPUImageView
self.imageView = [[GPUImageView alloc] initWithFrame:self.view.frame];
[self.view addSubview:self.imageView];
//按鈕實(shí)例化
self.recordButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.recordButton setTitle:@"錄制" forState:UIControlStateNormal];
[self.recordButton setTitle:@"結(jié)束" 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);
}];
//顯示時(shí)間label實(shí)例化
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);
}];
//滑動(dòng)條
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
{
//實(shí)例化GPUImageVideoCamera
self.videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
self.videoCamera.outputImageOrientation = [UIApplication sharedApplication].statusBarOrientation;
//實(shí)例化
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:@"錄制時(shí)間:%ld", self.timeValue ++];
[self.timeDisplayLabel sizeToFit];
}
- (void)sliderDidSlide:(UISlider *)slider
{
NSInteger factor = 5;
[self.sepiaFilter setIntensity:slider.value * factor];
}
@end
下面看輸出結(jié)果
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] 保存成功
功能效果
下面我們就看一下功能實(shí)現(xiàn)的效果。




由于簡(jiǎn)書(shū)最多只能上傳5M,所以gif我只是錄制的一部分,大家湊合著看吧,其實(shí)還是可以看到效果的,濾鏡效果發(fā)生了改變,為了效果明顯,在代碼中我將slider的值乘以5作為了濾鏡強(qiáng)度因子的數(shù)值。
后記
未完,待續(xù)~~
