2

似乎没有太多关于的信息AVAssetImageGenerator,甚至更少,cancelAllCGImageGeneration所以我希望这不是一个错误。

我正在调用generateCGImagesAsynchronouslyForTimes并成功取回帧,如果我让它处理整个文件,一切都很好。但是当我cancelAllCGImageGeneration...

...取消需要一段时间 - 这很奇怪,但没什么大不了的。

...它继续为请求的每一帧调用完成块,结果AVAssetImageGeneratorCancelled- 这似乎是一个奇怪的设计选择并且非常不方便。

但主要问题是,在与它进行一系列调用后,AVAssetImageGeneratorCancelled它又开始调用AVAssetImageGeneratorSucceeded。有任何想法吗?

(我可以通过在取消时设置一个标志来解决这个问题,并在此之后忽略图像,但是用户可以用另一个视频重新开始操作,这样逻辑就会变得混乱。而且我到处都是“内存不足”错误.)

编码:

AVURLAsset* asset = [AVURLAsset URLAssetWithURL:self.cameraSelection.movieURL options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], AVURLAssetPreferPreciseDurationAndTimingKey, nil]];
NSTimeInterval duration = CMTimeGetSeconds(asset.duration);
float fps = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0].nominalFrameRate;
int frames = duration * fps;

NSMutableArray* requestedTimes = [NSMutableArray array];
for( int i=0; i<frames; i++ )
{
    [requestedTimes addObject:[NSValue valueWithCMTime:CMTimeMake(i, fps)]];
}

assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
assetImageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
assetImageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
[assetImageGenerator generateCGImagesAsynchronouslyForTimes:requestedTimes completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error)
 {
     NSString* resultStr;
     switch (result)
     {
         case AVAssetImageGeneratorSucceeded:   resultStr = @"AVAssetImageGeneratorSucceeded";  break;
         case AVAssetImageGeneratorFailed:      resultStr = @"AVAssetImageGeneratorFailed"; break;
         case AVAssetImageGeneratorCancelled:   resultStr = @"AVAssetImageGeneratorCancelled";  break;
     }
     CFStringRef requestedTimeString = CMTimeCopyDescription(kCFAllocatorDefault, requestedTime);
     CFStringRef actualTimeString = CMTimeCopyDescription(kCFAllocatorDefault, actualTime);
     NSLog(@"%@ requestedTime:%@ actualTime:%@ error:%@", resultStr, (NSString*)requestedTimeString, (NSString*)actualTimeString, error);
     CFRelease(requestedTimeString);
     CFRelease(actualTimeString);
 }];

日志:

2013-07-01 12:23:54.815 ImprovEyes[9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{0/60 = 0.000} 实际时间:{0/600 = 0.000} 错误:(空)
2013-07-01 12:23:54.864 ImprovEyes[9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{1/60 = 0.017} 实际时间:{10/600 = 0.017} 错误:(空)
2013-07-01 12:23:54.894 ImprovEyes[9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{2/60 = 0.033} 实际时间:{20/600 = 0.033} 错误:(空)
2013-07-01 12:23:54.950 ImprovEyes[9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{3/60 = 0.050} 实际时间:{30/600 = 0.050} 错误:(空)
2013-07-01 12:23:54.964 ImprovEyes[9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{4/60 = 0.067} 实际时间:{40/600 = 0.067} 错误:(空)
*** 在这里取消 ***
2013-07-01 12:23:56.137 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{53/60 = 0.883} 实际时间:{530/600 = 0.883} 错误:(空)
2013-07-01 12:23:56.138 ImprovEyes[9114:907]assetImageGenerator cancelAllCGImageGeneration
2013-07-01 12:23:56.210 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{54/60 = 0.900} 实际时间:{540/600 = 0.900} 错误:(空)
2013-07-01 12:23:56.230 ImprovEyes[9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{55/60 = 0.917} 实际时间:{550/600 = 0.917} 错误:(空)
*** 继续接收图像一段时间然后停止 ***
2013-07-01 12:23:57.019 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{90/60 = 1.500} 实际时间:{900/600 = 1.500} 错误:(空)
2013-07-01 12:23:57.036 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{91/60 = 1.517} 实际时间:{910/600 = 1.517} 错误:(空)
2013-07-01 12:23:57.046 ImprovEyes[9114:1903] AVAssetImageGeneratorCancelled requestedTime:{92/60 = 1.533} actualTime:{INVALID} 错误:(null)
2013-07-01 12:23:57.056 ImprovEyes [9114:1903] AVAssetImageGeneratorCancelled requestedTime:{93/60 = 1.550} actualTime:{INVALID} 错误:(null)
*** 图像再次出现!***
2013-07-01 12:24:01.234 ImprovEyes[9114:1903] AVAssetImageGeneratorCancelled requestedTime:{538/60 = 8.967} actualTime:{INVALID} 错误:(null)
2013-07-01 12:24:01.241 ImprovEyes[9114:1903] AVAssetImageGeneratorCancelled requestedTime:{539/60 = 8.983} actualTime:{INVALID} 错误:(null)
2013-07-01 12:24:01.249 ImprovEyes [9114:1903] AVAssetImageGeneratorCancelled requestedTime:{540/60 = 9.000} actualTime:{INVALID} 错误:(null)
2013-07-01 12:24:01.259 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{541/60 = 9.017} 实际时间:{5410/600 = 9.017} 错误:(空)
2013-07-01 12:24:01.270 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{542/60 = 9.033} 实际时间:{5420/600 = 9.033} 错误:(空)
2013-07-01 12:24:01.279 ImprovEyes [9114:1903] AVAssetImageGeneratorSucceeded 请求时间:{543/60 = 9.050} 实际时间:{5430/600 = 9.050} 错误:(空)
...
4

1 回答 1

0

我有同样的问题,它仍然处理一些,因为它们已经在队列中。

尝试这样的事情:

__block BOOL hasErrors = NO;

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
    if (!hasErrors) {

        DDLogVerbose(@"ACTUAL GENERATION TIME %f", CMTimeGetSeconds(actualTime));

        if (result != AVAssetImageGeneratorSucceeded) {
            DDLogError(@"Failed to generate thumb: %@", error.localizedDescription);
            hasErrors = YES;
            [generator cancelAllCGImageGeneration];
            finishBlock(images, YES);
        } else {
            [images addObject:[UIImage imageWithCGImage:im]];

            if (CMTIME_COMPARE_INLINE(requestedTime, ==, ((NSValue *) timeIntervals.lastObject).CMTimeValue)) {
                DDLogVerbose(@"Movie composition thumb generation complete");
                finishBlock(images, NO);
            }
        }
    }
};
于 2013-09-20T15:04:47.957 回答