- 其实我也是在网上搜了很多博客然后跟着写的,不过还是遇到了一些问题,最后自己解决了。大部分人只实现了水印的添加,但并未控制水印的显示时间,我自己琢磨了一下下,变写代码边测试,完美地实现了水印显示控制,我想要它什么时候出现就什么时候出现。实现水印这里我就不详细说了,简书上有很多文章。推荐:[http://www.jianshu.com/p/f5fddad6b7d1)],还有@落影loyinglin也可以看看,他写了很多关于GPUImage的文章。
- 看到很多文章做水印用的是GPUImageDissolveBlendFilter,字面理解是溶解的意思,我试着用过,发现会使水印跟着视频模糊,因为那个滤镜值是设置溶解度的,设置0.5,水印跟视频都能显示但变得模糊,设置为1,水印根本就不显示。后来我用了另外一个滤镜GPUImageAlphaBlendFilter,效果杠杠的。 关键代码来了:
-
movieFile = [[GPUImageMovie alloc]initWithURL:_videoUrl]; movieFile.playAtActualSpeed = NO; [movieFile addTarget:lastFilter];//这里的lastFilter一个变量,因为我页面上有各种滤镜,点击哪个滤镜就会切换使用。 水印 AVAsset *asset = [AVAsset assetWithURL:_videoUrl]; CGSize movieSize = asset.naturalSize; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0,movieSize.width,movieSize.height)]; view.backgroundColor = [UIColor clearColor]; UIImage *image = [UIImage imageNamed:@"dog2"]; UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, movieSize.width*80/375.0, movieSize.width*80/375.0)];//拿到视频原尺寸,然后根据当前手机屏幕进行比例换算,得到真实尺寸。 imv.transform = _tietu.transform;//tietu是一个imageView,展示在当前屏幕上的。 imv.transform = CGAffineTransformRotate(_tietu.transform, (-_degress/180.0*M_PI));//这里的degress是视频角度,如果视频角度不是0,意味着视频被旋转了,为了正常显示我们需要对视频进行旋转(我在最后导出的时候进行了旋转),但水印方向却不对,后来试了几下,发现水印需要与所旋转角度相反,这里我加了一个“-”号。 imv.center =view.center; imv.image = image;
UILabel *name = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, movieSize.width/375.0*200, 60*movieSize.height/667.0)];
name.transform = CGAffineTransformRotate(name.transform, (-_degress/180.0*M_PI));
name.textColor = [UIColor whiteColor];
name.center = vi.center;
name.font = [UIFont systemFontOfSize:20*movieSize.width/375.0];
name.text = @"我是美女我怕谁";
name.alpha = 0;
[view addSubview:name];
landInput = [[GPUImageUIElement alloc]initWithView:view];
blend = [[GPUImageAlphaBlendFilter alloc]init];
[(GPUImageAlphaBlendFilter*)blend setMix:1.0];
[(GPUImageAlphaBlendFilter*)blend disableSecondFrameCheck];
[lastFilter addTarget:blend];
[landInput addTarget:blend];
__strong typeof(weakSelf) sself = weakSelf;
NSString *pathToMovie = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mMovie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieUrl = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc]initWithMovieURL:movieUrl size:CGSizeMake(960, 540)];
[blend addTarget:movieWriter];
-
下面这个setFrame方法我没有用,因为有人说影响性能会一直调用,所以按照博主的建议换了runAsy这个方法,当然,你还得改源码的。。。具体操作还是看我上面的链接文章吧。 // [lastFilter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) { // [sself-> landInput update];
// }];runAsynchronouslyOnVideoProcessingQueue(^{ [sself->landInput update]; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ name.alpha = 1; [sself->landInput updateWithTimestamp:CMTimeMake(fileas.duration.timescale*3, fileas.duration.timescale)];//记住,这里的时间一定要按这样的格式,我们知道value/timescale 就是second,但对于视频来说,一秒是代表多少帧的,假如视频一秒是30帧,那么2s 表示 CMTimeMake(30*2,30) 我这里代码控制文字在视频第三秒出现。 }); movieWriter.shouldPassthroughAudio = YES; movieFile.audioEncodingTarget = movieWriter; [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter]; [movieWriter startRecording]; [movieFile startProcessing];