Apple的AVCam示例代码崩溃了

时间:2017-03-27 21:41:59

标签: xcode swift3 avcam

我将此示例代码用于我的应用程序,但是当我关闭摄像机视图控制器并且在动画完成之前很快出现问题时,我再次单击返回摄像机视图控制器的按钮。

崩溃说:

libswiftCore.dylib`_swift_abortRetainUnowned:
0x83895e <+0>:  movw   r0, #0xe7ae
0x838962 <+4>:  movt   r0, #0x3
0x838966 <+8>:  add    r0, pc
0x838968 <+10>: ldr    r0, [r0]
0x83896a <+12>: movw   r1, #0xc1ad
0x83896e <+16>: movt   r1, #0x1
0x838972 <+20>: add    r1, pc
0x838974 <+22>: movs   r2, #0x0
0x838976 <+24>: str    r2, [r0, #0xc]
0x838978 <+26>: str    r1, [r0, #0x8]

- &GT; 0x83897a&lt; + 28&gt;:陷阱

当我试图追踪问题时,它有时会引导我走向以下几行:

DispatchQueue.main.async { [unowned self] in
            self.recordButton.isEnabled = self.movieFileOutput != nil
        }
    }

有时以下内容:

self.movieFileOutput = movieFileOutput

任何想法?

thread #7: tid = 0x3ec7a, 0x007a097a libswiftCore.dylib`_swift_abortRetainUnowned + 28, queue = 'session queue', stop reason = EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe)
* frame #0: 0x007a097a libswiftCore.dylib`_swift_abortRetainUnowned + 28
frame #1: 0x007ad1bc libswiftCore.dylib`swift_unknownUnownedLoadStrong + 50
frame #2: 0x000aca0c quichar`CameraViewController.(self=0x176e5e01) -> ()).(closure #2) + 1804 at CameraViewController.swift:229
frame #3: 0x000a9a18 quichar`thunk + 56 at CameraViewController.swift:0
frame #4: 0x00e47d56 libdispatch.dylib`_dispatch_call_block_and_release + 10
frame #5: 0x00e53e62 libdispatch.dylib`_dispatch_queue_serial_drain + 980
frame #6: 0x00e4b204 libdispatch.dylib`_dispatch_queue_invoke + 556
frame #7: 0x00e54390 libdispatch.dylib`_dispatch_queue_override_invoke + 410
frame #8: 0x00e55d9e libdispatch.dylib`_dispatch_root_queue_drain + 408
frame #9: 0x00e55ba6 libdispatch.dylib`_dispatch_worker_thread3 + 112
frame #10: 0x1c49b936 libsystem_pthread.dylib`_pthread_wqthread + 1168
frame #11: 0x1c49b490 libsystem_pthread.dylib`start_wqthread + 8

整个功能如下:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    sessionQueue.async {
        switch self.setupResult {
            case .success:
                // Only setup observers and start the session running if setup succeeded.
                self.addObservers()
                self.session.startRunning()
                self.isSessionRunning = self.session.isRunning

            case .notAuthorized:
                DispatchQueue.main.async { [unowned self] in
                    let message = NSLocalizedString("AVCam doesn't have permission to use the camera, please change privacy settings", comment: "Alert message when the user has denied access to the camera")
                    let alertController = UIAlertController(title: "AVCam", message: message, preferredStyle: .alert)
                    alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Alert OK button"), style: .cancel, handler: nil))
                    alertController.addAction(UIAlertAction(title: NSLocalizedString("Settings", comment: "Alert button to open Settings"), style: .`default`, handler: { action in
                        UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
                    }))

                    self.present(alertController, animated: true, completion: nil)
                }

            case .configurationFailed:
                DispatchQueue.main.async { [unowned self] in
                    let message = NSLocalizedString("Unable to capture media", comment: "Alert message when something goes wrong during capture session configuration")
                    let alertController = UIAlertController(title: "AVCam", message: message, preferredStyle: .alert)
                    alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Alert OK button"), style: .cancel, handler: nil))

                    self.present(alertController, animated: true, completion: nil)
                }
        }
    }


