版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.09.14 |
前言
GPUImage
是直接利用顯卡實(shí)現(xiàn)視頻或者圖像處理的技術(shù)茬射。感興趣可以看上面幾篇文章。
1. GPUImage解析(一) —— 基本概覽(一)
2. GPUImage解析(二) —— 基本概覽(二)
3. GPUImage解析(三) —— 基本概覽(三)
4. GPUImage解析(四) —— 安裝方法及框架介紹
5. GPUImage解析(五) —— 框架中的幾個(gè)基類
6. GPUImage解析(六) —— 一個(gè)簡單的實(shí)例(一)
7. GPUImage解析(七) —— 一個(gè)簡單的實(shí)例結(jié)合GPUImageVideoCamera(二)
8. GPUImage解析(八) —— 一個(gè)簡單的實(shí)例之多濾鏡視頻采集存儲(chǔ)(三)
9. GPUImage解析(九) —— 一個(gè)簡單的實(shí)例之GPUImageTiltShiftFilter濾鏡處理(四)
10. GPUImage解析(十) —— 一個(gè)簡單的實(shí)例之實(shí)時(shí)更改視頻的濾鏡值(五)
11. GPUImage解析(十一) —— 一個(gè)簡單的實(shí)例之視頻的疊加混合(六)
功能要求
實(shí)現(xiàn)視頻添加水印的效果。
功能實(shí)現(xiàn)
下面看示例代碼霜定。
#import "JJGPUWatermarkVC.h"
#import "GPUImage.h"
#import <AssetsLibrary/ALAssetsLibrary.h>
#import "Masonry.h"
#define kWidth [UIScreen mainScreen].bounds.size.width
#define kHeight [UIScreen mainScreen].bounds.size.height
@interface JJGPUWatermarkVC ()
@property (nonatomic, strong) GPUImageMovie *imageMovie;
@property (nonatomic, strong) GPUImageOutput <GPUImageInput> *blendFilter;
@property (nonatomic, strong) GPUImageMovieWriter *movieWriter;
@property (nonatomic, strong) UILabel *tipLabel;
@property (nonatomic, strong) GPUImageView *imageView;
@property (nonatomic, copy) NSString *pathStr;
@property (nonatomic, strong) NSURL *movieURL;
@end
@implementation JJGPUWatermarkVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
[self setupConfig];
}
- (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];
//顯示label
self.tipLabel = [[UILabel alloc] init];
self.tipLabel.textColor = [UIColor blueColor];
self.tipLabel.font = [UIFont systemFontOfSize:20.0];
[self.view addSubview:self.tipLabel];
[self.tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.equalTo(self.view).offset(20.0);
}];
}
- (void)setupConfig
{
//濾鏡
self.blendFilter = [[GPUImageDissolveBlendFilter alloc] init];
[(GPUImageDissolveBlendFilter *)self.blendFilter setMix:0.5];
//播放
NSURL *resourceURL = [[NSBundle mainBundle] URLForResource:@"lili" withExtension:@"mp4"];
AVAsset *asset = [AVAsset assetWithURL:resourceURL];
//實(shí)例化GPUImageMovie
self.imageMovie = [[GPUImageMovie alloc] initWithAsset:asset];
self.imageMovie.runBenchmark = YES;
self.imageMovie.playAtActualSpeed = YES;
//水印提示文字
UILabel *watermarkLabel = [[UILabel alloc] init];
watermarkLabel.text = @"水印";
watermarkLabel.font = [UIFont systemFontOfSize:30.0];
watermarkLabel.textColor = [UIColor redColor];
//水印圖片
UIView *backView = [[UIView alloc] initWithFrame:self.view.frame];
backView.backgroundColor = [UIColor clearColor];
[self.view addSubview:backView];
UIImageView *watermarkImageView = [[UIImageView alloc] init];
watermarkImageView.image = [UIImage imageNamed:@"light_4"];
watermarkImageView.center = CGPointMake(kHeight / 2, kWidth / 2);
[backView addSubview:watermarkLabel];
[backView addSubview:watermarkImageView];
[watermarkImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(backView);
make.height.equalTo(@(50.0));
make.width.equalTo(@(50.0));
}];
[watermarkLabel sizeToFit];
[watermarkLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(backView);
}];
//實(shí)例化GPUImageUIElement
GPUImageUIElement *uiElement = [[GPUImageUIElement alloc] initWithView:backView];
//存儲(chǔ)相關(guān)
NSString *pathStr = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathStr UTF8String]);
self.pathStr = pathStr;
NSURL *movieURL = [NSURL fileURLWithPath:pathStr];
self.movieURL = movieURL;
//實(shí)例化GPUImageMovieWriter
self.movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0, 480.0)];
GPUImageFilter *imageFilter = [[GPUImageFilter alloc] init];
[self.imageMovie addTarget:imageFilter];
[imageFilter addTarget:self.blendFilter];
[uiElement addTarget:self.blendFilter];
self.movieWriter.shouldPassthroughAudio = YES;
[self.imageMovie enableSynchronizedEncodingUsingMovieWriter:self.movieWriter];
//顯示
[self.blendFilter addTarget:self.imageView];
[self.blendFilter addTarget:self.movieWriter];
[self.movieWriter startRecording];
[self.imageMovie startProcessing];
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayProgress)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
displayLink.paused = NO;
[imageFilter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time){
CGRect frame = watermarkImageView.frame;
frame.origin.x += 0.5;
frame.origin.y += 0.5;
watermarkImageView.frame = frame;
[uiElement updateWithTimestamp:time];
}];
//存儲(chǔ)
__weak typeof(self) weakSelf = self;
[self.movieWriter setCompletionBlock:^{
__strong typeof(self) strongSelf = weakSelf;
[strongSelf.blendFilter removeTarget:strongSelf.movieWriter];
[strongSelf.movieWriter finishRecording];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(strongSelf.pathStr))
{
[library writeVideoAtPathToSavedPhotosAlbum:strongSelf.movieURL completionBlock:^(NSURL *assetURL, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"保存失敗");
}
else {
NSLog(@"保存成功");
}
});
}];
}
}];
}
#pragma mark - Action && Notification
- (void)displayProgress
{
NSLog(@"self.imageMovie.progress = %f", self.imageMovie.progress);
self.tipLabel.text = [NSString stringWithFormat:@"Progress = %.2f%%",self.imageMovie.progress * 100];
[self.tipLabel sizeToFit];
}
@end
功能效果
下面我們就給出幾個(gè)效果圖磨德。分別是錄制時(shí)和存儲(chǔ)在相冊回放時(shí)候的效果。
后記
未完,待續(xù)~~~