изображение с iphone на видео проблема в скорости видео - PullRequest
1 голос
/ 14 декабря 2011

Я сделал преобразование изображения в видео в iphone (конечно, я получил код из вопросов переполнения стека).Но проблема в том, что скорость записанного видео очень высока, он сбежал за 2 секунды, хотя у меня около 2250 кадров.Я знаю, проблема в частоте кадров.Но я не знаю, как сделать это правильно.мой код ниже

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 и как я могу сделать это правильно Одинбольше помогите, как я могу добавить аудио с этим видео.

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

Ваши PTS очень близко друг к другу. Вместо CMTimeMake(1, 1000), почему бы не 30FPS: CMTimeMake(1, 30))?

0 голосов
/ 27 декабря 2012

Добавить эту библиотеку AVFoundation CoreMedia CoreVideo

Я могу генерировать видео, но не могу получить аудио, если кто-то использовал этот код и создавал видео со звуком

0 голосов
/ 21 октября 2012

Я пересмотрел ваш код и пришел к решению, в моем случае я записываю каждое изображение в моем представлении за 0,1 секунды, поэтому мой fps равен 0.1fps.

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

Причина, по которой ваше видео слишком быстрое, потому что ваше соотношение составляет 1 секунду на 1000 изображений. Вы можете сделать это 1 изображение в секунду.

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

Попробуйте, надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...