版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.09.06 |
前言
GPUImage
是直接利用顯卡實現(xiàn)視頻或者圖像處理的技術卫枝。感興趣可以看上面幾篇文章。
1. GPUImage解析(一) —— 基本概覽(一)
2. GPUImage解析(二) —— 基本概覽(二)
3. GPUImage解析(三) —— 基本概覽(三)
4. GPUImage解析(四) —— 安裝方法及框架介紹
5. GPUImage解析(五) —— 框架中的幾個基類
6. GPUImage解析(六) —— 一個簡單的實例(一)
7. GPUImage解析(七) —— 一個簡單的實例結(jié)合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一個簡單的實例之多濾鏡視頻采集存儲(三)
9. GPUImage解析(九) —— 一個簡單的實例之GPUImageTiltShiftFilter濾鏡處理(四)
10. GPUImage解析(十) —— 一個簡單的實例之實時更改視頻的濾鏡值(五)
功能要求
實現(xiàn)給定的視頻和攝像頭采集視頻的混合疊加末早。
功能實現(xiàn)
下面我們還是老規(guī)矩看代碼。
1. JJGPUImageMPVC.h
#import <UIKit/UIKit.h>
@interface JJGPUImageMPVC : UIViewController
@end
2. JJGPUImageMPVC.m
#import "JJGPUImageMPVC.h"
#import "GPUImage.h"
#import "Masonry.h"
#import <AssetsLibrary/AssetsLibrary.h>
@interface JJGPUImageMPVC ()
@property (nonatomic, strong) GPUImageView *imageView;
@property (nonatomic, strong) GPUImageDissolveBlendFilter *blendFilter;
@property (nonatomic, strong) UILabel *progressLabel;
@property (nonatomic, strong) GPUImageMovie *imageMovie;
@property (nonatomic, strong) GPUImageMovieWriter *movieWriter;
@property (nonatomic, strong) GPUImageVideoCamera *videoCamera;
@property (nonatomic, strong) GPUImageOutput *imageOut;
@property (nonatomic, copy) NSString *moviePath;
@property (nonatomic, strong) NSURL *movieURL;
@end
@implementation JJGPUImageMPVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupUI];
[self setupConfiguration];
}
- (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)setupConfiguration
{
//實例化GPUImageDissolveBlendFilter
self.blendFilter = [[GPUImageDissolveBlendFilter alloc] init];
[self.blendFilter setMix:0.5];
//播放視頻
NSURL *demoURL = [[NSBundle mainBundle] URLForResource:@"lili" withExtension:@"mp4"];
self.imageMovie = [[GPUImageMovie alloc] initWithURL:demoURL];
self.imageMovie.runBenchmark = YES;
self.imageMovie.playAtActualSpeed = YES;
//實例化GPUImageVideoCamera
self.videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
self.videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
//路徑
NSString *moviePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([moviePath UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
self.moviePath = moviePath;
self.movieURL = movieURL;
//實例化GPUImageMovieWriter
GPUImageMovieWriter *movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0, 480.0)];
self.movieWriter = movieWriter;
[self.videoCamera addTarget:self.blendFilter];
[self.imageMovie addTarget:self.blendFilter];
self.movieWriter.shouldPassthroughAudio = NO;
self.imageMovie.audioEncodingTarget = self.movieWriter;
self.movieWriter.encodingLiveVideo = NO;
//開始并顯示
[self.blendFilter addTarget:self.imageView];
[self.blendFilter addTarget:self.movieWriter];
[self.videoCamera startCameraCapture];
[self.movieWriter startRecording];
[self.imageMovie startProcessing];
//定時
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(linkDidWorkUpdateProgress)];
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
link.paused = NO;
//存儲
__weak typeof(self) weakSelf = self;
[movieWriter setCompletionBlock:^{
__strong typeof(self) strongSelf = weakSelf;
[strongSelf.blendFilter removeTarget:strongSelf.movieWriter];
[strongSelf.movieWriter finishRecording];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(strongSelf.moviePath))
{
[library writeVideoAtPathToSavedPhotosAlbum:strongSelf.movieURL completionBlock:^(NSURL *assetURL, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"保存失敗");
}
else {
NSLog(@"保存成功");
}
});
}];
}
}];
}
- (void)setupUI
{
//實例化GPUImageView
self.imageView = [[GPUImageView alloc] initWithFrame:self.view.frame];
[self.view addSubview:self.imageView];
//實例化UILabel
self.progressLabel = [[UILabel alloc] init];
self.progressLabel.textColor = [UIColor redColor];
self.progressLabel.font = [UIFont systemFontOfSize:20.0];
self.progressLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.progressLabel];
[self.progressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.imageView);
make.bottom.equalTo(self.imageView).offset(-20.0);
make.height.equalTo(@25);
make.width.equalTo(self.imageView);
}];
}
#pragma mark - Action && Notification
- (void)linkDidWorkUpdateProgress
{
self.progressLabel.text = [NSString stringWithFormat:@"Progress = %.1f", self.imageMovie.progress * 100];
}
@end
功能效果
下面我們就看一下實現(xiàn)效果。
可見竞滓,本地視頻和攝像頭采集后的視頻混合了沦偎。
后記
未完疫向,待續(xù)~~~