【问题标题】:Creating Thumbnail for Video in iOS在 iOS 中为视频创建缩略图
【发布时间】:2011-08-23 05:50:51
【问题描述】:

我有一个正在为 iPhone 开发的应用程序。它的作用是,它从摄像头捕获视频并将视频文件存储到文件系统中。

在将图像保存到文件系统之前,我需要创建此视频文件的缩略图图像。我的动机是显示创建的视频的缩略图列表,以便用户可以选择特定的缩略图来播放所需的文件。

有人可以建议我如何创建相机捕获的视频文件的缩略图。

另外,能否请您告知我是否可以使用 iOS SDK 创建现有视频文件的缩略图。

【问题讨论】:

  • 我实际上是指在 IOS 上生成视频文件的缩略图,而不是以编程方式截取屏幕截图。要截屏,必须播放文件,但在我的情况下,播放文件不是必需的。

标签: ios objective-c thumbnails video-thumbnails


【解决方案1】:

很简单试试这个...

第一步:导入标头#import <MediaPlayer/MediaPlayer.h>

第二步:获取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;
}

【讨论】:

  • thumbnailImageAtTime:timeOption: 在 iOS 7 中已弃用
  • 此方法在 ios 7 中已弃用
【解决方案2】:

使用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类的一些属性:

  1. requestedTimeToleranceBefore (Apple's documentation):

在请求的时间之前可以生成图像的最长时间。

默认值为 kCMTimePositiveInfinity。

将 requestedTimeToleranceBefore 和 requestedTimeToleranceAfter 的值设置为 kCMTimeZero 以请求帧精确的图像生成;这可能会导致额外的解码延迟。

  1. requestedTimeToleranceAfter (Apple's documentation):

在请求的时间之后可以生成图像的最长时间。

默认值为 kCMTimePositiveInfinity。

将 requestedTimeToleranceBefore 和 requestedTimeToleranceAfter 的值设置为 kCMTimeZero 以请求帧精确的图像生成;这可能会导致额外的解码延迟。

  1. maximumSize (Apple's documentation):

指定生成图像的最大尺寸。

默认值为 CGSizeZero,它指定资产的未缩放尺寸。

AVAssetImageGenerator 缩放图像,使其适合定义的边界框。图像永远不会放大。缩放后图像的纵横比由光圈模式属性定义。

【讨论】:

    【解决方案3】:

    试试这个:

    generate.requestedTimeToleranceBefore = kCMTimeZero;
    generate.requestedTimeToleranceAfter = kCMTimeZero;
    

    需要添加才能获得正确的帧。

    【讨论】:

      【解决方案4】:

      实际上更好的解决方案是使用 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;
      }
      

      【讨论】:

      • 缩略图在最后,AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset]; CMTime 持续时间 = playerItem.duration;
      • @Underdog 你不需要AVPlayerItem。直接从AVAsset 获取持续时间。
      【解决方案5】:

      试试这个(它实际上并不显示电影播放器​​):

      + (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。

      【讨论】:

      • thumbnailImageAtTime:timeOption: 在 iOS 7 中已弃用
      猜你喜欢
      • 2016-01-25
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2012-02-24
      • 2018-05-15
      • 2011-04-24
      • 1970-01-01
      • 2015-03-30
      相关资源
      最近更新 更多