2014-05-16 192 views
7

我想在Mac OS X上鏡像從網絡攝像頭接收到的視頻。我想避免在收到視頻緩衝區後做手動翻轉/變換。所以,我想要設置AVCaptureSession,使得在captureOutput方法AVCaptureVideoDataOutputSampleBufferDelegate中接收到的視頻緩衝區被AVFoundation本身鏡像。我不想使用預覽圖層。AVFoundation - 如何從網絡攝像頭鏡像視頻 - Mac OS X

在設置videoMirrored屬性之前,在iMac(10.8.5)上,爲了鏡像視頻,已成功測試了AVCaptureConnection isVideoMirroringSupported。但是,在captureOutput代表中收到的視頻緩衝區不是鏡像的。

注意:iOS上的視頻鏡像成功,當我按照this SO回答。但它在mac os x上沒有幫助。

使用的代碼如下。錯誤檢查被忽略了這篇文章。

//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 
    ........ 

不太重要1 - 儘管C++,我也試着研究OpenCV的VideoCapture實現方式來鏡像視頻。但是,OpenCV不會鏡像來自Mac的視頻(使用翻轉)。左邊是libVlc/V4L。

不太重要2 - 在this 2010 wwdc蘋果演示文稿(3Mb pdf)的幻燈片73中,提到setVideoOrientation在'AVCaptureVideoDataOutput`連接上不受支持。但在2013年,Apple docs已更新並支持此方法。

回答

5

您可以在預覽圖層上添加一個轉換,以在幀到達預覽窗口之前翻轉x值。

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

然後,您可以通過導出會話運行錄製的視頻並進行相同的轉換。這樣視頻預覽將匹配最終錄製的視頻。黑客的位,但獲得相同的結果。

+0

謝謝。但有問題,我曾提到過不願意使用預覽圖層(在第1段中) – Kiran

+2

OSX不尊重videoMirrored屬性,可能是一個錯誤。使用預覽圖層是我發現達到效果的唯一方式。 – tansk1

2

爲什麼在非常簡單的情況下破解它。只需設置AVCaptureConnection的自動調整視頻鏡像,然後手動設置即可。

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

謝謝。但請親切看到我提到的不願意預覽圖層的問題(在問題的第1段中)。在我對先前的回答的評論中再次提到了這一點。 – Kiran

+0

我不認爲你可以不使用預覽圖層。但你可以通過縮放比例來達到同樣的效果。通過(x,y,z)=(-1,1,1)縮放緩衝區將實現鏡像效果:) –

+0

'我不認爲你可以不使用預覽圖層。「 - 然後關閉問題,支持這一點,我們將需要一份有效的原始文檔或Apple接受的錯誤報告。 – Kiran

相關問題