2014-05-16 191 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

相关问题