我想获得一张用iPhone / iPAD拍摄的视频缩略图(* .mov)。我正在尝试使用AVFoundation库并收到此错误:
couldn't generate thumbnail, error:Error Domain=AVFoundationErrorDomain Code=-11822 "Cannot Open" UserInfo=0x15d90a30 {NSLocalizedDescription=Cannot Open, NSLocalizedFailureReason=This media format is not supported.}
代码:
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir=[paths objectAtIndex:0];
NSString *videoPath=[documentDir stringByAppendingPathComponent:[NSString stringWithFormat:@"videos/%@.mov",videoName]];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:videoPath options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform=TRUE;
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
if (result != AVAssetImageGeneratorSucceeded) {
NSLog(@"couldn't generate thumbnail, error:%@", error);
}
self.img.image=[UIImage imageWithCGImage:im];
};
CGSize maxSize = CGSizeMake(320, 180);
generator.maximumSize = maxSize;
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];
我用我的应用程序录制了视频,并希望显示它们的缩略图。
答案 0 :(得分:14)
这是......(从此链接中挑选 - Getting video snapshot for thumbnail)
- (UIImage *)thumbnailImageFromURL:(NSURL *)videoURL {
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL: videoURL options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *err = NULL;
CMTime requestedTime = CMTimeMake(1, 60); // To create thumbnail image
CGImageRef imgRef = [generator copyCGImageAtTime:requestedTime actualTime:NULL error:&err];
NSLog(@"err = %@, imageRef = %@", err, imgRef);
UIImage *thumbnailImage = [[UIImage alloc] initWithCGImage:imgRef];
CGImageRelease(imgRef); // MUST release explicitly to avoid memory leak
return thumbnailImage;
}
答案 1 :(得分:2)
我没有足够的声誉来评论,但上面的示例缺少CGImageRelease(imageRef)
...
最终的方法应该是这样的:
- (UIImage*)loadImage {
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil];
AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *err = NULL;
CMTime time = CMTimeMake(1, 60);
//Grab image
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err];
NSLog(@"err==%@, imageRef==%@", err, imgRef);
UIImage* finalImage = [[UIImage alloc] initWithCGImage:imgRef];
CGImageRelease(imageRef);
return finalImage;
}
让我意识到......所以也许它会对某人有所帮助。
答案 2 :(得分:1)
你可以用两种方式在swift中生成1. AVAssetImageGenerator 2. MPMoviePlayerController
1.
func generateThumnail(url : NSURL) -> UIImage{
var asset : AVAsset = AVAsset.assetWithURL(url) as AVAsset
var assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
assetImgGenerate.appliesPreferredTrackTransform = true
var error : NSError? = nil
var time : CMTime = CMTimeMake(1, 30)
var img : CGImageRef = assetImgGenerate.copyCGImageAtTime(time, actualTime: nil, error: &error)
var frameImg : UIImage = UIImage(CGImage: img)!
return frameImg
}
2.
override func viewDidLoad() {
super.viewDidLoad()
var moviePlayer : MPMoviePlayerController! = MPMoviePlayerController(contentURL: moviePlayManager.movieURL)
moviePlayer.view.frame = CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y, width:
self.view.frame.size.width, height: self.view.frame.height)
moviePlayer.fullscreen = true
moviePlayer.controlStyle = MPMovieControlStyle.None
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "videoThumbnailIsAvailable:",
name: MPMoviePlayerThumbnailImageRequestDidFinishNotification,
object: nil)
let thumbnailTimes = 3.0
moviePlayer.requestThumbnailImagesAtTimes([thumbnailTimes],
timeOption: .NearestKeyFrame)
}
func videoThumbnailIsAvailable(notification: NSNotification){
if let player = moviePlayer{
let thumbnail =
notification.userInfo![MPMoviePlayerThumbnailImageKey] as? UIImage
if let image = thumbnail{
/* We got the thumbnail image. You can now use it here */
println("Thumbnail image = \(image)")
}
}
答案 3 :(得分:0)
您需要检查视频轨道中的每个视频片段是否为空。
+ (UIImage*)getVideoPreViewImage:(AVAsset *)asset atTimeSec:(double)timeSec
{
if (!asset) {
return nil;
}
AVAssetTrack *videoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
NSArray<AVAssetTrackSegment *> *segs = videoTrack.segments;
if (!segs.count) {
return nil;
}
CMTime currentStartTime = kCMTimeZero;
for (NSInteger i = 0; i < segs.count; i ++) {
if (!segs[i].isEmpty) {
currentStartTime = segs[i].timeMapping.target.start;
break;
}
}
CMTime coverAtTimeSec = CMTimeMakeWithSeconds(timeSec, asset.duration.timescale);
if (CMTimeCompare(coverAtTimeSec, asset.duration) == 1 || CMTimeCompare(coverAtTimeSec, currentStartTime) == -1) {
coverAtTimeSec = currentStartTime;
}
AVAssetImageGenerator *assetGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
assetGen.requestedTimeToleranceBefore = kCMTimeZero;
assetGen.requestedTimeToleranceAfter = kCMTimeZero;
assetGen.appliesPreferredTrackTransform = YES;
NSError *error = nil;
CGImageRef image = [assetGen copyCGImageAtTime:coverAtTimeSec actualTime:NULL error:&error];
if (error) {
return nil;
}
UIImage *videoImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
return videoImage;
}