【问题标题】:Get Recording Video Raw frames获取录制视频原始帧
【发布时间】:2014-05-01 08:46:56
【问题描述】:

我是 Objective-C 和 iOS 技术的新手。我想通过代码录制视频,并且在运行时,我必须将每一帧作为原始数据进行一些处理。我该如何实现这个?请任何人帮助我。提前致谢。到目前为止,这是我的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self setupCaptureSession];

}

viewDidAppear 函数

-(void)viewDidAppear:(BOOL)animated
{
    if (!_bpickeropen)
    {
       _bpickeropen = true;
        _picker = [[UIImagePickerController alloc] init];
        _picker.delegate = self;
        NSArray *sourceTypes = [UIImagePickerController availableMediaTypesForSourceType:picker.sourceType];
        if (![sourceTypes containsObject:(NSString *)kUTTypeMovie ])
        {
            NSLog(@"device not supported");
            return;
        }

        _picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        _picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie,nil];//,(NSString *) kUTTypeImage
        _picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
        [self presentModalViewController:_picker animated:YES];
    }



}

// 写入样本缓冲区时调用的委托例程

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

    CVImageBufferRef cameraFrame = CMSampleBufferGetImageBuffer(sampleBuffer);


    CVPixelBufferLockBaseAddress(cameraFrame, 0);

    GLubyte *rawImageBytes = CVPixelBufferGetBaseAddress(cameraFrame);

    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(cameraFrame);

    **NSData *dataForRawBytes = [NSData dataWithBytes:rawImageBytes length:bytesPerRow * CVPixelBufferGetHeight(cameraFrame)];

**

问题 1.(这里我只得到一次原始字节) 2.(之后我想将此原始字节作为二进制文件存储在应用程序路径中)。

// Do whatever with your bytes

NSLog(@"bytes per row %zd",bytesPerRow);

[dataForRawBytes writeToFile:[self datafilepath]atomically:YES];

NSLog(@"Sample Buffer Data is %@\n",dataForRawBytes);


CVPixelBufferUnlockBaseAddress(cameraFrame, 0);

}

我在这里设置输出委托//创建和配置捕获会话并开始运行 - (void)setupCaptureSession { NSError *error = nil;

// Create the session
AVCaptureSession *session = [[AVCaptureSession alloc] init];


// Configure the session to produce lower resolution video frames, if your
// processing algorithm can cope. We'll specify medium quality for the
// chosen device.
session.sessionPreset = AVCaptureSessionPresetMedium;

// Find a suitable AVCaptureDevice
AVCaptureDevice *device = [AVCaptureDevice
                           defaultDeviceWithMediaType:AVMediaTypeVideo];

// Create a device input with the device and add it to the session.
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                    error:&error];
if (!input)
{
    // Handling the error appropriately.
}
[session addInput:input];

// Create a VideoDataOutput and add it to the session
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];


// Configure your output.
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);

// Specify the pixel format
output.videoSettings =
[NSDictionary dictionaryWithObject:
 [NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                            forKey:(id)kCVPixelBufferPixelFormatTypeKey]; //kCVPixelBufferPixelFormatTypeKey


// If you wish to cap the frame rate to a known value, such as 15 fps, set
// minFrameDuration.
// output.minFrameDuration = CMTimeMake(1, 15);

// Start the session running to start the flow of data
[session startRunning];

// Assign session to an ivar.
//[self setSession:session];

}

感谢您的帮助。提前致谢。

【问题讨论】:

    标签: ios image-processing video-processing ca


    【解决方案1】:

    您可以查看AVFoundation 框架。它允许您访问从相机生成的原始数据。

    这个link 是一个很好的 AVFoundation 摄像机使用入门级项目。

    为了从视频输出中获取单个帧,您可以使用 AVFoundation 框架中的 AVCaptureVideoDataOutput 类。

    希望这会有所帮助。

    编辑:您可以查看AVCaptureVideoDataOutputSampleBufferDelegate 的委托函数,特别是captureOutput:didOutputSampleBuffer:fromConnection: 方法。每次捕获新帧时都会调用它。

    如果您不知道委托是如何工作的,这个link 就是一个很好的委托示例。

    【讨论】:

    • 是的,我为此使用了 AVFoundation 框架。但我不知道如何以及在哪里调用 AVCaptureVideoDataOutput。因为我的摄像机记录一直在录制,但我只得到一次原始字节。但是我想继续从我的相机中获取。那么我怎样才能以有效的方式使用 AVCaptureVideoDataOutput。从中获取原始字节后,我还必须获取帧的原始字节的二进制格式。所以请帮助我如何我也能做到这一点吗。非常感谢你的有趣。
    • 嗨 Tcharni,我的类的功能是这样的。也给我更多的想法。
    • 嘿,我编辑了我的答案并为您的问题添加了一个可能的解决方案。如果这有帮助,请告诉我。
    • 我在该函数中保留了一个计数值,并且在此方法中继续增加 captureOutput:didOutputSampleBuffer:fromConnection: 中的计数值,但计数值保持不变。是的,我正在使用您告诉 AVCaptureVideoDataOutputSampleBufferDelegate 代表的内容,但在这里我只获取一次原始字节。但我怀疑我想获取每个记录帧的原始字节,并且我想将原始字节转换为二进制格式我必须存储到应用程序内存中,请@tcharni 帮我解决这个问题。我希望你对这个主题有更多的了解。
    • - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { NSLog(@">>>>>>>>>",count++); CVImageBufferRef cameraFrame = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(cameraFrame, 0); GLubyte *rawImageBytes = CVPixelBufferGetBaseAddress(cameraFrame); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(cameraFrame); }
    猜你喜欢
    • 1970-01-01
    • 2013-06-16
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多