iOS-视频播放过程中录制GIF图
2017-10-30 本文已影响59人
半缘魔君
近期,各大视频APP都推出了一个新的功能----在播放视频过程中录制GIF图片,并分享.
截图.png我们项目刚好有这个需求,就写了一个demo,这里分享一下我的实现思路;
技术点:
1 视频播放(略:可参考http://www.jianshu.com/p/6cb137340732)
2 LongPress手势的添加和使用(略)
3 视频截取帧图(略:可参考http://www.jianshu.com/p/69be2869ad02)
4 多张图片合成GIF图(重点)
5 分享(略)
本篇文章的视频播放是基于AVPlayer的,关于AVPlayer的详细使用手册可以参考:http://www.jianshu.com/p/6cb137340732
我们假定的需求:
1 触发录制GIF的条件是长按某个按钮;
2 图片暂不做压缩处理
3 内存问题暂不考虑
视频播放过程中录制GIF图实现思路:
1 长按手势开始每0.3s截取一张帧图
2 长按手势结束,将截取到的图片合成一张GIF
本篇文章的重点是多张图片合成GIF,截取帧图方法参考:http://www.jianshu.com/p/69be2869ad02,这里不再赘述
核心代码如下:
//长按手势的方法
- (void)longp:(UILongPressGestureRecognizer *)longp{
switch (longp.state) {
case UIGestureRecognizerStateBegan:
self.flag = YES;//标识开始截图
[self getThumbnails];//截图方法
NSLog(@"开始截图");
break;
case UIGestureRecognizerStateEnded:
self.flag = NO;标识停止截图
NSLog(@"结束截图");
NSLog(@"----%@",self.thumbnailArray);
//生成gif
UIImage *ima = [self createGitWithImageArray:self.thumbnailArray];//生成GIF
[self.imageV setImage:ima forState:UIControlStateNormal];
[self.thumbnailArray removeAllObjects];
break;
default:
break;
}
}
//截取帧图的方法
- (void)getThumbnails{
if (self.flag) {
if(player.currentItem.status == AVPlayerStatusReadyToPlay){
dispatch_async(dispatch_get_global_queue(0,0), ^{
CMTime currentTime = player.currentItem.currentTime;
CVPixelBufferRef buffer = [videoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil];
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:buffer];
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
CGImageRef videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(buffer), CVPixelBufferGetHeight(buffer))];
UIImage *image = [UIImage imageWithCGImage:videoImage];
[self.thumbnailArray addObject:image];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self screenShot];
NSLog(@"------");
});
});
}
}
}
//多张图片生成GIF
- (UIImage *)createGitWithImageArray:(NSArray <UIImage *> *)imageArray{
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"animated4.gif"];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSFileManager defaultManager] removeItemAtPath:path error:NULL];
NSLog(@"删除--");
}
CGImageDestinationRef destination =CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], kUTTypeGIF, imageArray.count, NULL);
NSDictionary *frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.3f] forKey:(NSString *)kCGImagePropertyGIFDelayTime] forKey:(NSString *)kCGImagePropertyGIFDictionary];
NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:(NSString *)kCGImagePropertyGIFLoopCount]forKey:(NSString *)kCGImagePropertyGIFDictionary];
for (int i = 0; i<imageArray.count; i++) {
UIImage *shacho = imageArray[i];
CGImageDestinationAddImage(destination, shacho.CGImage, (CFDictionaryRef)frameProperties);
}
CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);
CGImageDestinationFinalize(destination);
CFRelease(destination);
// NSLog(@"animated GIF file created at %@", path);
NSData *data = [NSData dataWithContentsOfFile:path];
return [UIImage sd_animatedGIFWithData:data];
}