iOS10,相机权限-“相机应用”黑屏

Posted

技术标签:

【中文标题】iOS10,相机权限-“相机应用”黑屏【英文标题】:iOS10, camera permission - black screen for "camera app" 【发布时间】:2016-10-03 16:23:27 【问题描述】:

当然,对于 ios 10,您现在必须这样做

使用手机的相机。首次启动时,用户会收到一个问题,例如,

一切都很好。

但是我们有一个“相机应用”的客户端应用:当您启动应用时它会立即启动相机,当应用运行时相机正在运行并全屏显示。这样做的代码是通常的方式,见下文。

问题是 - 在手机上首次启动应用程序时,会询问用户问题;用户说是的。但是,在我们尝试过的设备上,相机只是黑色的。它不会崩溃(就像你忘记了 plist 项一样),但它会变黑并保持黑色。

如果用户退出应用程序并再次启动它 - 没关系,一切正常。

“相机应用”的工作流程到底是什么?我看不到一个好的解决方案,但必须有一个适用于各种相机应用的解决方案 - 立即进入全屏启动应用时的相机。

class CameraPlane:UIViewController
    
    ... 
    func cameraBegin()
        
        captureSession = AVCaptureSession()
        captureSession!.sessionPreset = AVCaptureSessionPresetPhoto

        let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

        var error: NSError?
        var input: AVCaptureDeviceInput!
        do 
            input = try AVCaptureDeviceInput(device: backCamera)
             catch let error1 as NSError
                
                error = error1
                input = nil
                

        if ( error != nil )
            
            print("probably on simulator? no camera?")
            return;
            

        if ( captureSession!.canAddInput(input) == false )
            
            print("capture session problem?")
            return;
            

        captureSession!.addInput(input)

        stillImageOutput = AVCaptureStillImageOutput()
        stillImageOutput!.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]

        if ( captureSession!.canAddOutput(stillImageOutput) == false )
            
            print("capture session with stillImageOutput problem?")
            return;
            

        captureSession!.addOutput(stillImageOutput)
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
                                        // or, AVLayerVideoGravityResizeAspect

        fixConnectionOrientation()

        view.layer.addSublayer(previewLayer!)
        captureSession!.startRunning()
        previewLayer!.frame = view.bounds
        

【问题讨论】:

你应该在获得权限后初始化相机,像这样AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if(status == AVAuthorizationStatusAuthorized) else [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) [self performSelectorOnMainThread:@selector(initializeCamera) withObject:nil waitUntilDone:NO]; ]; 【参考方案1】:

注意:很可能 OP 的代码实际上在新的 ISO10 权限字符串方面工作正常,并且 OP 有另一个问题导致黑屏。


从您发布的代码中,我无法判断您为什么会遇到这种行为。我只能给你适合我的代码。

此代码也可以在 iOS 9 上运行。请注意,我将相机加载到 viewDidAppear 以确保设置了所有约束。

import AVFoundation

class ViewController : UIViewController 

    //the view where the camera feed is shown
    @IBOutlet weak var cameraView: UIView!

    var captureSession: AVCaptureSession = 
        let session = AVCaptureSession()
        session.sessionPreset = AVCaptureSessionPresetPhoto
        return session
    ()
    var sessionOutput = AVCaptureStillImageOutput()
    var previewLayer = AVCaptureVideoPreviewLayer()

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)

        let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice]
        guard let backCamera = (devices?.first     $0.position == .back    ) else 
            print("The back camera is currently not available")
            return
        

        do 
            let input = try AVCaptureDeviceInput(device: backCamera)
            if captureSession.canAddInput(input)
                captureSession.addInput(input)
                sessionOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]

                if captureSession.canAddOutput(sessionOutput) 
                    captureSession.addOutput(sessionOutput)
                    captureSession.startRunning()

                    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                    previewLayer.connection.videoOrientation = .portrait
                    cameraView.layer.addSublayer(previewLayer)

                    previewLayer.position = CGPoint(x: cameraView.frame.width / 2, y: cameraView.frame.height / 2)
                    previewLayer.bounds = cameraView.frame
                
            
         catch 
            print("Could not create a AVCaptureSession")
        
    

如果您希望相机全屏显示,您只需使用view 而不是cameraView。在我的相机实现中,相机源并没有覆盖整个视图,还有一些导航内容。

【讨论】:

嗨斜线。感谢这个很好的例子。说 - 你很确定,如果你完全卸载应用程序,然后使用你的代码方法安装 - 它确实有效吗?您第一次(仅)启动应用程序时没有遇到“黑屏”问题?谢谢! 不,我刚刚删除了应用程序,重新安装了它,当我打开它时,我没有黑屏。似乎工作。 知道了 - 明确一点,当你这样做时:当然,iOS 会请求用户的许可,对吧? 是的,它要求获得许可。如果您单击“是”,您会看到摄像头供稿。如果单击“否”,则带有摄像头馈送的视图为黑色。所以如果用户点击拒绝访问,你仍然需要编写一些代码来重新请求相机权限。 太棒了,谢谢。可以确认您的代码运行良好。当然,我完全有可能搞砸了别的东西——而我的原始代码本来可以不用管的,呵呵! :) 顺便说一句,有趣的是您不使用 sessionPreset(例如captureSession!.sessionPreset = AVCaptureSessionPresetPhoto)。不管用什么设备,你是否发现你得到了“正确的形状”?有趣的东西。【参考方案2】:

发生的情况是,在第一次启动时,您正在激活相机,然后它才能检查权限是什么并显示适当的 UIAlertController。您想要做的是将此代码包含在 if 语句中以检查相机权限的状态 (AVAuthorizationStatus)。如果不允许,请确保在显示相机之前请求许可。如需更多帮助,请参阅this question。

【讨论】:

以上是关于iOS10,相机权限-“相机应用”黑屏的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发调用相机时出现黑屏的解决办法(原因:没有获取到相机权限)

调用相机应用程序(权限拒绝:启动 Intent )

我需要啥权限才能在相机预览中使用相机闪光灯?

从android中的意图选择器中选择选项(相机或画廊)后请求权限

我的简单相机应用程序(android)在第一次尝试后不会加载相机视图

关于Android6.0权限的学习