【问题标题】:Grabbing the first frame of a video from UIImagePickerController?从 UIImagePickerController 抓取视频的第一帧?
【发布时间】:2009-10-05 07:26:34
【问题描述】:

我正在尝试从UIImagePickerController 中的选定视频中获取第一帧以显示在UIImageView 中,但我不知道这是否可能。如果是,我该怎么做?

【问题讨论】:

标签: iphone ios cocoa-touch uiimagepickercontroller


【解决方案1】:

您可以通过以下两种方式之一执行此操作。第一种方式是使用MPMoviePlayerController抓取缩略图:

MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc]
                                       initWithContentURL:videoURL];
moviePlayer.shouldAutoplay = NO;
UIImage *thumbnail = [moviePlayer thumbnailImageAtTime:time
                     timeOption:MPMovieTimeOptionNearestKeyFrame];

这可行,但MPMoviePlayerController 不是一个特别轻量级的对象,也不是特别快速抓取缩略图。

首选方法是在 AVFoundation 中使用新的AVAssetImageGenerator。这比旧方式快速、轻量且更灵活。这是一个帮助方法,它将从视频中返回一个自动发布的图像。


+ (UIImage *)thumbnailImageForVideo:(NSURL *)videoURL 
                             atTime:(NSTimeInterval)time 
{

    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
    NSParameterAssert(asset);
    AVAssetImageGenerator *assetIG = 
                [[AVAssetImageGenerator alloc] initWithAsset:asset];
    assetIG.appliesPreferredTrackTransform = YES;
    assetIG.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;

    CGImageRef thumbnailImageRef = NULL;
    CFTimeInterval thumbnailImageTime = time;
    NSError *igError = nil;
    thumbnailImageRef = 
             [assetIG copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)
                             actualTime:NULL
                                  error:&igError];

    if (!thumbnailImageRef)
        NSLog(@"thumbnailImageGenerationError %@", igError );

    UIImage *thumbnailImage = thumbnailImageRef 
                          ? [[UIImage alloc] initWithCGImage:thumbnailImageRef]
                          : nil;

    return thumbnailImage;
}

异步使用


- (void)thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time completion:(void (^)(UIImage *)) completion
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
        NSParameterAssert(asset);
        AVAssetImageGenerator *assetIG =
        [[AVAssetImageGenerator alloc] initWithAsset:asset];
        assetIG.appliesPreferredTrackTransform = YES;
        assetIG.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;

        CGImageRef thumbnailImageRef = NULL;
        CFTimeInterval thumbnailImageTime = time;
        NSError *igError = nil;
        thumbnailImageRef =
        [assetIG copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)
                        actualTime:NULL
                             error:&igError];

        if (!thumbnailImageRef)
            NSLog(@"thumbnailImageGenerationError %@", igError );

        UIImage *thumbnailImage = thumbnailImageRef
        ? [[UIImage alloc] initWithCGImage:thumbnailImageRef]
        : nil;

        dispatch_async(dispatch_get_main_queue(), ^{
            completion(thumbnailImage);
        });
    });
}

【讨论】:

  • 对于其他尝试使用此功能的人:注意 videoURL 是否由 fileURLWithPath 或 URLWithString 创建(当您在 NSString* 中有路径时)
  • 只是一个问题(和一个提醒) - 上面的方法是同步是吗?最好把它扔到另一个线程中。
  • 你甚至把它打包成一个公共类方法......谢谢;-)
  • [assetIG copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多