将UIImage数组导出为视频 - 相应地设置CMTime

时间:2014-08-10 12:19:35

标签: objective-c arrays uiimage movie cmtime

我有一个10帧的UIImage数组。我想把它导出为总共15秒的电影。所以它必须循环这10帧长达15秒。在每帧之间,我需要0.2秒的间隔。

我设法创建了一个我的数组的电影,但我不明白CMTime是如何工作的。我试过弄乱数字,但我无法得到我想要的结果。要么我的电影太短,要么播放得太快等等......

我已经读过这个: Trying to understand CMTime and CMTimeMake 但它对我来说仍然没有意义......

我需要了解这3个CMTime变量是如何相互关联的

CMTime frameTime = CMTimeMake(1, 5);
CMTime lastTime = CMTimeMake(i, 5);
CMTime presentTime = CMTimeAdd(lastTime, frameTime);

这是我正在使用的代码

- (void)writeImageAsMovie:(NSArray *)array toPath:(NSURL*)path size:(CGSize)size {
    NSError *error = nil;
   self.videoWriter = [[AVAssetWriter alloc] initWithURL:path
                                                           fileType:AVFileTypeMPEG4
                                                              error:&error];
    NSParameterAssert(self.videoWriter);

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:size.height], AVVideoHeightKey,
                                   nil];
    AVAssetWriterInput* writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
                                                                          outputSettings:videoSettings];
    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
    [attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
    [attributes setObject:[NSNumber numberWithUnsignedInt:size.width] forKey:(NSString*)kCVPixelBufferWidthKey];
    [attributes setObject:[NSNumber numberWithUnsignedInt:size.height] forKey:(NSString*)kCVPixelBufferHeightKey];

    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:attributes];
    NSParameterAssert(writerInput);
    NSParameterAssert([self.videoWriter canAddInput:writerInput]);
    [self.videoWriter addInput:writerInput];
    writerInput.expectsMediaDataInRealTime = YES;


    //Start a session:
    [self.videoWriter startWriting];
    [self.videoWriter startSessionAtSourceTime:kCMTimeZero];

    CVPixelBufferRef buffer = NULL;
    buffer = ([self pixelBufferFromCGImage:[[array objectAtIndex:0] CGImage] size:CGSizeMake(size.width, size.height)]);
    CVPixelBufferPoolCreatePixelBuffer (NULL, adaptor.pixelBufferPool, &buffer);

    [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];
    int i = 1;
    while (writerInput.readyForMoreMediaData)
    {
        CMTime frameTime = CMTimeMake(1, 15);
        CMTime lastTime= CMTimeMake(i, 15);
        CMTime presentTime= CMTimeAdd(lastTime, frameTime);

        if (i >= [array count]) {
            buffer = NULL;
        }
        else {
            buffer = [self pixelBufferFromCGImage:[[array objectAtIndex:i] CGImage] size:size];
        }

        if (buffer) {
            [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
            i++;
        } else {

            [writerInput markAsFinished];
            [self.videoWriter finishWritingWithCompletionHandler:^{
                NSLog (@"Done");

            }];

            CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
            break;
        }
    }

}

1 个答案:

答案 0 :(得分:0)

我与CMTime挣扎并拍电影。我最终做的是使用:

CMTime presentTime = CMTimeMake(frameNum, (int32_t)fps);

我认为你所追求的是5的fps(在帧之间给你0.2秒)然后你会添加总共75帧(对于15秒的电影)。您可以将每张图像显示7.5次(我知道 - 需要为int - 如果您有10帧,可以选择不同的fps或电影长度)来拍摄电影。

诠: fps = 5,所需的电影长度16秒= 80帧。将每个图像添加到电影8次。