将OpenGL视图捕获到AVAssetWriterInputPixelBufferAdaptor

时间:2011-11-10 14:20:52

标签: iphone export avfoundation opengl-es-2.0 avassetwriter

我正在尝试创建一个AVAssetWriter来捕获一个openGL项目。我从来没有写过AVAssetWriter或AVAssetWriterInputPixelBufferAdaptor所以我不确定我是否做了正确的事。

- (id) initWithOutputFileURL:(NSURL *)anOutputFileURL {
    if ((self = [super init])) {
        NSError *error;
        movieWriter = [[AVAssetWriter alloc] initWithURL:anOutputFileURL fileType:AVFileTypeMPEG4 error:&error];
        NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                       AVVideoCodecH264, AVVideoCodecKey,
                                       [NSNumber numberWithInt:640], AVVideoWidthKey,
                                       [NSNumber numberWithInt:480], AVVideoHeightKey,
                                       nil];
        writerInput = [[AVAssetWriterInput
                        assetWriterInputWithMediaType:AVMediaTypeVideo
                        outputSettings:videoSettings] retain];
        writer = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:writerInput sourcePixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey,nil]];

        [movieWriter addInput:writerInput];
        writerInput.expectsMediaDataInRealTime = YES;
    }

    return self;
}

班上的其他部分:

- (void)getFrame:(CVPixelBufferRef)SampleBuffer:(int64_t)frame{
    frameNumber = frame;
    [writer appendPixelBuffer:SampleBuffer withPresentationTime:CMTimeMake(frame, 24)]; 
}

- (void)startRecording {
   [movieWriter startWriting];
   [movieWriter startSessionAtSourceTime:kCMTimeZero];
}

- (void)stopRecording {
   [writerInput markAsFinished];
   [movieWriter endSessionAtSourceTime:CMTimeMake(frameNumber, 24)];
   [movieWriter finishWriting];
}

资产撰稿人由以下人士发起:

    NSURL *outputFileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]];
    recorder = [[GLRecorder alloc] initWithOutputFileURL:outputFileURL];

视图以这种方式记录:

    glReadPixels(0, 0, 480, 320, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    for(int y = 0; y <320; y++) {
    for(int x = 0; x <480 * 4; x++) {
        int b2 = ((320 - 1 - y) * 480 * 4 + x);
        int b1 = (y * 4 * 480 + x);
        buffer2[b2] = buffer[b1];
    }
}    
pixelBuffer = NULL;
CVPixelBufferCreateWithBytes (NULL,480,320,kCVPixelFormatType_32BGRA,buffer2,1920,NULL,0,NULL,&pixelBuffer);
[recorder getFrame:pixelBuffer :framenumber];
    framenumber++;

注意:

pixelBufferCVPixelBufferRef framenumberint64_t bufferbuffer2GLubyte

我没有错误但是当我完成录制时没有文件。任何帮助或帮助链接将非常感激。 opengl来自相机的实时馈送。我已经能够将屏幕保存为UIImage,但想要拍摄我创作的电影。

2 个答案:

答案 0 :(得分:0)

如果您正在编写RGBA帧,我认为您可能需要使用AVAssetWriterInputPixelBufferAdaptor来编写它们。这个类应该管理一个像素缓冲池,但我觉得它实际上将你的数据按摩成YUV。

如果有效,那么我认为你会发现你的颜色都被交换了,你可能需要写像素着色器才能将它们转换为BGRA。或者(颤抖)在CPU上做。由你决定。

答案 1 :(得分:0)

在这里找到答案:Saving to library 我从未将视频保存到carmera roll。

我不得不用时间来更改相机胶卷中创建的文件的名称,这样它就不会自动保存或反复保存同一个文件。