我正在尝试录制 GLKView 中显示的内容的视频。我正在使用 Sparrow 框架在 openGL 中显示所需的内容。我正在使用帧缓冲区对象或 FBO 从 openGLES 获取帧,并使用 AVAssetwriter 将这些帧写入视频。好吧,我可以创建视频,但由于 GLKView 中的此内容显示已停止。它不再被刷新。
我正在做的是:
1.在开始编写视频之前,我使用以下方法创建 frameBuffer 对象:
-(void)createFBO{
SPViewController *vC = Sparrow.currentController;
int contentScaleFactor = Sparrow.contentScaleFactor;
int width = vC.view.bounds.size.width*contentScaleFactor;
int height = vC.view.bounds.size.height*contentScaleFactor;
CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [vC context], NULL, &coreVideoTextureCache);
if (err)
{
NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate");
}
CFDictionaryRef empty; // empty value for attr value.
CFMutableDictionaryRef attrs;
empty = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // our empty IOSurface properties dictionary
attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty);
err = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, attrs, &renderTarget);
if (err)
{
NSAssert(NO, @"Error at CVPixelBufferCreate %d", err);
}
CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &renderTarget);
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, renderTarget,
NULL, // texture attributes
GL_TEXTURE_2D,
GL_RGBA, // opengl format
width,
height,
GL_BGRA, // native iOS format
GL_UNSIGNED_BYTE,
0,
&renderTexture);
glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);
/////////
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
NSAssert(status == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", status);
glBindTexture(GL_TEXTURE_2D, 0);
CFRelease(attrs);
CFRelease(empty);
}
2.然后我在-glkView:drawInRect:方法中调用实际编写代码为:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
//Check for recording status and write a frame to video
if (_movieWriter && _movieWriter.isRecording) {
[_movieWriter writeCurrentFrameToVideo];
}
//The code below is unmodified Sparrow-Framework code
@autoreleasepool
{
if (!_root)
{
// ideally, we'd do this in 'viewDidLoad', but when iOS starts up in landscape mode,
// the view width and height are swapped. In this method, however, they are correct.
[self readjustStageSize];
[self createRoot];
}
[Sparrow setCurrentController:self];
[EAGLContext setCurrentContext:_context];
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
[_support nextFrame];
[_stage render:_support];
[_support finishQuadBatch];
if (_statsDisplay)
_statsDisplay.numDrawCalls = _support.numDrawCalls - 2; // stats display requires 2 itself
#if DEBUG
[SPRenderSupport checkForOpenGLError];
#endif
}
}
编写代码是:
-(void)writeCurrentFrameToVideo{
CVPixelBufferLockBaseAddress(renderTarget, 0);
if (!startTime) {
startTime = [NSDate date];
}
CMTime currentTime = CMTimeMakeWithSeconds([[NSDate date] timeIntervalSinceDate:startTime],120);
//[assetWriterPixelBufferInput appendPixelBuffer:pixelBuffer withPresentationTime:currentTime];
if(![assetWriterPixelBufferInput appendPixelBuffer:renderTarget withPresentationTime:currentTime])
{
NSLog(@"Problem appending pixel buffer at time: %lld", currentTime.value);
}
else
{
NSLog(@"Recorded pixel buffer at time: %lld", currentTime.value);
}
CVPixelBufferUnlockBaseAddress(renderTarget, 0);
}
我是openGLES的新手,对它了解不多。请帮忙。
谢谢