AVAssetWriter / AVAssetWriterInputPixelBufferAdaptor - 黑帧和帧速率

时间:2014-11-03 11:10:50

标签: ios objective-c avfoundation avassetwriter

我正在拍摄相机信息并将其写入电影。 我遇到的问题是导出后电影前面有几个黑秒(相对于实际录制开始时间)。

我认为这与[self.assetWriter startSessionAtSourceTime:kCMTimeZero];有关 我有一个半工作的解决方案,它有一个frameStart变量,它在samplebuffer委托方法中向上计数。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    frameStart++;
    if (self.startRecording == YES) {

        static int64_t frameNumber = 0;
        if(self.assetWriterInput.readyForMoreMediaData) {
            [self.pixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:CMTimeMake(frameNumber, 25)];
        }
        frameNumber++;
    }
}

然后在用户按下按钮时调用此方法:

[self.assetWriter startSessionAtSourceTime:CMTimeMake(frameStart,25)];
这是有效的。但只有一次......如果我想要录制第二部电影,那么黑框会再次回来。

另外,当我看输出的电影时,帧速率是25fps,就像我想要的那样。但视频看起来好像加快了。好像框架之间没有足够的空间。所以这部电影的播放速度快了两倍。

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:640], AVVideoWidthKey, [NSNumber numberWithInt:480], AVVideoHeightKey, AVVideoCodecH264, AVVideoCodecKey, nil];

self.assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:outputSettings];
self.assetWriterInput.expectsMediaDataInRealTime = YES;

2 个答案:

答案 0 :(得分:2)

您不需要自己计算帧时间戳。您可以使用

获取当前样本的时间戳
CMTime timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);

然而,在我看来,你只是将帧的像素缓冲区传递给适配器而不进行修改。将样本缓冲区本身直接传递给assetWriterInput会不会更容易,如下所示?

[self.assetWriterInput appendSampleBuffer:sampleBuffer];

答案 1 :(得分:0)

首先,为什么每帧增加两次frameNumber? 增加一次,删除第一个。 这应该可以确定播放速度。

其次,你完成录制时是否将frameNumber重置为0? 如果不是这个是你的问题。 如果不是,我需要更多解释这里发生的事情..

问候