2011-12-13 103 views
1

我已經完成圖像視頻轉換在iPhone(當然,我從堆棧溢出問題得到的代碼)。但問題是錄製視頻的速度非常快,即使我擁有2250幀左右的幀,它也會在2秒內跑掉。我知道問題在於幀率。 但我不知道如何使其正確。 我的代碼如下iphone圖像視頻問題視頻速度

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

這個代碼是在調用函數的功能defenitions下面

- (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變量,我該如何正確 一個更多的幫助,使它我怎樣才能用這個視頻添加音頻。

+0

創建視頻我還一個問題應用程序崩潰,沒有在日誌中打印它只發生在視頻記錄使用彩色圖像時發生,而不是在使用普通白色圖像時發生崩潰 – Johnykutty 2011-12-22 12:29:44

回答

1

您的PTS非常接近。爲什麼不是CMTimeMake(1, 1000),而不是30FPS:CMTimeMake(1, 30))

0

我修改了你的代碼,並提出瞭解決方案,在我的情況下,我在0.1秒內記錄了我的視圖中的每個圖像,所以我的fps是0.1fps。

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

您的視頻過快的原因是因爲您的比例是1000秒圖像中的1秒。您可以每秒製作1張圖片。

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

試試這個,希望它能幫到你。

0

添加這個庫 AVFoundation CoreMedia corevideo的

我能夠生成視頻,但沒能獲得音頻是人有使用此代碼,並與音頻