版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.10.08 |
前言
GPUImage
是直接利用顯卡實現(xiàn)視頻或者圖像處理的技術(shù)。感興趣可以看上面幾篇文章龄章。部分代碼上傳到刀客傳奇 - Github
1. GPUImage解析(一) —— 基本概覽(一)
2. GPUImage解析(二) —— 基本概覽(二)
3. GPUImage解析(三) —— 基本概覽(三)
4. GPUImage解析(四) —— 安裝方法及框架介紹
5. GPUImage解析(五) —— 框架中的幾個基類
6. GPUImage解析(六) —— 一個簡單的實例(一)
7. GPUImage解析(七) —— 一個簡單的實例結(jié)合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一個簡單的實例之多濾鏡視頻采集存儲(三)
9. GPUImage解析(九) —— 一個簡單的實例之GPUImageTiltShiftFilter濾鏡處理(四)
10. GPUImage解析(十) —— 一個簡單的實例之實時更改視頻的濾鏡值(五)
11. GPUImage解析(十一) —— 一個簡單的實例之視頻的疊加混合(六)
12. GPUImage解析(十二) —— 一個簡單的實例之添加水由嘉洹(七)
功能要求
實現(xiàn)視頻音頻的簡單混合,這個demo借鑒的是落影的簡書博客
,特此聲明。
功能實現(xiàn)
還是直接看代碼吧烟逊。
#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];
//添加響應(yīng)鏈
[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];
//進(jìn)度顯示
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
功能效果
下面看一下功能效果渣窜。
這里是有聲音的,但是只能讓大家看到視頻的混合了宪躯,實際是有聲音的混合的乔宿。
后記
未完,待續(xù)~~~