GPUImage解析(十) —— 一個(gè)簡(jiǎn)單的實(shí)例之實(shí)時(shí)更改視頻的濾鏡值(五)

版本記錄

版本號(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í)更改濾鏡GPUImageSepiaFilterintensity值,達(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ù)~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容