// Switch to Video
    sessionQueue.async { [unowned self] in
        let movieFileOutput = AVCaptureMovieFileOutput()

        if self.session.canAddOutput(movieFileOutput) {
            self.session.beginConfiguration()
            self.session.addOutput(movieFileOutput)
            self.session.sessionPreset = AVCaptureSessionPreset352x288
            if let connection = movieFileOutput.connection(withMediaType: AVMediaTypeVideo) {
                if connection.isVideoStabilizationSupported {
                    connection.preferredVideoStabilizationMode = .auto
                }

            }
            self.session.commitConfiguration()
            //the first place where the problem arise.

            self.movieFileOutput = movieFileOutput
            DispatchQueue.main.async { [unowned self] in
                self.recordButton.isEnabled = true
            }
        }
    }
//Switch Cameras
    recordButton.isEnabled = false

    sessionQueue.async { [unowned self] in
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
        //Do Nothing
        } else {
            return
        }

        let currentVideoDevice = self.videoDeviceInput.device
        let currentPosition = currentVideoDevice!.position

        let preferredPosition: AVCaptureDevicePosition
        let preferredDeviceType: AVCaptureDeviceType

        switch currentPosition {
        case .unspecified, .front:
            preferredPosition = .back
            preferredDeviceType = AVCaptureDeviceType.builtInDualCamera

        case .back:
            preferredPosition = .front
            preferredDeviceType = .builtInWideAngleCamera
        }

        let devices = self.videoDeviceDiscoverySession.devices!
        var newVideoDevice: AVCaptureDevice? = nil

        // First, look for a device with both the preferred position and device type. Otherwise, look for a device with only the preferred position.
        if let device = devices.filter({ $0.position == preferredPosition && $0.deviceType == preferredDeviceType }).first {
            newVideoDevice = device
        }
        else if let device = devices.filter({ $0.position == preferredPosition }).first {
            newVideoDevice = device
        }

        if let videoDevice = newVideoDevice {
            do {
                let videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice)

                self.session.beginConfiguration()

                // Remove the existing device input first, since using the front and back camera simultaneously is not supported.
                self.session.removeInput(self.videoDeviceInput)

                if self.session.canAddInput(videoDeviceInput) {
                    NotificationCenter.default.removeObserver(self, name: Notification.Name("AVCaptureDeviceSubjectAreaDidChangeNotification"), object: currentVideoDevice!)

                    NotificationCenter.default.addObserver(self, selector: #selector(self.subjectAreaDidChange), name: Notification.Name("AVCaptureDeviceSubjectAreaDidChangeNotification"), object: videoDeviceInput.device)

                    self.session.addInput(videoDeviceInput)
                    self.videoDeviceInput = videoDeviceInput
                }
                else {
                    self.session.addInput(self.videoDeviceInput);
                }

                if let connection = self.movieFileOutput?.connection(withMediaType: AVMediaTypeVideo) {
                    if connection.isVideoStabilizationSupported {
                        connection.preferredVideoStabilizationMode = .auto
                    }

                }

                /*
                 Set Live Photo capture enabled if it is supported. When changing cameras, the
                 `isLivePhotoCaptureEnabled` property of the AVCapturePhotoOutput gets set to NO when
                 a video device is disconnected from the session. After the new video device is
                 added to the session, re-enable Live Photo capture on the AVCapturePhotoOutput if it is supported.
                 */
                self.photoOutput.isLivePhotoCaptureEnabled = self.photoOutput.isLivePhotoCaptureSupported;

                self.session.commitConfiguration()
            }
            catch {
                print("Error occured while creating video device input: \(error)")
            }
        }
        //second place that is stop on

        DispatchQueue.main.async { [unowned self] in
            self.recordButton.isEnabled = self.movieFileOutput != nil
        }
    }



}

0 个答案:

没有答案