1

我已经在 iphone 中完成了图像到视频的转换(当然我从堆栈溢出问题中得到了代码)。但问题是录制视频的速度非常快,即使我有大约 2250 帧,它也会在 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 变量以及如何正确制作另一个帮助如何在此视频中添加音频。

4

3 回答 3

1

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

于 2011-12-14T14:56:38.703 回答
0

我修改了你的代码并提出了解决方案,在我的例子中,我在 0.1 秒内记录了我视图中的每张图像,所以我的 fps 是 0.1fps。

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

你的视频之所以太快,是因为你的比例是 1 秒成 1000 张图像。您可以使其每秒 1 张图像。

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

试试这个,希望对你有帮助。

于 2012-10-21T12:05:06.967 回答
0

添加这个库 AVFoundation CoreMedia CoreVideo

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

于 2012-12-27T10:17:25.437 回答