Подтвердить что ты не робот

AVCaptureSession с несколькими выходами?

В настоящее время я разрабатываю приложение iOS, которое применяет CoreImage к каналу камеры для съемки фотографий и видео, и я столкнулся с некоторой проблемой.

До сих пор я использовал AVCaptureVideoDataOutput для получения пробных буферов и управления ими с помощью CoreImage, а затем отображал простой предварительный просмотр, а также использовал его для захвата фотографий и их сохранения.

Когда я попытался выполнить видеозапись, написав SampleBuffers на видео, когда я получил их из AVCaptureVideoDataOutput, он имел очень медленную частоту кадров (вероятно, из-за другого изображения, связанного с обработкой, которая продолжалось).

Итак, мне было интересно: возможно ли иметь AVCaptureVideoDataOutput и AVCaptureMoveFileOutput одновременно на одном и том же AVCaptureSession?

Я быстро перешел к нему и обнаружил, что когда я добавил дополнительный вывод, мой AVCaptureVideoDataOutput прекратил получать информацию.

Если я могу заставить его работать, я надеюсь, что это означает, что я могу просто использовать второй выход для записи видео с высокой частотой кадров и выполнять пост-обработку на видео после того, как пользователь остановил запись.

Любая помощь будет принята с благодарностью.

4b9b3361

Ответ 1

Это проще, чем вы думаете.

Смотрите: AVCamDemo

  • Захват данных с помощью AVCaptureVideoDataOutput.
  • Создайте новую очередь отправки перед записью, например. recordQueue: recordingQueue = dispatch_queue_create("Movie Recording Queue", DISPATCH_QUEUE_SERIAL);
  • В captureOutput: didOutputSampleBuffer: fromConnection: delegate   метод, захват буфера выборки, сохранение его и запись   очереди, напишите его в файл:

    -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {    
    
        CFRetain(sampleBuffer);
    
        dispatch_async(recordingQueue, ^{
    
            if (assetWriter) {
    
                if (connection == videoConnection) {
                    [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo];
                } else if (connection == audioConnection) {
                    [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeAudio];
                }
    
            }
    
            CFRelease(sampleBuffer);        
        });
    }
    
        - (void) writeSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(NSString *)mediaType
        {
            CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
    
            if ( assetWriter.status == AVAssetWriterStatusUnknown ) {
    
                if ([assetWriter startWriting]) {
                    [assetWriter startSessionAtSourceTime:presentationTime];
                } else {
                    NSLog(@"Error writing initial buffer");
                }
            }
    
            if ( assetWriter.status == AVAssetWriterStatusWriting ) {
    
                if (mediaType == AVMediaTypeVideo) {
                    if (assetWriterVideoIn.readyForMoreMediaData) {
    
                        if (![assetWriterVideoIn appendSampleBuffer:sampleBuffer]) {
                            NSLog(@"Error writing video buffer");
                        }
                    }
                }
                else if (mediaType == AVMediaTypeAudio) {
                    if (assetWriterAudioIn.readyForMoreMediaData) {
    
                        if (![assetWriterAudioIn appendSampleBuffer:sampleBuffer]) {
                            NSLog(@"Error writing audio buffer");
                        }
                    }
                }
            }
        }