版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.09.06 |
前言
GPUImage
是直接利用显卡实现视频或者图像处理的技术。感兴趣可以看上面几篇文章。
1. GPUImage解析(一) —— 基本概览(一)
2. GPUImage解析(二) —— 基本概览(二)
3. GPUImage解析(三) —— 基本概览(三)
4. GPUImage解析(四) —— 安装方法及框架介绍
5. GPUImage解析(五) —— 框架中的几个基类
6. GPUImage解析(六) —— 一个简单的实例(一)
7. GPUImage解析(七) —— 一个简单的实例结合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一个简单的实例之多滤镜视频采集存储(三)
9. GPUImage解析(九) —— 一个简单的实例之GPUImageTiltShiftFilter滤镜处理(四)
10. GPUImage解析(十) —— 一个简单的实例之实时更改视频的滤镜值(五)
功能要求
实现给定的视频和摄像头采集视频的混合叠加。
功能实现
下面我们还是老规矩看代码。
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
功能效果
下面我们就看一下实现效果。
可见,本地视频和摄像头采集后的视频混合了。
后记
未完,待续~~~