AVFoundation - 如何从网络摄像头镜像视频 - Mac OS X.

Kir*_*ran 7 macos avfoundation webcam-capture

我试图在mac os x上镜像从网络摄像头收到的视频.我希望在收到视频缓冲区后避免进行手动翻转/转换.所以,我想设置AVCaptureSession这样的captureOutput方法接收的视频缓冲区AVCaptureVideoDataOutputSampleBufferDelegate由AVFoundation本身镜像.我不想使用预览图层.

在iMac(10.8.5)上,镜像视频,AVCaptureConnection isVideoMirroringSupported在设置videoMirrored属性之前已成功通过测试.但代理中收到的视频缓冲区captureOutput未镜像.

注意:当我按照这个 SO答案时,iOS上的视频镜像是成功的.但它对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
    ........
Run Code Online (Sandbox Code Playgroud)

不太重要1 - 虽然是C++,但我也尝试过研究OpenCV的VideoCapture实现,以便镜像视频.但是,OpenCV不会反映来自Mac的视频(使用翻转).左边是libVlc/V4L.

不太重要的2 -在幻灯片73 2010 WWDC上苹果展示(3MB PDF),存在一提的setVideoOrientation是不支持"AVCaptureVideoDataOutput`连接.但在2013年,Apple docs已更新并支持此方法.

tan*_*sk1 6

您可以在预览图层上添加变换,以在帧到达预览窗口之前翻转帧的x值.

[[self previewLayer] setTransform:CATransform3DMakeScale(-1, 1, 1)];
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过导出会话运行录制的视频并执行相同的转换.这样,视频预览将与最终录制的视频相匹配.有点黑客,但它得到了相同的结果.

  • OSX不尊重videoMirrored属性,可能是一个bug.使用预览图层是我发现实现效果的唯一方法. (2认同)

Þor*_*son 5

当它很容易时为什么要破解它。只需设置您的 AVCaptureConnection 的自动调整视频镜像,然后手动设置。

    aPreviewLayer.connection.automaticallyAdjustsVideoMirroring = NO;
    aPreviewLayer.connection.videoMirrored = YES;
Run Code Online (Sandbox Code Playgroud)