您的位置:首页 > 编程语言

分享一个获取视频帧的代码(解决时间不准确问题)留给自己备忘

2014-05-09 15:13 603 查看
使用AVFoundation 获取一组视频的帧
- (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;
之后 时间就比较准确了  只剩一点微小的误差  不过完全可以接受
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  视频 framework ios开发
相关文章推荐