iPhone图像到视频问题的视频速度



我已经在iPhone中完成了图像到视频的转换(当然,我从堆栈溢出问题中获得了代码(。但问题是录制视频的速度非常快,即使我有大约 2 帧,它也会在 2 秒内跑掉。我知道问题出在它的帧速率上。但我不知道如何使它正确。我的代码如下

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *myFilePath = [documentsDirectoryPath stringByAppendingPathComponent:@"test.mov"];
if ([self openVideoFile:myFilePath withSize:CGSizeMake (480.0, 320.0)]) {
    for (int i=1; i<2226; i++) {
        NSString *imagename=[NSString stringWithFormat:@"1 (%i).jpg",i];
        UIImage *image=[ UIImage imageNamed:imagename];
        [self writeImageToMovie:[image CGImage]];
    }
    [videoWriter finishWriting];
}
else {
    NSLog(@"friled to open video file");
}

这段代码是在调用函数和下面给出的函数的防御中

- (BOOL) openVideoFile: (NSString *) path withSize:(CGSize)imageSize {
    CGSize size = CGSizeMake (480.0, 320.0);//imageSize;
    NSError *error = nil;
    videoWriter = [[AVAssetWriter alloc] initWithURL:
                   [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
                                               error:&error];
    if (error != nil){
        NSLog(@"error>>>> %@",error);
        return NO;
    }
    NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                                [NSNumber numberWithDouble:size.width], AVVideoCleanApertureWidthKey,
                                                [NSNumber numberWithDouble:size.height], AVVideoCleanApertureHeightKey,
                                                [NSNumber numberWithInt:10], AVVideoCleanApertureHorizontalOffsetKey,
                                                [NSNumber numberWithInt:10], AVVideoCleanApertureVerticalOffsetKey,
                                                nil];

    NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                              [NSNumber numberWithInt:1], AVVideoPixelAspectRatioHorizontalSpacingKey,
                                              [NSNumber numberWithInt:1],AVVideoPixelAspectRatioVerticalSpacingKey,
                                              nil];

    NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   videoCleanApertureSettings, AVVideoCleanApertureKey,
                                   videoAspectRatioSettings, AVVideoPixelAspectRatioKey,
                                  nil];
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey,
                                   codecSettings,AVVideoCompressionPropertiesKey,
                                   [NSNumber numberWithDouble:size.width], AVVideoWidthKey,
                                   [NSNumber numberWithDouble:size.height], AVVideoHeightKey,
                                   nil];
    writerInput = [[AVAssetWriterInput
                    assetWriterInputWithMediaType:AVMediaTypeVideo
                    outputSettings:videoSettings] retain];
    NSMutableDictionary * bufferAttributes = [[NSMutableDictionary alloc] init];
    [bufferAttributes setObject: [NSNumber numberWithInt: kCVPixelFormatType_32ARGB]
                         forKey: (NSString *) kCVPixelBufferPixelFormatTypeKey];
    [bufferAttributes setObject: [NSNumber numberWithInt: 480]
                         forKey: (NSString *) kCVPixelBufferWidthKey];
    [bufferAttributes setObject: [NSNumber numberWithInt: 320]
                         forKey: (NSString *) kCVPixelBufferHeightKey];

    adaptor = [[AVAssetWriterInputPixelBufferAdaptor
                assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
                sourcePixelBufferAttributes:nil] retain];
    NSMutableDictionary*     attributes;
    attributes = [NSMutableDictionary dictionary];
    int width = 480;
    int height = 320;
    [attributes setObject:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
    [attributes setObject:[NSNumber numberWithInt:width] forKey: (NSString*)kCVPixelBufferWidthKey];
    [attributes setObject:[NSNumber numberWithInt:height] forKey: (NSString*)kCVPixelBufferHeightKey];
    CVReturn theError = CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (CFDictionaryRef) attributes, &pixelBufferPool);                                           

    NSParameterAssert(writerInput);
    NSParameterAssert([videoWriter canAddInput:writerInput]);
    [videoWriter addInput:writerInput];
    writerInput.expectsMediaDataInRealTime = YES;
    [videoWriter startWriting];
    [videoWriter startSessionAtSourceTime:kCMTimeZero];
    buffer = NULL;
    lastTime = kCMTimeZero;
    presentTime = kCMTimeZero;
    return YES;
}



   - (void) writeImageToMovie:(CGImageRef)image 
{
    if([writerInput isReadyForMoreMediaData])
    {
        buffer = [self pixelBufferFromCGImage:image];
        BOOL success = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
        if (!success) NSLog(@"Failed to appendPixelBuffer");
        CVPixelBufferRelease(buffer);
        presentTime = CMTimeAdd(lastTime, CMTimeMake(1, 1000));//I think problem is here but what will be given for correct output
        lastTime = presentTime;
    }
    else
    {
        NSLog(@"error - writerInput not ready");
    }
}

    - (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image
{
    CGSize size = CGSizeMake (480.0, 320.0);
    CVPixelBufferRef pxbuffer;
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];
    if (pixelBufferPool == NULL) NSLog(@"pixelBufferPool is null!");
    CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, pixelBufferPool, &pxbuffer); 
    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
                                                 size.height, 8, 4*size.width, rgbColorSpace, 
                                                 kCGImageAlphaNoneSkipFirst);
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
    CGContextDrawImage(context, CGRectMake(90, 10, CGImageGetWidth(image), 
                                           CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
    return pxbuffer;
}

如何处理CMTime变量以及如何正确制作它还有一个帮助,如何在此视频中添加音频。

你的PTS非常接近。而不是CMTimeMake(1, 1000),为什么不是30FPS:CMTimeMake(1, 30))

我修改了您的代码并提出了解决方案,就我而言,我在 0.1 秒内记录了视图中的每个图像,因此我的 fps 为 0.1fps。

presentTime = CMTimeAdd(lastTime, CMTimeMake(1, 10));
你的

视频太快的原因是因为你的比例是 1 秒进入 1000 张图像。您可以将其设置为每秒 1 张图像。

presentTime = CMTimeAdd(lastTime, CMTimeMake(1, 1));

试试这个,希望它能帮助你。

添加此库AVFoundation核心媒体核心视频

我能够生成视频,但无法获取音频,有人使用此代码并创建带有音频的视频

最新更新