获取录制的视频的第一帧

  1. - (UIImage*) getVideoPreViewImage:(NSString *)videoURL  
  2. {  
  3.     videoURL = @"http://vf1.mtime.cn/Video/2012/04/23/mp4/120423212602431929.mp4";  
  4.     AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:videoURL] options:nil];  
  5.     AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];  
  6.     gen.appliesPreferredTrackTransform = YES;  
  7.     CMTime time = CMTimeMake(11000);  
  8.     NSError *error = nil;  
  9.     CMTime actualTime;  
  10.     CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];  
  11.     UIImage *img = [[UIImage alloc] initWithCGImage:image];  
  12.     CGImageRelease(image);  
  13.     self.showImageView.image = img;  
  14.     return img;  
  15.       
  16. }  

[objc]  view plain  copy
  1. CMTime  
  2. CMTime 是一个用来描述视频时间的结构体。  
  3. 他有两个构造函数: * CMTimeMake * CMTimeMakeWithSeconds  
  4. 这两个的区别是 * CMTimeMake(a,b) a当前第几帧, b每秒钟多少帧.当前播放时间a/b * CMTimeMakeWithSeconds(a,b) a当前时间,b每秒钟多少帧.  
  5. 我们引用例子来说明它:  


CMTimeMakeWithSeconds

[objc]  view plain  copy
  1. 1  
  2. 2  
  3. 3  
  4. 4  
  5. Float64 seconds = 5;  
  6. int32_t preferredTimeScale = 600;  
  7. CMTime inTime = CMTimeMakeWithSeconds(seconds, preferredTimeScale);  
  8. CMTimeShow(inTime);  
  9. OUTPUT: {3000/600 = 5.000}  
  10. 代表当前时间为5s,视频一共有3000帧,一秒钟600帧  
  11. CMTimeMake  
  12. 1  
  13. 2  
  14. 3  
  15. 4  
  16. int64_t value = 10000;  
  17. int32_t preferredTimeScale = 600;  
  18. CMTime inTime = CMTimeMake(value, preferredTimeScale);  
  19. CMTimeShow(inTime);  
  20. OUTPUT: {10000/600 = 16.667}  
  21. 代表时间为16.667s, 视频一共1000帧,每秒600帧  
  22. 其实,在我们这里,我们关心的只有最后那个总时间。 换句话说,我们把那个(0600)换成(x, 600) 是没问题的… = =!  
  23. requestedTimeTolerance  
  24. 那么为什么,效果差了这么多呢? 我们可以把  
  25. 1  
  26. 2  
  27. 3  
  28. CGImageRef image = [gen copyCGImageAtTime:time  
  29.                                    actualTime:&actualTime  
  30.                                         error:&error];  
  31. 返回的 actualTime 输出一下  
  32. 1  
  33. CMTimeShow(actualTime)  
  34. 就会发现时间差的很远。 这是为什么呢。  
  35. 首先他的 actualTime 使用的 fps * 1000 当每秒的帧率。 顺路普及下fps的获取方法  
  36. 1  
  37. float fps = [[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] nominalFrameRate];  
  38. 然后我们来思考为什么要有 requestTime 和 actualTime 呢? 开始我对这个api 很困惑: 为什么我request的时间 不等于 actual  
  39. 后来查了一下文档。  
  40. 当你想要一个时间点的某一帧的时候,他会在一个范围内找,如果有缓存,或者有在索引内的关键帧,就直接返回,从而优化性能。  
  41. 这个定义范围的API就是 requestedTimeToleranceAfter 和 requestedTimeToleranceBefore  
  42. 如果我们要精确时间,那么只需要  
  43. 1  
  44. 2  
  45.  gen.requestedTimeToleranceAfter = kCMTimeZero;  
  46.  gen.requestedTimeToleranceBefore = kCMTimeZero;  









+ (UIImage*) thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time { AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil]; NSParameterAssert(asset); AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset]; assetImageGenerator.appliesPreferredTrackTransform = YES; assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels; CGImageRef thumbnailImageRef = NULL; CFTimeInterval thumbnailImageTime = time; NSError *thumbnailImageGenerationError = nil; thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError]; if(!thumbnailImageRef) NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError); UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil; return thumbnailImage;}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值