在iOS中为video创build缩略图
我有一个应用程序,我正在开发的iPhone。 它所做的是从摄像机捕获video并将video文件存储到文件系统中。
在将图像保存到文件系统之前,我需要创build此video文件的缩略图。 我的动机是显示创build的video的缩略图列表,以便用户可以select特定的缩略图播放所需的文件。
有人可以请build议我如何创build一个video文件已经被相机捕获的缩略图图像。
另外,你可以请指教,如果我可以使用iOS SDK创build现有video文件的缩略图。
试试这个(它实际上并不显示电影播放器):
+ (UIImage *)imageFromMovie:(NSURL *)movieURL atTime:(NSTimeInterval)time { // set up the movie player MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; mp.shouldAutoplay = NO; mp.initialPlaybackTime = time; mp.currentPlaybackTime = time; // get the thumbnail UIImage *thumbnail = [mp thumbnailImageAtTime:time timeOption:MPMovieTimeOptionNearestKeyFrame]; // clean up the movie player [mp stop]; [mp release]; return(thumbnail); }
它应该是一个同步调用,所以它可能会阻止主线程,但似乎在我使用电影开始时间的时候,相当即时运行。 如果你做了这么多,你可以把它作为UIImage的一个类别添加,这就是我所做的。
我从你的问题中看到,你想在电影保存之前做到这一点,我想这可能无法工作,没有文件的url。 但是,如果您使用UIImagePickerController进行相机捕获,则可以将imagePickerController:didFinishPickingMediaWithInfo:的信息字典中返回的URL与UIImagePickerControllerMediaURL键一起传递给此函数。
更好的解决scheme实际上是使用AVFoundation框架来做到这一点。 它绕过构造一个MPMoviePlayerController的需要,如果与UIImagePickerController结合使用(至less这是我所经历的),会导致相机的Iris保持closures的问题。
我使用的代码是:
+ (UIImage *)thumbnailFromVideoAtURL:(NSURL *)contentURL { UIImage *theImage = nil; AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:contentURL options:nil]; AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; generator.appliesPreferredTrackTransform = YES; NSError *err = NULL; CMTime time = CMTimeMake(1, 60); CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; theImage = [[[UIImage alloc] initWithCGImage:imgRef] autorelease]; CGImageRelease(imgRef); [asset release]; [generator release]; return theImage; }
很简单,试试这个…
第1步 :导入标题#import <MediaPlayer/MediaPlayer.h>
导入#import <MediaPlayer/MediaPlayer.h>
第2步 :获取urlpath
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"m4v"]];
第3步 :获取缩略图
- (UIImage *)VideoThumbNail:(NSURL *)videoURL { MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:contentURL]; UIImage *thumbnail = [player thumbnailImageAtTime:52.0 timeOption:MPMovieTimeOptionNearestKeyFrame]; [player stop]; return thumbnail; }
尝试这个 :
generate.requestedTimeToleranceBefore = kCMTimeZero; generate.requestedTimeToleranceAfter = kCMTimeZero;
需要添加到正确的框架。
代码解决scheme,使用AVFoundation
框架和Swift 3.0(评论代码是不必要的,并在代码下面讨论 – 你必须决定是否需要它):
import AVFoundation func generateThumbnailForVideo(at url: URL) -> UIImage? { let kPreferredTimescale: Int32 = 1000 let asset = AVURLAsset(url: url) let generator = AVAssetImageGenerator(asset: asset) generator.appliesPreferredTrackTransform = true //generator.requestedTimeToleranceBefore = kCMTimeZero //generator.requestedTimeToleranceAfter = kCMTimeZero //generator.maximumSize = CGSize(width: 100, height: 100) var actualTime: CMTime = CMTime(seconds: 0, preferredTimescale: kPreferredTimescale) //generates thumbnail at first second of the video let cgImage = try? generator.copyCGImage(at: CMTime(seconds: 1, preferredTimescale: kPreferredTimescale), actualTime: &actualTime) return cgImage.flatMap() { return UIImage(cgImage: $0, scale: UIScreen.main.scale, orientation: .up) } }
请注意,您可能会考虑在后台线程上运行此代码,因为创build缩略图可能是一个代价高昂的操作。
另外,请看一下AVAssetImageGenerator
类的一些属性:
-
requestedTimeToleranceBefore
( Apple的文档 ):
在可能产生图像的请求时间之前的最大时间长度。
默认值是kCMTimePositiveInfinity。
将requestedTimeToleranceBefore和requestedTimeToleranceAfter的值设置为kCMTimeZero,以请求帧精确的图像生成; 这可能会导致额外的解码延迟。
-
requestedTimeToleranceAfter
( Apple的文档 ):
在可能产生图像的请求时间之后的最大时间长度。
默认值是kCMTimePositiveInfinity。
将requestedTimeToleranceBefore和requestedTimeToleranceAfter的值设置为kCMTimeZero,以请求帧精确的图像生成; 这可能会导致额外的解码延迟。
-
maximumSize
( 苹果的文档 ):
指定生成图像的最大尺寸。
默认值是CGSizeZero,它指定资产的未缩放尺寸。
AVAssetImageGenerator缩放图像,使其适合定义的边界框。 图像永远不会放大。 缩放图像的宽高比由apertureMode属性定义。