Reputation: 31
I have a problem with my MPMoviePlayer in another thread, using (Grand Central Dispatch). I want to appeal to the video by url, cut 5-th frame and return the picture. In the emulator works fine, but on a real device - fall. What's the problem here? maybe it only works in the main thread?
NSURL* url = [NSURL URLWithString:filePath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void)
{
MPMoviePlayerController* moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
moviePlayer.shouldAutoplay = NO;
UIImage* thumbnail = [moviePlayer thumbnailImageAtTime:5 timeOption:MPMovieTimeOptionNearestKeyFrame];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[[Singleton sharedSingleton].imageCache setValue:thumbnail forKey:filePath];
[cell.presentationViewOutlet setImage:thumbnail];;
});
});
Now, I try to use another method but it also - works well on the simulator and on a real device is not displayed. Sometimes returns imageRef = (null)
, sometimes imageRef = <CGImage 0x1766dd20>
.
EDIT:
NSURL* url = [NSURL URLWithString:filePath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void)
{
AVAsset *asset = [AVAsset assetWithURL:videoURL];
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
imageGenerator.appliesPreferredTrackTransform = TRUE;
CMTime time = CMTimeMakeWithSeconds(1, 1);
NSError *err = NULL;
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:&err];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
NSLog(@"imageRef = %@", imageRef);
UIImage* image = [UIImage imageWithCGImage:imageRef];
if (image != nil)
{
NSLog(@"image != nil");
[view setImage:image];
NSString* videoURLString = [videoURL absoluteString];
[[Singleton sharedSingleton].imageCache setValue:image forKey:videoURLString];
CGImageRelease(imageRef);
}
else
{
NSLog(@"err = %@", err);
}
});
});
Error:
If imageRef = (null) show err = Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x156c1a50 {NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x155b29a0 "The operation couldn’t be completed. (OSStatus error -12792.)", NSLocalizedFailureReason=An unknown error occurred (-12792)}
Upvotes: 3
Views: 927
Reputation: 3415
Does it work better if you move the imageref inside the async section? Like:
NSURL* url = [NSURL URLWithString:filePath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void)
{
AVAsset *asset = [AVAsset assetWithURL:videoURL];
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
imageGenerator.appliesPreferredTrackTransform = TRUE;
CMTime time = CMTimeMakeWithSeconds(1, 1);
dispatch_async(dispatch_get_main_queue(), ^(void)
{
NSError *err = NULL;
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:&err];
NSLog(@"imageRef = %@", imageRef);
UIImage* image = [UIImage imageWithCGImage:imageRef];
if (image != nil)
{
NSLog(@"image != nil");
[view setImage:image];
NSString* videoURLString = [videoURL absoluteString];
[[Singleton sharedSingleton].imageCache setValue:image forKey:videoURLString];
CGImageRelease(imageRef);
}
else
{
NSLog(@"err = %@", err);
}
});
});
Upvotes: 0
Reputation: 131491
An MPMoviePlayerController is a user interface controller. As such it is almost certainly not thread-safe. The docs don't say specifically, but I would bet money that it's not.
Upvotes: 1