从iOS中的视频网址或数据中获取缩略图

Dan*_*iel 59 iphone video thumbnails ios

我试图从iphone 3GS相机拍摄的视频中获取(第一帧的)缩略图,以便我可以显示它.这该怎么做?

Dik*_*hah 70

-(UIImage *)generateThumbImage : (NSString *)filepath
{
    NSURL *url = [NSURL fileURLWithPath:filepath];

    AVAsset *asset = [AVAsset assetWithURL:url];
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
    imageGenerator.appliesPreferredTrackTransform = YES;
    CMTime time = [asset duration];
    time.value = 0;
    CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);  // CGImageRef won't be released by ARC

    return thumbnail;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用time.value获取帧,假设您想要1秒帧然后使用

time.value = 1000 //Time in milliseconds
Run Code Online (Sandbox Code Playgroud)

  • @Diken Shah如何在视频的第n秒获得缩略图.我设置time.value = n,但我仍然得到第一帧 (3认同)

Dan*_*iel 69

这个问题的答案是,现在可以使用4.0 iOS获取使用AVFoundation的缩略图,以下代码,其中类属性url是电影网址,将完成这一操作(您可以随时获取缩略图,在示例中它可以时间0)

-(void)generateImage
{
    AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:self.url options:nil];
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    generator.appliesPreferredTrackTransform=TRUE;
    [asset release];
    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);
        }
        [button setImage:[UIImage imageWithCGImage:im] forState:UIControlStateNormal];
        thumbImg=[[UIImage imageWithCGImage:im] retain];
        [generator release];
    };

    CGSize maxSize = CGSizeMake(320, 180);
    generator.maximumSize = maxSize;
    [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];

}
Run Code Online (Sandbox Code Playgroud)

  • 该代码效果很好.AVAssettImageGenerator的唯一缺点是目前它使用的关键帧通常以一秒的间隔间隔 - 所以你不能得到比这更精细的分辨率.如果您只是想让一些缩略图在时间轴上展开,那么它可能很好,但如果您尝试读取连续帧,则无法正常工作.在这种情况下,你必须使用AVAssetReader,它有一些自己的怪癖,或MPMovieController,它具有帧精确的缩略图方法. (7认同)
  • 欣赏这个线程是旧的,但只想添加MPMoviePlayerController(见下文)是一个更快的选择.上面的代码需要5-10秒才能生成缩略图,而MPMovie几乎是即时的. (3认同)
  • @GuybrushThreepwood我已经尝试了同时使用5种不同视频的方法,并且所有缩略图都在一秒内准备就绪; 需要注意的一点是,您应该使用GCD来更新UI. (2认同)

Bus*_*hid 23

NSURL *videoURL = [NSURL fileURLWithPath:url];

MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];

        UIImage *thumbnail = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];

        //Player autoplays audio on init
        [player stop];
        [player release];
Run Code Online (Sandbox Code Playgroud)

检查此链接是否有替代方法: thumbnailImageAtTime:现已弃用 - 有什么替代方案?

  • thumbnailImageAtTime:现在已弃用,仅限访问此主题的任何人. (6认同)

E-M*_*add 13

我找到的最佳方法...... MPMoviePlayerController thumbnailImageAtTime:timeOption

  • 实际上在测试中我发现这个方法比上面列出的AVAsset代码快得多. (2认同)

Dha*_*ngh 12

SWIFT 2.0

你可以用两种方式在swift中生成1. AVFoundation 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)")
            }
        }
Run Code Online (Sandbox Code Playgroud)


Avt*_*Avt 8

Swift 2代码:

func previewImageForLocalVideo(url:NSURL) -> UIImage?
{
    let asset = AVAsset(URL: url)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    imageGenerator.appliesPreferredTrackTransform = true

    var time = asset.duration
    //If possible - take not the first frame (it could be completely black or white on camara's videos)
    time.value = min(time.value, 2)

    do {
        let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
        return UIImage(CGImage: imageRef)
    }
    catch let error as NSError
    {
        print("Image generation failed with error \(error)")
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)


Hir*_*hal 8

对于Swift 3.0

func createThumbnailOfVideoFromFileURL(_ strVideoURL: String) -> UIImage?{

let asset = AVAsset(url: URL(string: strVideoURL)!)
let assetImgGenerate = AVAssetImageGenerator(asset: asset)
assetImgGenerate.appliesPreferredTrackTransform = true
let time = CMTimeMakeWithSeconds(Float64(1), 100)
do {
  let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
  let thumbnail = UIImage(cgImage: img)
  return thumbnail
} catch {
  /* error handling here */
}
return nil   }
Run Code Online (Sandbox Code Playgroud)