我正在捕捉相机画面并将其写入电影。 我遇到的问题是,在导出电影之后,它前面有几秒钟的黑色(相对于实际录制开始时间)。
我认为这与[self.assetWriter startSessionAtSourceTime:kCMTimeZero];
有关
通过在 samplebuffer 委托(delegate)方法中增加一个 frameStart 变量,我得到了一个半工作解决方案。
- (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;
最佳答案
您不需要自己计算帧时间戳。您可以使用
获取当前样本的时间戳CMTime timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
但是,在我看来,您只是将帧的像素缓冲区未经修改地传递给适配器。像下面这样将样本缓冲区本身直接传递给 assetWriterInput
不是更容易吗?
[self.assetWriterInput appendSampleBuffer:sampleBuffer];
关于ios - AVAssetWriter/AVAssetWriterInputPixelBufferAdaptor - 黑帧和帧率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26712985/