0

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

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

我读过这个:试图理解 CMTime 和 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;
        }
    }

}
4

1 回答 1

0

我在 CMTime 和制作电影方面苦苦挣扎。我最终做的是使用:

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

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

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

于 2014-08-10T13:17:18.670 回答