版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.10.08 |
前言
GPUImage
是直接利用显卡实现视频或者图像处理的技术。感兴趣可以看上面几篇文章。部分代码上传到刀客传奇 - Github
1. GPUImage解析(一) —— 基本概览(一)
2. GPUImage解析(二) —— 基本概览(二)
3. GPUImage解析(三) —— 基本概览(三)
4. GPUImage解析(四) —— 安装方法及框架介绍
5. GPUImage解析(五) —— 框架中的几个基类
6. GPUImage解析(六) —— 一个简单的实例(一)
7. GPUImage解析(七) —— 一个简单的实例结合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一个简单的实例之多滤镜视频采集存储(三)
9. GPUImage解析(九) —— 一个简单的实例之GPUImageTiltShiftFilter滤镜处理(四)
10. GPUImage解析(十) —— 一个简单的实例之实时更改视频的滤镜值(五)
11. GPUImage解析(十一) —— 一个简单的实例之视频的叠加混合(六)
12. GPUImage解析(十二) —— 一个简单的实例之添加水印(七)
功能要求
实现视频音频的简单混合,这个demo借鉴的是落影的简书博客
,特此声明。
功能实现
还是直接看代码吧。
#import "ViewController.h"
#import "GPUImage.h"
#import "THImageMovieWriter.h"
#import "THImageMovie.h"
#import <AssetsLibrary/ALAssetsLibrary.h>
@interface ViewController ()
@property (nonatomic, strong) UILabel *displayLabel;
@property (nonatomic, strong) THImageMovieWriter *movieWriter;
@property (nonatomic, strong) dispatch_group_t recordDispatchGroup;
@property (nonatomic, strong) THImageMovie *imageMovieOne;
@property (nonatomic, strong) THImageMovie *imageMovieTwo;
@property (nonatomic, strong) GPUImageOutput <GPUImageInput> *filter;
@property (nonatomic, strong) GPUImageView *imageView;
@end
@implementation ViewController
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
[self setupConfiguration];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Object Private Function
- (void)setupUI
{
//展示视图
GPUImageView *imageView = [[GPUImageView alloc] initWithFrame:self.view.frame];
self.view = imageView;
self.imageView = imageView;
//Label
self.displayLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 150, 150)];
self.displayLabel.textColor = [UIColor redColor];
[self.view addSubview:self.displayLabel];
}
- (void)setupConfiguration
{
self.filter = [[GPUImageDissolveBlendFilter alloc] init];
GPUImageDissolveBlendFilter *filter = (GPUImageDissolveBlendFilter *)self.filter;
[filter setMix:0.5];
//播放
NSURL *demoURL1 = [[NSBundle mainBundle] URLForResource:@"abc" withExtension:@"mp4"];
self.imageMovieOne = [[THImageMovie alloc] initWithURL:demoURL1];
self.imageMovieOne.runBenchmark = YES;
self.imageMovieOne.playAtActualSpeed = YES;
NSURL *demoURL2 = [[NSBundle mainBundle] URLForResource:@"def" withExtension:@"mp4"];
self.imageMovieTwo = [[THImageMovie alloc] initWithURL:demoURL2];
self.imageMovieTwo.runBenchmark = YES;
self.imageMovieTwo.playAtActualSpeed = YES;
NSArray *imageMovieArr = @[self.imageMovieOne, self.imageMovieTwo];
//存储路径
NSString *pathStr = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathStr UTF8String]);
NSURL *movieURL = [NSURL URLWithString:pathStr];
//写入
self.movieWriter = [[THImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640, 480) movies:imageMovieArr];
//添加响应链
[self.imageMovieOne addTarget:filter];
[self.imageMovieTwo addTarget:filter];
//显示
[filter addTarget:self.imageView];
[filter addTarget:self.movieWriter];
[self.imageMovieOne startProcessing];
[self.imageMovieTwo startProcessing];
[self.movieWriter startRecording];
//进度显示
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgress)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[displayLink setPaused:NO];
//存储
__weak typeof(self) weakSelf = self;
[self.movieWriter setCompletionBlock:^{
__strong typeof(self) strongSelf = weakSelf;
[filter removeTarget:strongSelf.self.movieWriter];
[strongSelf.imageMovieOne endProcessing];
[strongSelf.imageMovieTwo endProcessing];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(pathStr))
{
[library writeVideoAtPathToSavedPhotosAlbum:movieURL completionBlock:^(NSURL *assetURL, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"保存失败");
} else {
NSLog(@"保存成功");
}
});
}];
}
else {
NSLog(@"error mssg)");
}
}];
}
- (void)updateProgress
{
self.displayLabel.text = [NSString stringWithFormat:@"Progress:%d%%", (int)(self.imageMovieOne.progress * 100)];
[self.displayLabel sizeToFit];
}
@end
功能效果
下面看一下功能效果。
这里是有声音的,但是只能让大家看到视频的混合了,实际是有声音的混合的。
后记
未完,待续~~~