我有一个正在为 iPhone 开发的应用程序。它的作用是,它从摄像头捕获视频并将视频文件存储到文件系统中。
在将图像保存到文件系统之前,我需要创建此视频文件的缩略图图像。我的动机是显示创建的视频的缩略图列表,以便用户可以选择特定的缩略图来播放所需的文件。
有人可以建议我如何创建相机捕获的视频文件的缩略图图像。
另外,您能否告知我是否可以使用 iOS SDK 创建现有视频文件的缩略图。
我有一个正在为 iPhone 开发的应用程序。它的作用是,它从摄像头捕获视频并将视频文件存储到文件系统中。
在将图像保存到文件系统之前,我需要创建此视频文件的缩略图图像。我的动机是显示创建的视频的缩略图列表,以便用户可以选择特定的缩略图来播放所需的文件。
有人可以建议我如何创建相机捕获的视频文件的缩略图图像。
另外,您能否告知我是否可以使用 iOS SDK 创建现有视频文件的缩略图。
实际上,更好的解决方案是使用 AVFoundation 框架来执行此操作。它绕过了构建 MPMoviePlayerController 的需要,如果与 UIImagePickerController 结合使用,则会导致相机的 Iris 保持关闭的问题(至少这是我所经历的)。
我使用的代码:
+ (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;
}
试试这个(它实际上并没有显示电影播放器):
+ (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 一起传递给此函数。
很简单试试这个...
第 1 步:导入标头#import <MediaPlayer/MediaPlayer.h>
第 2 步:获取 url 路径
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"m4v"]];
第 3 步:最后得到缩略图
- (UIImage *)VideoThumbNail:(NSURL *)videoURL
{
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
UIImage *thumbnail = [player thumbnailImageAtTime:52.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
[player stop];
return thumbnail;
}
试试这个 :
generate.requestedTimeToleranceBefore = kCMTimeZero;
generate.requestedTimeToleranceAfter = kCMTimeZero;
需要添加以获得正确的帧。
使用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) }
}
请注意,您可能会考虑在后台线程上运行此代码,因为缩略图创建可能是一项昂贵的操作。
另外,请看一下AVAssetImageGenerator
类的一些属性:
requestedTimeToleranceBefore
(苹果的文档):可以生成图像的请求时间之前的最大时间长度。
默认值为 kCMTimePositiveInfinity。
将 requestedTimeToleranceBefore 和 requestedTimeToleranceAfter 的值设置为 kCMTimeZero 以请求帧精确的图像生成;这可能会导致额外的解码延迟。
requestedTimeToleranceAfter
(苹果的文档):在请求的时间之后可以生成图像的最大时间长度。
默认值为 kCMTimePositiveInfinity。
将 requestedTimeToleranceBefore 和 requestedTimeToleranceAfter 的值设置为 kCMTimeZero 以请求帧精确的图像生成;这可能会导致额外的解码延迟。
maximumSize
(苹果的文档):指定生成图像的最大尺寸。
默认值为 CGSizeZero,它指定资产的未缩放尺寸。
AVAssetImageGenerator 缩放图像,使其适合定义的边界框。图像永远不会放大。缩放图像的纵横比由孔径模式属性定义。