从视频中截取缩略图始终返回null

Dej*_*ell 5 iphone cocoa-touch objective-c ios ios6

我想从视频中获取第一个缩略图.

我尝试了以下方法:

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
gen.appliesPreferredTrackTransform = YES;
CMTime time = CMTimeMakeWithSeconds(0.0, 600);
NSError *error = nil;
CMTime actualTime;

CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
NSLog(@"the error is %@: image is %@: url is %@: ",error,_mainThumbnail,[NSURL fileURLWithPath:_moviePath] );
Run Code Online (Sandbox Code Playgroud)

但是,我的日志是:

the error is (null): image is (null): 
url is file:///private/var/mobile/Applications/D1293BDC-EA7E-4AC7-AD3C-1BA3548F37D6/tmp/trim.6F0C4631-E5E8-43CD-BF32-9B8F09D4ACF1.MOV: 
Run Code Online (Sandbox Code Playgroud)

AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil];
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    generator.appliesPreferredTrackTransform=TRUE;

    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);
        }
        _mainThumbnail.image = [UIImage imageWithCGImage:im];
        NSLog(@"thumbnails %@ ",_mainThumbnail.image);
    };

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

日志thumnails null.

为什么图像为空?我查看了其他论坛,他们建议使用fileURLWithPath - 我已经在使用了.

我正在使用ios7

Luk*_*cka 19

你可以尝试这种方法.它在给定的URL处获取视频的第一帧并将其返回为UIImage.

- (UIImage *)thumbnailFromVideoAtURL:(NSURL *)url
{
    AVAsset *asset = [AVAsset assetWithURL:url];

    //  Get thumbnail at the very start of the video
    CMTime thumbnailTime = [asset duration];
    thumbnailTime.value = 0;

    //  Get image from the video at the given time
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

    CGImageRef imageRef = [imageGenerator copyCGImageAtTime:thumbnailTime actualTime:NULL error:NULL];
    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

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

该方法不检查错误,因为我使用它的代码是正常的,nil如果有任何失败则返回.


编辑:澄清CMTime价值观

CMTime 具有

  • timescale - 将此视为视频的FPS(每秒帧数)(25 FPS - > 1s的视频有25个视频帧)
  • value - 识别混凝土框架.在上面的代码中,这表示您想要缩略图的帧.

要在精确时间计算帧,您必须进行以下计算:

value = timescale * seconds_to_skip
Run Code Online (Sandbox Code Playgroud)

这相当于

"Frame of the video to take" = "FPS" * "Number of seconds to skip"
Run Code Online (Sandbox Code Playgroud)

如果您想拍摄视频第2帧的第1帧,您实际上想要跳过视频的第1秒.所以你会用:

CMTime thumbnailTime = [asset duration];
thumbnailTime.value = thumbnailTime.timescale * 1;
Run Code Online (Sandbox Code Playgroud)

另一种观点:你想跳过视频的前1个而不是缩略图.即25 FPS,你想跳过25帧.所以CMTime.value = 25(跳过25帧).