从使用AVAssetWriter创建的视频生成缩略图 [英] Generating thumbnails from videos created using AVAssetWriter

查看:407
本文介绍了从使用AVAssetWriter创建的视频生成缩略图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AVAssetWritercaptureOutput回调来录制视频和音频.问题在于,在大约5%的情况下,我无法从第二个零开始生成缩略图(如果我尝试在视频中走得更远,则没有问题).我收到的错误是:

I'm recording video+audio using AVAssetWriter and the captureOutput callback. The problem is that in about 5% of the cases I cannot generate a thumbnail from second zero(If I try to go further in the video, then there is no problem). The error I'm getting is:

Error Domain = AVFoundationErrorDomain代码= -11832无法打开" UserInfo = 0x4b31b0 {NSLocalizedFailureReason =此媒体不能是 ,NSUnderlyingError = 0x4effb0无法执行该操作 完全的. (OSStatus错误-12431.)",NSLocalizedDescription =无法 打开}

Error Domain=AVFoundationErrorDomain Code=-11832 "Cannot Open" UserInfo=0x4b31b0 {NSLocalizedFailureReason=This media cannot be used., NSUnderlyingError=0x4effb0 "The operation couldn’t be completed. (OSStatus error -12431.)", NSLocalizedDescription=Cannot Open}

这是我正在使用的代码:

Here is the code I'm using:

AVURLAsset *asset=[[AVURLAsset alloc] initWithURL: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)
    {
        [self NSLogPrint:[NSString stringWithFormat:@"couldn't generate thumbnail, error:%@", error]];
    }

    UIImage *thumbImg=[[UIImage imageWithCGImage:im] retain];   

    [image setImage:thumbImg];
    [thumbImg release];

    [generator release];
};

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

这是我设置视频 AVAssetWriterInput 的方式:

Here is how I'm setting up my video AVAssetWriterInput:

- (BOOL) setupAssetWriterVideoInput:(CMFormatDescriptionRef)currentFormatDescription 
{
    float bitsPerPixel;
    CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(currentFormatDescription);
    int numPixels = dimensions.width * dimensions.height;
    int bitsPerSecond;

    // Assume that lower-than-SD resolutions are intended for streaming, and use a lower bitrate
    if ( numPixels < (640 * 480) )
        bitsPerPixel = 4.05; // This bitrate matches the quality produced by AVCaptureSessionPresetMedium or Low.
    else
        bitsPerPixel = 11.04; // This bitrate matches the quality produced by AVCaptureSessionPresetHigh.

    bitsPerSecond = numPixels * bitsPerPixel;

    NSDictionary *videoCompressionSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                              AVVideoCodecH264, AVVideoCodecKey,
                                              [NSNumber numberWithInteger:dimensions.width], AVVideoWidthKey,
                                              [NSNumber numberWithInteger:dimensions.height], AVVideoHeightKey,
                                              [NSDictionary dictionaryWithObjectsAndKeys:
                                               [NSNumber numberWithInteger:bitsPerSecond], AVVideoAverageBitRateKey,
                                               [NSNumber numberWithInteger:30], AVVideoMaxKeyFrameIntervalKey,
                                               nil], AVVideoCompressionPropertiesKey,
                                              nil];
    if ([_videoWriter canApplyOutputSettings:videoCompressionSettings forMediaType:AVMediaTypeVideo]) 
    {
        self._videoWriterInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoCompressionSettings];
        self._videoWriterInput.expectsMediaDataInRealTime = YES;
        self._videoWriterInput.transform = [self returnOrientation];
        if ([_videoWriter canAddInput:self._videoWriterInput])
            [_videoWriter addInput:self._videoWriterInput];
        else
        {
            NSLog(@"Couldn't add asset writer video input.");
            return NO;
        }
    }
    else
    {
        NSLog(@"Couldn't apply video output settings.");
        return NO;
    }

    return YES;
}

我知道该错误意味着当时没有图像,但是为什么会发生这种情况?

I know that the error means there is no image at that time, but why is this happening?

我还测试了使用AVCaptureMovieFileOutput进行录制,并且始终会生成缩略图. 另外,如果我将视频导出到相机胶卷,则照片"中也不会提供预览.

I've also tested recording using AVCaptureMovieFileOutput and the thumbnails are always generated. Also if I export the video that to camera roll, the preview also isn't available in Photos.

P.S:我还在某个地方读到这可能与关键帧间隔有关,但是我不确定如何做.

P.S: I've also read somewhere that this may have something to do with the key frame interval, but I'm not sure how.

推荐答案

我已经解决了我的问题.我在iOS 4.2.1上运行,并决定升级到iOS 5.1.1,该问题消失了.

I sort of fixed my problem. I was running on iOS 4.2.1,and decided to upgrade to iOS 5.1.1 and the issue dissappeared.

这篇关于从使用AVAssetWriter创建的视频生成缩略图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