iphone image to video issue in video speed

99封情书 提交于 2020-01-02 22:59:22

问题


I have done image to video conversion in iphone(of course I got the code from stack overflow questions). But the problem is speed of recorded video is very fast, it ran away within 2 seconds even though I have around 2250 frames. I know the problem is with its frame rate. But i don't know how to make it correct. my code is below

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");
}

this code is in calling function and defenitions of the functions given below

- (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;
}

What to do with the CMTime variables and how can I made it correctly One more help how can I add audio with this video.


回答1:


Your PTSs are very close together. Instead of CMTimeMake(1, 1000), why not 30FPS: CMTimeMake(1, 30))?




回答2:


I revised you code and came up to the solution, in my case I record every image in my view in 0.1 seconds so my fps is 0.1fps.

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

The reason why your video is too fast because your ratio is 1 seconds into 1000 image. You can make it 1 image per second.

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

Try this out, hope it will help you.




回答3:


Add this library AVFoundation CoreMedia CoreVideo

i am able to generate video , but not able to get audio is anyone had use this code and create video with audio



来源:https://stackoverflow.com/questions/8497481/iphone-image-to-video-issue-in-video-speed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!