2014-05-16 15 views
7

Ich versuche, Video von Webcam auf Mac OS X empfangen zu spiegeln. Ich würde gerne vermeiden, eine manuelle Flip/Transform nach dem Erhalt der Video-Puffer zu tun. Also, ich möchte AVCaptureSession so einrichten, dass Video-Puffer in captureOutput Methode AVCaptureVideoDataOutputSampleBufferDelegate empfangen wird von AVFoundation selbst gespiegelt. Ich möchte den Vorschau-Layer nicht verwenden.AVFoundation - wie Video von Webcam zu spiegeln - Mac OS X

Auf einem iMac (10.8.5) wird zum Spiegeln des Videos erfolgreich getestet, bevor die videoMirrored-Eigenschaft festgelegt wird. Aber der in captureOutput empfangene Videopuffer wird nicht gespiegelt.

Hinweis: Videospiegelung auf iOS war erfolgreich, als ich folgte this SO Antwort. Aber es hilft nicht auf Mac OS X.

Der verwendete Code ist unten. Die Fehlerprüfung ist für diesen Beitrag ausgelassen.

//create session 
    _session = [[AVCaptureSession alloc] init]; 

    //get capture device 
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    //create sesion input 
    NSError * error; 
    _sessionInput = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error]; 

    //create session output 
    _sessionOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    [_sessionOutput setAlwaysDiscardsLateVideoFrames:YES]; 
    [[_sessionOutput connectionWithMediaType:AVMediaTypeVideo] setEnabled:YES]; 
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 
    [_sessionOutput setVideoSettings:videoSettings]; 

    //serial queue to process video frames 
    dispatch_queue_t videoOutputQueue = dispatch_queue_create("deviceeraQueue", DISPATCH_QUEUE_SERIAL); 
    [_sessionOutput setSampleBufferDelegate:self queue:videoOutputQueue]; 

    //begin session configuration 
    [_session beginConfiguration ]; 

    //input and output for session 
    if([_session canAddInput:_sessionInput]) { 
     [_session addInput:_sessionInput]; 
    } 
    if([_session canAddOutput:_sessionOutput]) { 
     [_session addOutput:_sessionOutput]; 

    } 

    //set video mirroring 
    AVCaptureConnection* avConnection = [_sessionOutput connectionWithMediaType:AVMediaTypeVideo]; 
    if([avConnection isVideoMirroringSupported]) { 
     avConnection.videoMirrored = YES; 
     NSLog(@"Video mirroring Support: YES"); // this line is printed 
    } else { 
     NSLog(@"Video mirroring Support: NO"); 
    } 

    //set session preset  
    [_session setSessionPreset:AVCaptureSessionPreset640x480]; 
    [ _session commitConfiguration ]; 

    ........... 
    ........... 

    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
    { 
    ......... 
    //sampleBuffer is not mirrored video 
    ........ 

Von geringerer Bedeutung 1 - obwohl C++, habe ich versucht, auch für Videocapture-Implementierung OpenCV Weg, um in Video zu spiegeln. Aber OpenCV spiegelt kein Video vom Mac (verwendet Flip). Links ist libVlc/V4L.

Von geringerer Wichtigkeit 2 - In Folie 73 von this 2010 wwdc Apple-Präsentation (3Mb pdf), gibt es eine Erwähnung, dass setVideoOrientation nicht auf 'AVCaptureVideoDataOutput'-Verbindung unterstützt wird. Aber im Jahr 2013 sind Apple docs aktualisiert und unterstützt diese Methode.

Antwort

5

Sie können eine Transformation auf der Vorschauebene hinzufügen, um den x-Wert der Bilder zu spiegeln, bevor sie in das Vorschaufenster gelangen.

[[self previewLayer] setTransform:CATransform3DMakeScale(-1, 1, 1)]; 

Dann können Sie das aufgezeichnete Video durch Exportsitzung ausführen und die gleiche Umwandlung durchführen. Auf diese Weise wird die Videovorschau mit dem zuletzt aufgenommenen Video übereinstimmen. Etwas von einem Hack, aber es bringt die gleichen Ergebnisse.

+0

Danke. Aber in Frage, hatte ich erwähnt über die Zurückhaltung, Preview-Layer zu verwenden (in Absatz 1) – Kiran

+2

OSX nicht respektiert die videoMirrored-Eigenschaft, wahrscheinlich ein Bug. Die einzige Möglichkeit, den Effekt zu erzielen, ist die Verwendung einer Vorschau-Ebene. – tansk1

2

Warum hack es, wenn es sehr einfach ist. Stellen Sie einfach AutoVideoMirroring Ihrer AVCaptureConnection automatisch ein und stellen Sie es manuell ein.

aPreviewLayer.connection.automaticallyAdjustsVideoMirroring = NO; 
    aPreviewLayer.connection.videoMirrored = YES; 
+0

Danke. Aber bitte sehen Sie meine Erwähnung über die Zurückhaltung zu Ihrer Vorschau-Ebene (in Absatz 1 der Frage). Das gleiche wird wieder in meinem Kommentar zu der früheren Antwort erwähnt. – Kiran

+0

Ich glaube nicht, dass Sie ohne die Vorschau-Ebene können. Aber Sie können sicherlich den gleichen Effekt erzielen, zum Beispiel durch Skalierung. Scaling-Puffer von (x, y, z) = (-1,1,1) würde die Spiegelung Affekt erreichen :) –

+0

'Ich glaube nicht, dass Sie ohne die Vorschau-Layer können. - Dann, um die Frage zu schließen unterstützen, dass wir ein gültiges Quelldokument oder einen akzeptierten Fehlerbericht von Apple benötigen. – Kiran