【问题标题】:Problems with AVCaptureSession in landscape mode on iPadiPad 上横向模式下的 AVCaptureSession 问题
【发布时间】:2014-06-05 13:59:29
【问题描述】:

我一直在尝试从前置摄像头捕捉帧并将其呈现在视图上。这是我的代码

_session = [[AVCaptureSession alloc] init];
_session.sessionPreset = AVCaptureSessionPreset640x480;

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error];

if (deviceInput) {
    [_session addInput:deviceInput];
}
else {
    DDLogInfo(@"Some wierd shit happened");
    return;
}

// Session output
/*
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:output];
output.metadataObjectTypes = @[AVMetadataObjectTypeFace];
AVCaptureConnection *connection = [output connectionWithMediaType:AVMediaTypeMetadata];
connection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
*/

// Session output
AVCaptureMovieFileOutput *videoOutput = [[AVCaptureMovieFileOutput alloc] init];
[_session addOutput:videoOutput];
AVCaptureConnection *connection = [videoOutput connectionWithMediaType:AVMediaTypeVideo];
connection.videoOrientation = AVCaptureVideoOrientationPortrait;

// Preview layer
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.frame = CGRectMake(0, 0, self.middleView.frame.size.width, self.middleView.frame.size.height);
[self.middleView.layer addSublayer:_previewLayer];

[_session startRunning];

问题是,当我的 iPad 是横向时,表示层上的图像旋转了 90 度。我该如何解决?我一直在浏览堆栈溢出,试图用AVCaptureConnection 做点什么,可惜无济于事。

【问题讨论】:

    标签: ios ipad device-orientation avcapturemoviefileoutput


    【解决方案1】:

    解决了,现在它可以在各个方向工作。我们需要设置这个

    _previewLayer.connection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];
    

    方法在哪里:

     - (AVCaptureVideoOrientation) videoOrientationFromCurrentDeviceOrientation {
    switch (self.interfaceOrientation) {
        case UIInterfaceOrientationPortrait: {
            return AVCaptureVideoOrientationPortrait;
        }
        case UIInterfaceOrientationLandscapeLeft: {
            return AVCaptureVideoOrientationLandscapeLeft;
        }
        case UIInterfaceOrientationLandscapeRight: {
            return AVCaptureVideoOrientationLandscapeRight;
        }
        case UIInterfaceOrientationPortraitUpsideDown: {
            return AVCaptureVideoOrientationPortraitUpsideDown;
        }
    }
    }
    

    还有我们需要设置的捕获输出:

    AVCaptureConnection *output2VideoConnection = [videoOutput connectionWithMediaType:AVMediaTypeVideo];
    output2VideoConnection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];
    

    【讨论】:

    • 别忘了当用户旋转他们的设备时你需要再次设置.connection.videoOrientation :)
    【解决方案2】:

    Swift 3 中:

    首先我们必须像 MegaManX 一样设置previewLayer.connection.videoOrientation

    previewLayer.connection.videoOrientation = self.videoOrientationFromCurrentDeviceOrientation()
    

    方法在哪里:

    func videoOrientationFromCurrentDeviceOrientation() -> AVCaptureVideoOrientation {
        switch UIApplication.shared.statusBarOrientation {
        case .portrait:
            return AVCaptureVideoOrientation.portrait
        case .landscapeLeft:
            return AVCaptureVideoOrientation.landscapeLeft
        case .landscapeRight:
            return AVCaptureVideoOrientation.landscapeRight
        case .portraitUpsideDown:
            return AVCaptureVideoOrientation.portraitUpsideDown
        default:
            // Can this happen?
            return AVCaptureVideoOrientation.portrait
        }
    }
    

    那么我们还要处理用户旋转设备时的videoOrientation(方法来自here

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    
        coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            self.previewLayer.connection.videoOrientation = self.videoOrientationFromCurrentDeviceOrientation()
    
            }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
                // Finish Rotation
        })
    
        super.viewWillTransition(to: size, with: coordinator)
    }
    

    【讨论】:

    • 设备方向被锁定怎么办? viewWillTransitionToSize 方法不会调用。如何管理这个。我必须在设备锁定时检测图片方向。
    • @mahbaleshwarhegde 您的意思是尽管设备方向已锁定,但您仍希望图片随设备一起旋转?
    • 是的。当设备锁定时,我得到 statusBarOrientation 是纵向的。所以即使我在横向模式下拍照,视频连接也会变成纵向。怎么做。有什么想法吗?
    • @mahbaleshwarhegde 试试这个问题的答案stackoverflow.com/q/4574693/2603230 :)
    • 我的应用没有任何 coremotion 功能。如果我使用 coremotion Apple 可能会拒绝该应用程序,仅用于在一个屏幕上获取方向。任何其他想法表示赞赏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多