分享一个获取视频帧的代码(解决时间不准确问题)留给自己备忘
2014-05-09 15:13
603 查看
使用AVFoundation 获取一组视频的帧
这个破东西我看了两天资料 好像别人都没有问题,网上搜不到有问这个问题的(ps:估计是我太笨了,别人都没问题)
终于找到解决办法了
官网文档有一句话 https://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html
The actual time of a generated image is within the range [requestedTime-requestedTimeToleranceBefore, requestedTime+requestedTimeToleranceAfter]
and may differ from the requested time for efficiency.
然后找到了requestedTimeToleranceAfter这个属性 http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html#//apple_ref/occ/instp/AVAssetImageGenerator/requestedTimeToleranceAfter
里面有一句话说明
Set the values of requestedTimeToleranceBefore and requestedTimeToleranceAfter to kCMTimeZero to request frame-accurate
image generation; this may incur additional decoding delay.
加上
self.myImageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
self.myImageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
之后 时间就比较准确了 只剩一点微小的误差 不过完全可以接受
- (IBAction)goCap:(id)sender { NSBundle *mainBundle = [NSBundle mainBundle]; NSString *urlAsString = [mainBundle pathForResource:@"asdf" ofType:@"mp4"]; NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; NSURL *url = [NSURL fileURLWithPath:urlAsString]; AVURLAsset *myAsset = [[AVURLAsset alloc] initWithURL:url options:opts]; float minute = 0.0f, second = 0.0f; // value为 总帧数,timescale为 fps second = myAsset.duration.value / myAsset.duration.timescale; // 获取视频总时长,单位秒 self.myImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:myAsset]; self.myImageGenerator.appliesPreferredTrackTransform = YES; //解决 时间不准确问题 self.myImageGenerator.requestedTimeToleranceBefore = kCMTimeZero; self.myImageGenerator.requestedTimeToleranceAfter = kCMTimeZero; // 获取视频总时长,单位秒 Float64 durationSeconds = CMTimeGetSeconds([myAsset duration]); NSLog(@"%f~!~!~!~",durationSeconds); CMTime firstThird = CMTimeMakeWithSeconds(10.0, 600); CMTime secondThird = CMTimeMakeWithSeconds(11.0, 600); CMTime end = CMTimeMakeWithSeconds(12.0, 600); NSArray *times = [NSArray arrayWithObjects:[NSValue valueWithCMTime:firstThird], [NSValue valueWithCMTime:secondThird],[NSValue valueWithCMTime:end],nil]; // myImageGenertor 必须为strong [self.myImageGenerator generateCGImagesAsynchronouslyForTimes:times completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { NSString *requestedTimeString = (NSString *) CFBridgingRelease(CMTimeCopyDescription(NULL, requestedTime)); NSString *actualTimeString = (NSString *) CFBridgingRelease(CMTimeCopyDescription(NULL, actualTime)); NSLog(@"Requested: %@; actual %@", requestedTimeString, actualTimeString); if (result == AVAssetImageGeneratorSucceeded) { // Do something interesting with the image. NSLog(@"asdfasdgtryer4563464"); UIImage* image1 = [UIImage imageWithCGImage: image]; // UIImageWriteToSavedPhotosAlbum(image1, self, nil, nil); } if (result == AVAssetImageGeneratorFailed) { NSLog(@"Failed with error: %@", [error localizedDescription]); } if (result == AVAssetImageGeneratorCancelled) { NSLog(@"Canceled"); } }]; }
这个破东西我看了两天资料 好像别人都没有问题,网上搜不到有问这个问题的(ps:估计是我太笨了,别人都没问题)
终于找到解决办法了
官网文档有一句话 https://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html
The actual time of a generated image is within the range [requestedTime-requestedTimeToleranceBefore, requestedTime+requestedTimeToleranceAfter]
and may differ from the requested time for efficiency.
然后找到了requestedTimeToleranceAfter这个属性 http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html#//apple_ref/occ/instp/AVAssetImageGenerator/requestedTimeToleranceAfter
里面有一句话说明
Set the values of requestedTimeToleranceBefore and requestedTimeToleranceAfter to kCMTimeZero to request frame-accurate
image generation; this may incur additional decoding delay.
加上
self.myImageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
self.myImageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
之后 时间就比较准确了 只剩一点微小的误差 不过完全可以接受
相关文章推荐
- 用NSIS安装日志install。log解决了一个安装出现隐蔽的问题、不用看代码,可以节省大把时间!开心!
- 一个关于js代码如何获取服务器时间问题
- JS代码获取当前日期时支持IE,不兼容FF和chrome,解决这个问题,我们需要把获取时间的getYear()函数换成getFullYear()
- JS代码获取当前日期时支持IE,不兼容FF和chrome,解决这个问题,我们需要把获取时间的getYear()函数换成getFullYear()
- 做了五年的程序员啦,从今天开始,没解决一个问题,坚持把思路整理出来,发布到网上分享,对自己对他人都有益处
- JS代码获取当前日期时支持IE,不兼容FF和chrome,解决这个问题,我们需要把获取时间的getYear()函数换成getFullYear()
- 一个小工具解决时间同步问题
- 关于FreeMarker获取一个对象中另一个对象出现的问题以及解决方法
- 解决一个服务器时间滞后的问题
- 解决一个服务器时间滞后的问题
- 今天在用c语言写一个栈,碰到不少问题,感觉到自己基础还是蛮差劲的,现在拿出来分享分享
- 关于获取当前时间出现1970年问题的解决
- PHP中Date获取的系统时间不准确的原因和解决方法
- 基本上,把switch,用设计模式代替,肯定是bug和过度设计。想想,本来修改一个文件几行代码可以解决的问题,变成修改3-6个类才能实现一样的功能。不是傻是什么?
- 解决通过CHttpFile获取远程图片,图片长度取得不准确的问题
- PHP 获取当前时间以及解决PHP通过date()函数取得时间错误问题
- java计算时间差 Java问题通用解决代码
- 解决微信小程序中Date.parse()获取时间戳iOS无法获取的问题
- 解决微信小程序中Date.parse()获取时间戳IOS不兼容的问题(IOS为NaN的问题)
- 感觉自己总是写代码,看代码,解决问题,却从未总结过,从今天起开始总结。