一、相关属性声明(有可能有遗漏的,自行添加)
/// 滤镜相关
@property (nonatomic,strong)GPUImageView * gpuView;//预览视频内容
@property (nonatomic,strong)GPUImageMovie * gpuMovie;//接管视频数据
@property (nonatomic,strong)UIScrollView * EditView;//滤镜选择视图
@property (nonatomic,strong)NSArray * GPUImgArr;//存放滤镜数组
@property (nonatomic,strong)GPUImageOutput * pixellateFilter;//视频滤镜
@property (nonatomic,strong)GPUImageMovieWriter * movieWriter;//视频处理输出
@property (nonatomic,copy)NSString * fileSavePath;//视频合成后存储路径
@property (nonatomic,assign)NSTimer * timer;//设置计时器,因为重复合成同一个滤镜时间会很长超时后重新创建
@property (nonatomic,assign)int timeNum;//记时时间
@property (nonatomic,strong)UIView * hudView;//加载框
@property (nonatomic , assign) NSInteger index;// 记录选择滤镜下标
** 二、相关方法实现**
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = HEXCOLOR(0x333333);
self.index = 0;
[self createPreviewView];
// 封面视图
self.firstIma = [MSUCameraPhotoVc getImageAtSomeFrame:self.videoUrl videoTime:1];
}
#pragma mark - 创建视图
// 视频播放视图
- (void)createPreviewView{
self.gpuView = [[GPUImageView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT-150)];
CGSize videoSize = [MSUCameraPhotoVc getVideoSizeWithURL:_videoUrl];
if (videoSize.width < videoSize.height || [self.statusStr isEqualToString:@"竖屏"]) {
//设置展示页面的旋转
[_gpuView setInputRotation:kGPUImageRotateRight atIndex:0];
_gpuView.fillMode = kGPUImageFillModePreserveAspectRatioAndFill;
}
[self.view addSubview:_gpuView];
self.gpuMovie = [[GPUImageMovie alloc]initWithURL:self.videoUrl];
_gpuMovie.shouldRepeat = YES;//循环
_gpuMovie.playAtActualSpeed = YES;
[_gpuMovie addTarget:_gpuView];
[_gpuMovie startProcessing];
[self createFilterView];
}
- (void)createFilterView{
UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
closeBtn.frame = CGRectMake(14, 20, 20, 29);
// closeBtn.backgroundColor = [UIColor whiteColor];
[closeBtn setImage:[MSUPathTools showImageWithContentOfFileByName:@"record-close"] forState:UIControlStateNormal];
closeBtn.adjustsImageWhenHighlighted = NO;
[closeBtn addTarget:self action:@selector(closeBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:closeBtn];
UIButton *seleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
seleBtn.frame = CGRectMake(0, HEIGHT-150, 80, 150);
seleBtn.backgroundColor = [UIColor whiteColor];
[seleBtn setImage:[MSUPathTools showImageWithContentOfFileByName:@"WechatIMG896"] forState:UIControlStateNormal];
seleBtn.adjustsImageWhenHighlighted = NO;
[seleBtn addTarget:self action:@selector(saveBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:seleBtn];
self.EditView = [[UIScrollView alloc]initWithFrame:CGRectMake(80, HEIGHT-150, WIDTH, 150)];
_EditView.backgroundColor = [UIColor whiteColor];
_EditView.showsVerticalScrollIndicator = NO;
_EditView.showsHorizontalScrollIndicator = NO;
AVURLAsset * myAsset = [AVURLAsset assetWithURL:_videoUrl];
//初始化AVAssetImageGenerator
AVAssetImageGenerator * imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:myAsset];
imageGenerator.appliesPreferredTrackTransform = YES;
UIImage *inputImage = [[UIImage alloc]init];
// First image
//创建第一张预览图
CGImageRef halfWayImage = [imageGenerator copyCGImageAtTime:kCMTimeZero actualTime:nil error:nil];
if (halfWayImage != NULL) {
inputImage = [[UIImage alloc] initWithCGImage:halfWayImage];
}
self.GPUImgArr = [self CreateGPUArr];
for (int i = 0; i<_GPUImgArr.count; i++) {
UIButton * effectImg = [UIButton buttonWithType:UIButtonTypeCustom];
effectImg.frame = CGRectMake(16+i*(75+16), 22.5, 75 ,75);
[effectImg setImage:inputImage forState:UIControlStateNormal];
if (i>0) {
GPUImageOutput * disFilter = (GPUImageOutput *)[_GPUImgArr[i] objectForKey:@"filter"];
//设置要渲染的区域
[disFilter useNextFrameForImageCapture];
//获取数据源
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc]initWithImage:inputImage];
//添加上滤镜
[stillImageSource addTarget:disFilter];
//开始渲染
[stillImageSource processImage];
//获取渲染后的图片
UIImage *newImage = [disFilter imageFromCurrentFramebuffer];
[effectImg setImage:newImage forState:UIControlStateNormal];
}
effectImg.layer.cornerRadius = 10;
effectImg.layer.masksToBounds = YES;
effectImg.tag = 1000+i;
[effectImg addTarget:self action:@selector(effectImgClick:) forControlEvents:UIControlEventTouchUpInside];
// if (i == 0) {
// effectImg.layer.borderWidth = 2;
// effectImg.layer.borderColor = HEXCOLOR(0xf49818).CGColor;
// }
UILabel * effectName = [[UILabel alloc]initWithFrame:CGRectMake(effectImg.frame.origin.x, CGRectGetMaxY(effectImg.frame)+10, effectImg.frame.size.width, 20)];
effectName.textColor = HEXCOLOR(0x757575);
effectName.textAlignment = NSTextAlignmentCenter;
effectName.font = [UIFont systemFontOfSize:14];
effectName.text = _GPUImgArr[i][@"name"];
[_EditView addSubview:effectImg];
[_EditView addSubview:effectName];
_EditView.contentSize = CGSizeMake(_GPUImgArr.count*(75+16)+16+80, _EditView.frame.size.height);
}
[self.view addSubview:_EditView];
}
#pragma mark ---------------------------选择滤镜----------------------------
-(void)effectImgClick:(UIButton *)button{
self.index++;
for (int i = 0 ; i<_GPUImgArr.count ;i++) {
UIButton *btn = [_EditView viewWithTag:1000+i];
btn.layer.borderWidth = 0;
btn.userInteractionEnabled = YES;
}
button.userInteractionEnabled = NO;
button.layer.borderWidth = 2;
button.layer.borderColor = HEXCOLOR(0xf49818).CGColor;
[_gpuMovie cancelProcessing];
[_gpuMovie removeAllTargets];
_gpuMovie = [[GPUImageMovie alloc]initWithURL:_videoUrl];
CGSize videoSize = [MSUCameraPhotoVc getVideoSizeWithURL:_videoUrl];
if (videoSize.width < videoSize.height || [self.statusStr isEqualToString:@"竖屏"]) {
//设置展示页面的旋转
[_gpuView setInputRotation:kGPUImageRotateRight atIndex:0];
}
if (button.tag == 1000) {
_pixellateFilter = (GPUImageOutput *)[_GPUImgArr[button.tag-1000] objectForKey:@"filter"];
[_gpuMovie addTarget:_pixellateFilter];
[_pixellateFilter addTarget:_gpuView];
// _pixellateFilter = nil;
// [_gpuMovie addTarget:_gpuView];
}else{
_pixellateFilter = (GPUImageOutput *)[_GPUImgArr[button.tag-1000] objectForKey:@"filter"];
[_gpuMovie addTarget:_pixellateFilter];
[_pixellateFilter addTarget:_gpuView];
}
[_gpuMovie startProcessing];
}
#pragma mark ------------------------滤镜数组-----------------------
-(NSArray *)CreateGPUArr{
NSMutableArray * arr = [[NSMutableArray alloc]init];
GPUImageOutput * Filter0 = [[GPUImageFilter alloc] init];
NSString * title0 = @"原图";
NSDictionary * dic0 = [NSDictionary dictionaryWithObjectsAndKeys:Filter0,@"filter",title0,@"name", nil];
[arr addObject:dic0];
GPUImageOutput * Filter5 = [[GPUImageGammaFilter alloc] init];
[(GPUImageGammaFilter *)Filter5 setGamma:1.5];
NSString * title5 = @"伽马线";
NSDictionary * dic5 = [NSDictionary dictionaryWithObjectsAndKeys:Filter5,@"filter",title5,@"name", nil];
[arr addObject:dic5];
GPUImageOutput * Filter6 = [[GPUImageColorInvertFilter alloc] init];
NSString * title6 = @"反色";
NSDictionary * dic6 = [NSDictionary dictionaryWithObjectsAndKeys:Filter6,@"filter",title6,@"name", nil];
[arr addObject:dic6];
GPUImageOutput * Filter7 = [[GPUImageSepiaFilter alloc] init];
NSString * title7 = @"褐色怀旧";
NSDictionary * dic7 = [NSDictionary dictionaryWithObjectsAndKeys:Filter7,@"filter",title7,@"name", nil];
[arr addObject:dic7];
GPUImageOutput * Filter8 = [[GPUImageGrayscaleFilter alloc] init];
NSString * title8 = @"灰度";
NSDictionary * dic8 = [NSDictionary dictionaryWithObjectsAndKeys:Filter8,@"filter",title8,@"name", nil];
[arr addObject:dic8];
GPUImageOutput * Filter9 = [[GPUImageHistogramGenerator alloc] init];
NSString * title9 = @"色彩直方图?";
NSDictionary * dic9 = [NSDictionary dictionaryWithObjectsAndKeys:Filter9,@"filter",title9,@"name", nil];
[arr addObject:dic9];
GPUImageOutput * Filter10 = [[GPUImageRGBFilter alloc] init];
NSString * title10 = @"RGB";
[(GPUImageRGBFilter *)Filter10 setRed:0.8];
[(GPUImageRGBFilter *)Filter10 setGreen:0.3];
[(GPUImageRGBFilter *)Filter10 setBlue:0.5];
NSDictionary * dic10 = [NSDictionary dictionaryWithObjectsAndKeys:Filter10,@"filter",title10,@"name", nil];
[arr addObject:dic10];
GPUImageOutput * Filter11 = [[GPUImageMonochromeFilter alloc] init];
[(GPUImageMonochromeFilter *)Filter11 setColorRed:0.3 green:0.5 blue:0.8];
NSString * title11 = @"单色";
NSDictionary * dic11 = [NSDictionary dictionaryWithObjectsAndKeys:Filter11,@"filter",title11,@"name", nil];
[arr addObject:dic11];
GPUImageOutput * Filter12 = [[GPUImageBoxBlurFilter alloc] init];
// [(GPUImageMonochromeFilter *)Filter11 setColorRed:0.3 green:0.5 blue:0.8];
NSString * title12 = @"单色";
NSDictionary * dic12 = [NSDictionary dictionaryWithObjectsAndKeys:Filter12,@"filter",title12,@"name", nil];
[arr addObject:dic12];
GPUImageOutput * Filter13 = [[GPUImageSobelEdgeDetectionFilter alloc] init];
// [(GPUImageSobelEdgeDetectionFilter *)Filter13 ];
NSString * title13 = @"漫画反色";
NSDictionary * dic13 = [NSDictionary dictionaryWithObjectsAndKeys:Filter13,@"filter",title13,@"name", nil];
[arr addObject:dic13];
GPUImageOutput * Filter14 = [[GPUImageXYDerivativeFilter alloc] init];
// [(GPUImageSobelEdgeDetectionFilter *)Filter13 ];
NSString * title14 = @"蓝绿边缘";
NSDictionary * dic14 = [NSDictionary dictionaryWithObjectsAndKeys:Filter14,@"filter",title14,@"name", nil];
[arr addObject:dic14];
GPUImageOutput * Filter15 = [[GPUImageSketchFilter alloc] init];
// [(GPUImageSobelEdgeDetectionFilter *)Filter13 ];
NSString * title15 = @"素描";
NSDictionary * dic15 = [NSDictionary dictionaryWithObjectsAndKeys:Filter15,@"filter",title15,@"name", nil];
[arr addObject:dic15];
GPUImageOutput * Filter16 = [[GPUImageSmoothToonFilter alloc] init];
// [(GPUImageSobelEdgeDetectionFilter *)Filter13 ];
NSString * title16 = @"卡通";
NSDictionary * dic16 = [NSDictionary dictionaryWithObjectsAndKeys:Filter16,@"filter",title16,@"name", nil];
[arr addObject:dic16];
GPUImageOutput * Filter17 = [[GPUImageColorPackingFilter alloc] init];
// [(GPUImageSobelEdgeDetectionFilter *)Filter13 ];
NSString * title17 = @"监控";
NSDictionary * dic17 = [NSDictionary dictionaryWithObjectsAndKeys:Filter17,@"filter",title17,@"name", nil];
[arr addObject:dic17];
return arr;
}
#pragma mark -----------------------------视频存放位置------------------------
- (NSString *)fileSavePath{
NSFileManager* fileManager = [NSFileManager defaultManager];
NSString *pathDocuments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *createPath = [NSString stringWithFormat:@"%@/myVidio/333.mp4", pathDocuments];//视频存放位置
NSString *createPath2 = [NSString stringWithFormat:@"%@/myVidio", pathDocuments];//视频存放文件夹
//判断视频文件是否存在,存在删除
BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:createPath];
if (blHave) {
BOOL blDele= [fileManager removeItemAtPath:createPath error:nil];
if (!blDele) {
[fileManager removeItemAtPath:createPath error:nil];
}
}
//判断视频存放文件夹是否存在,不存在创建
BOOL blHave1=[[NSFileManager defaultManager] fileExistsAtPath:createPath2];
if (!blHave1) {
[fileManager createDirectoryAtPath:createPath2 withIntermediateDirectories:YES attributes:nil error:nil];
}
_fileSavePath = createPath;
NSLog(@"视频存放地址 fileSavePath = %@",_fileSavePath);
return _fileSavePath;
}
#pragma amrk - 点击事件
- (void)closeBtnClick:(UIButton *)sender{
[self.navigationController dismissViewControllerAnimated:NO completion:^{
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
}];
}
- (void)saveBtnClick:(UIButton *)sender{
// [self createHudView];
if (self.index == 0) {
[MSUHUD showFileWithString:@"请选择列表中的任一滤镜"];
} else{
[MSUHUD showStatusWithString:@"正在合成"];
_timeNum = 0;
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeRun) userInfo:nil repeats:YES];
NSURL *movieURL = [NSURL fileURLWithPath:self.fileSavePath];
NSLog(@"movieURL %@",movieURL);
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(WIDTH, HEIGHT-150)];//视频存放路径及输出视频宽高
[_pixellateFilter addTarget:_movieWriter];
_movieWriter.shouldPassthroughAudio = YES;
_movieWriter.encodingLiveVideo = YES;
[_gpuMovie enableSynchronizedEncodingUsingMovieWriter:_movieWriter];
[_movieWriter startRecording];
__weak MSUFilterController * weakSelf = self;
[_movieWriter setFailureBlock:^(NSError *error) {
NSLog(@"合成失败 173:error = %@",error.description);
dispatch_async(dispatch_get_main_queue(), ^{
[MSUHUD showFileWithString:@"合成失败,请重新合成"];
weakSelf.hudView.hidden = YES;
[weakSelf.pixellateFilter removeTarget:weakSelf.movieWriter];
// [weakSelf.dic setObject:weakSelf.pixellateFilter forKey:@"filter"];
[weakSelf.movieWriter finishRecording];
[weakSelf.timer setFireDate:[NSDate distantFuture]];
});
}];
[_movieWriter setCompletionBlock:^{
NSLog(@"视频合成结束: 188 ");
dispatch_async(dispatch_get_main_queue(), ^{
[MSUHUD showFileWithString:@"合成成功"];
// [[NSFileManager defaultManager] removeItemAtPath:weakSelf.fileSavePath error:nil];//取消之后就删除,以免占用手机硬盘空间
weakSelf.hudView.hidden = YES;
[weakSelf.pixellateFilter removeTarget:weakSelf.movieWriter];
// [weakSelf.dic setObject:weakSelf.pixellateFilter forKey:@"filter"];
[weakSelf.movieWriter finishRecording];
[weakSelf.timer setFireDate:[NSDate distantFuture]];
[weakSelf.timer invalidate];
weakSelf.timer = nil;
// weakSelf.hidesBottomBarWhenPushed = YES;
MSUEditController *edit = [[MSUEditController alloc] init];
edit.videoUrl = weakSelf.videoUrl;
edit.firstIma = weakSelf.firstIma;
edit.videoInputUrl = movieURL;
// edit.videoPathUrl = weakSelf.videoPathUrl;
[weakSelf.navigationController pushViewController:edit animated:YES];
});
}];
}
}
-(void)createHudView{
if (!_hudView) {
_hudView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT)];
_hudView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
UIView * huV = [[UIView alloc]initWithFrame:CGRectMake(WIDTH/2-50, HEIGHT/2-50, 100, 100)];
huV.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
huV.layer.cornerRadius = 5;
huV.clipsToBounds = YES;
UIActivityIndicatorView * activityView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityView.frame = CGRectMake(0, 0,huV.frame.size.width, huV.frame.size.height);
[activityView startAnimating];
[huV addSubview:activityView];
[_hudView addSubview:huV];
[[[UIApplication sharedApplication] keyWindow] addSubview:_hudView];
}else{
_hudView.hidden = NO;
}
}
#pragma mark -----------------------计时器--------------------------
-(void)timeRun{
_timeNum += 1;
if (_timeNum >= 5) {
[MSUHUD showFileWithString:@"视频处理超时,请再试一次"];
NSLog(@"视频处理超时");
[_timer invalidate];
_timer = nil;
_hudView.hidden = YES;
[self createPreviewView];
}
}