2011-11-09 13 views
12

Obecnie pracuję nad aplikacją na iOS, która stosuje CoreImage w kanale aparatu, aby robić zdjęcia i filmy, a ja wpadłem w szczyptę.AVCaptureSession z wieloma wyjściami?

Do tej pory używam AVCaptureVideoDataOutput uzyskanie bufory próbki i manipulować nimi z CoreImage, a następnie wyświetlane prosty podgląd, jak go używać do robienia zdjęć i ich zapisywania.

Kiedy starałem się wdrożyć Nagrywanie wideo, pisząc SampleBuffers do filmu jak dostałam je od AVCaptureVideoDataOutput, miał bardzo małą szybkość klatek (prawdopodobnie ze względu na inny obraz dotyczącej przetwarzania, które się dzieje) .

Więc zastanawiałem się, czy to możliwe, aby mieć AVCaptureVideoDataOutput a AVCaptureMoveFileOutput dzieje na tej samej AVCaptureSession jednocześnie?

Podałem go szybko i stwierdziłem, że po dodaniu dodatkowego wyjścia, mój AVCaptureVideoDataOutput przestał otrzymywać informacje.

Jeśli mogę sprawić, że działa, mam nadzieję, że oznacza to, że mogę po prostu użyć drugiego wyjścia, aby nagrać wideo z dużą liczbą klatek na sekundę, i zrobić post-processing na wideo po zatrzymaniu nagrywania przez użytkownika.

Każda pomoc zostanie bardzo doceniona.

+0

byłaś używając AVAssetWriter do zapisania obrazu na MOV/MP4? Używam niestandardowego silnika przetwarzania obrazu OpenGL i nadal mogę nagrywać z prędkością 30 klatek na sekundę. Zakładam, że CoreImage będzie OpenGL poparty wydajnością. Podejrzewam, że to, co powstrzymuje cię, to wyświetlanie obrazów. Czy używasz OpenGL do renderowania obrazów, czy używasz innego API (prawdopodobnie opartego na CPU)? –

+0

znalazłeś działające rozwiązanie? – user454083

Odpowiedz

3

To łatwiejsze niż myślisz.

Patrz: AVCamDemo

  1. odczyt danych za pomocą AVCaptureVideoDataOutput.
  2. Utwórz nową kolejkę wysyłkową przed nagraniem, np. recordingQueue: recordingQueue = dispatch_queue_create("Movie Recording Queue", DISPATCH_QUEUE_SERIAL);
  3. W captureOutput: didOutputSampleBuffer: fromConnection: delegować metody przechwytywania samplebuffer, zachowują je, a w kolejce nagranie , zapisz go do pliku:

    -(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"); 
            } 
           } 
          } 
         } 
        } 
    
+0

, proszę, zamień na Swift 4 – user924

Powiązane problemy