I have server application which serves informations about the videos on server. One of the requests is URL:PORT/video/:id/:time ... which I parse and get the video file, prepare the time and ask method to generate the thumbnail. It works for first 5 minutes really fast (generates image under 200ms), then the process of image generation suddenly takes even 10 seconds...
Do you have any idea why ? Code used:
-(NSImage *)thumbnailAt: (CMTime) time
withSize: (NSSize) size
error: (NSError **) error {
@autoreleasepool {
if ( self.assetChanged ) {
self.generate = [[AVAssetImageGenerator alloc] initWithAsset:_asset];
self.generate.appliesPreferredTrackTransform = TRUE;
self.assetChanged = NO;
}
self.generate.maximumSize = NSSizeToCGSize(size);
CGImageRef imageReference = [self.generate copyCGImageAtTime:time actualTime:NULL error:error];
if ( imageReference != nil ) {
NSImage* ret = [[NSImage alloc] initWithCGImage:imageReference size:size];
CGImageRelease(imageReference);
return ret;
}
return nil;
}
}
Any idea what I am doing wrong or any suggestion how to do it differently (eg. using AVAssetReader) ?
In the end I solved it by using different approach: I used asynchronous images
-(NSImage *)createAsyncThumbnailAtTime:(CMTime)time withSize:(NSSize)size {
if ( self.updated ) {
[_generator cancelAllCGImageGeneration]; // Stop we did not comply in time.
_generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:_asset];
_generator.maximumSize = NSSizeToCGSize(size);
}
NSMutableArray * times = [NSMutableArray array];
[times addObject:[NSValue valueWithCMTime:time]];
__block NSImage * image;
__block BOOL finished = NO;
[_generator generateCGImagesAsynchronouslyForTimes:times completionHandler:^(CMTime requestedTime, CGImageRef imageRef, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
image = nil;
if ( result == AVAssetImageGeneratorCancelled ) {
image = nil;
NSLog(@"CANCELLED %@", error);
finished = YES;
}
else
if ( result == AVAssetImageGeneratorFailed ) {
image = nil;
NSLog(@"FAILDED %@", error);
finished = YES;
}
else /* result == AVAssetImageGeneratorSucessed */
{
image = [[NSImage alloc] initWithCGImage:imageRef size:size];
finished = YES;
}
}];
while ( !finished ) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
return thumbnail->image;
}