- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对这个简直要疯了 - 到处都看了,也尝试了我能想到的一切。
我正在制作一个使用 AVFoundation - 特别是 AVCapture 来使用 iPhone 相机捕获视频的 iPhone 应用程序。
我需要一个覆盖在录制内容中的视频源上的自定义图像。
到目前为止,我已经设置了 AVCapture session ,可以显示提要、访问框架、将其保存为 UIImage 并将覆盖图像添加到其上。然后将这个新的 UIImage 转换为 CVPixelBufferRef。为了仔细检查 bufferRef 是否正常工作,我将其转换回 UIImage,并且它仍然可以很好地显示图像。
当我尝试将 CVPixelBufferRef 转换为 CMSampleBufferRef 以附加到 AVCaptureSessions assetWriterInput 时,问题就开始了。当我尝试创建 CMSampleBufferRef 时,它总是返回 NULL。
这是 -(void)captureOutput 函数
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
UIImage *botImage = [self imageFromSampleBuffer:sampleBuffer];
UIImage *wheel = [self imageFromView:wheelView];
UIImage *finalImage = [self overlaidImage:botImage :wheel];
//[previewImage setImage:finalImage]; <- works -- the image is being merged into one UIImage
CVPixelBufferRef pixelBuffer = NULL;
CGImageRef cgImage = CGImageCreateCopy(finalImage.CGImage);
CFDataRef image = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
int status = CVPixelBufferCreateWithBytes(NULL,
self.view.bounds.size.width,
self.view.bounds.size.height,
kCVPixelFormatType_32BGRA,
(void*)CFDataGetBytePtr(image),
CGImageGetBytesPerRow(cgImage),
NULL,
0,
NULL,
&pixelBuffer);
if(status == 0){
OSStatus result = 0;
CMVideoFormatDescriptionRef videoInfo = NULL;
result = CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixelBuffer, &videoInfo);
NSParameterAssert(result == 0 && videoInfo != NULL);
CMSampleBufferRef myBuffer = NULL;
result = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,
pixelBuffer, true, NULL, NULL, videoInfo, NULL, &myBuffer);
NSParameterAssert(result == 0 && myBuffer != NULL);//always null :S
NSLog(@"Trying to append");
if (!CMSampleBufferDataIsReady(myBuffer)){
NSLog(@"sampleBuffer data is not ready");
return;
}
if (![assetWriterInput isReadyForMoreMediaData]){
NSLog(@"Not ready for data :(");
return;
}
if (![assetWriterInput appendSampleBuffer:myBuffer]){
NSLog(@"Failed to append pixel buffer");
}
}
}
我不断听到的另一个解决方案是使用 AVAssetWriterInputPixelBufferAdaptor,它消除了进行困惑的 CMSampleBufferRef 包装的需要。但是,我搜索了 stacked 和苹果开发者论坛和文档,但找不到有关如何设置或如何使用它的清晰描述或示例。如果有人有一个可行的示例,请您向我展示或帮助我解决上述问题 - 我已经为此不间断地工作了一个星期,但束手无策。
如果您需要任何其他信息,请告诉我
提前致谢,
迈克尔
最佳答案
您需要 AVAssetWriterInputPixelBufferAdaptor,这是创建它的代码:
// Create dictionary for pixel buffer adaptor
NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil];
// Create pixel buffer adaptor
m_pixelsBufferAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:bufferAttributes];
以及使用它的代码:
// If ready to have more media data
if (m_pixelsBufferAdaptor.assetWriterInput.readyForMoreMediaData) {
// Create a pixel buffer
CVPixelBufferRef pixelsBuffer = NULL;
CVPixelBufferPoolCreatePixelBuffer(NULL, m_pixelsBufferAdaptor.pixelBufferPool, &pixelsBuffer);
// Lock pixel buffer address
CVPixelBufferLockBaseAddress(pixelsBuffer, 0);
// Create your function to set your pixels data in the buffer (in your case, fill with your finalImage data)
[self yourFunctionToPutDataInPixelBuffer:CVPixelBufferGetBaseAddress(pixelsBuffer)];
// Unlock pixel buffer address
CVPixelBufferUnlockBaseAddress(pixelsBuffer, 0);
// Append pixel buffer (calculate currentFrameTime with your needing, the most simplest way is to have a frame time starting at 0 and increment each time you write a frame with the time of a frame (inverse of your framerate))
[m_pixelsBufferAdaptor appendPixelBuffer:pixelsBuffer withPresentationTime:currentFrameTime];
// Release pixel buffer
CVPixelBufferRelease(pixelsBuffer);
}
并且不要忘记释放您的 PixelBufferAdaptor。
关于iphone - AVCapture追加SampleBuffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3846331/
我正在使用 ReplayKit 录制视频: let sharedRecorder = RPScreenRecorder.shared() sharedRecorder.startC
我使用此代码从相机捕获视频,但 CMSampleBufferGetImageBuffer(sampleBuffer) 始终返回 nil。问题是什么?。这是代码,我修改了此源代码以适应 Swift 4
我尝试将示例缓冲区而不是 UIImage 保存到数组中,以便稍后转换它。这样可以加快图像捕获速度,并且可能不会收到内存警告。我只是不知道如何将它保存到数组,然后再次使用它来调用 [self image
我正在使用前置摄像头,当我捕捉帧时,它们会逆时针旋转 90 度。我想在 CGContext 中旋转捕获的图像(因为我读到 Core Graphic 比其他框架快得多)。 这是我的代码: func ca
如何在 Swift 中使用“CFRetain(sampleBuffer)”和“CFRelease(sampleBuffer)”? CFRetain 不可用:Core Foundation 对象自动进行
我正在尝试使用 OpenCV 进行实时相机处理。在 AVCaptureVideoDataOutputSampleBufferDelegate 的 didOutputSampleBuffer 方法中,我
我正在努力解决这个问题。我想使用 AVAssetWriterInput 在 OSX 上使用 Swift 录制实时视频。 我创建了一个名为 input 的 AVAssetWriterInput 实例,我
我试图更好地理解 AVFoundation 框架以及各种 Core xxxx 框架,因此我决定尝试一个简单的视频捕获,看看是否可以将图像输出到 UI。我查看了 rosyWriter 代码和文档,但没有
如何在 Swift 3 中将 captureStillImageAsynchronously(sampleBuffer) 转换为 base64 编码 我正在尝试将图像数据连续馈送到 HTML WebV
我是一名优秀的程序员,十分优秀!