overrideOutputAudioPort Не работает должным образом, когда камера открывается с помощью AVCaptureSession на iOS 13 - PullRequest
0 голосов
/ 23 октября 2019

В одном из моих приложений у меня есть функция изменения аудиовыхода, например, изменение аудиовыхода на динамик, даже если подключены внешние наушники, и обратно на внешний наушник от динамика. Он работал нормально в iOS 12, но после обновления нашего устройства OS до 13.1.2, он не работает должным образом. Когда подключены внешние наушники и я звоню try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker), уведомление AVAudioSessionRouteChange вызывается дважды, при первом вызове: это показывает, что выход изменяется с внешнего на внутренний, а при втором вызове: это показывает, что выход снова изменился на внешний. из внутреннего. Поэтому я не могу получить желаемый результат.

Функция Для изменения звука на динамик

func changeToInternal() {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.default, policy: .default, options: .allowBluetooth)
        try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
        try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
        print("Current Route :\(AVAudioSession.sharedInstance().currentRoute)")

        print("------------Changed to Internal-------\n\n\n\n")
    } catch {
        print("------------Change to Internal Error:\(error)-------\n\n\n\n")
    }
}

Код для настройки сеанса:

private func configureSession() {
    if setupResult != .success {
        return
    }

    session.beginConfiguration()

    /*
     Do not create an AVCaptureMovieFileOutput when setting up the session because
     Live Photo is not supported when AVCaptureMovieFileOutput is added to the session.
     */
    session.sessionPreset = .hd1920x1080

    // Add video input.
    do {
        var defaultVideoDevice: AVCaptureDevice?

        // Choose the back dual camera, if available, otherwise default to a wide angle camera.

        if let dualCameraDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back) {
            defaultVideoDevice = dualCameraDevice
        } else if let backCameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) {
            // If a rear dual camera is not available, default to the rear wide angle camera.
            defaultVideoDevice = backCameraDevice
        } else if let frontCameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) {
            // If the rear wide angle camera isn't available, default to the front wide angle camera.
            defaultVideoDevice = frontCameraDevice
        }
        guard let videoDevice = defaultVideoDevice else {
            print("Default video device is unavailable.")
            setupResult = .configurationFailed
            session.commitConfiguration()
            return
        }
        let videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice)

        if session.canAddInput(videoDeviceInput) {
            session.addInput(videoDeviceInput)
            self.videoDeviceInput = videoDeviceInput

            DispatchQueue.main.async {
                /*
                 Dispatch video streaming to the main queue because AVCaptureVideoPreviewLayer is the backing layer for PreviewView.
                 You can manipulate UIView only on the main thread.
                 Note: As an exception to the above rule, it's not necessary to serialize video orientation changes
                 on the AVCaptureVideoPreviewLayer’s connection with other session manipulation.

                 Use the window scene's orientation as the initial video orientation. Subsequent orientation changes are
                 handled by CameraViewController.viewWillTransition(to:with:).
                 */
                var initialVideoOrientation: AVCaptureVideoOrientation = .portrait
                if self.windowOrientation != .unknown {
                    if let videoOrientation = AVCaptureVideoOrientation(interfaceOrientation: self.windowOrientation) {
                        initialVideoOrientation = videoOrientation
                    }
                }

                self.previewView.videoPreviewLayer.connection?.videoOrientation = initialVideoOrientation
            }
        } else {
            print("Couldn't add video device input to the session.")
            setupResult = .configurationFailed
            session.commitConfiguration()
            return
        }
    } catch {
        print("Couldn't create video device input: \(error)")
        setupResult = .configurationFailed
        session.commitConfiguration()
        return
    }

    // Add an audio input device.
    do {
        let audioDevice = AVCaptureDevice.default(for: .audio)
        let audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice!)

        if session.canAddInput(audioDeviceInput) {
            session.addInput(audioDeviceInput)
        } else {
            print("Could not add audio device input to the session")
        }
    } catch {
        print("Could not create audio device input: \(error)")
    }

    if session.canAddOutput(videoDataOutput) {
        session.addOutput(videoDataOutput)
        videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]

        videoDataOutput.setSampleBufferDelegate(self, queue: dataOutputQueue)
    } else {
        print("Could not add video data output to the session")
        setupResult = .configurationFailed
        session.commitConfiguration()
        return
    }

    do {
        let audioDevice = AVCaptureDevice.default(for: .audio)
        let audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice!)

        if self.session.canAddInput(audioDeviceInput) {
            self.session.addInput(audioDeviceInput)
        } else {
            print("Could not add audio device input to the session")
        }
    } catch {
        print("Could not create audio device input: \(error)")
    }

    if self.session.canAddOutput(self.audioOutPut) {
        self.session.addOutput(self.audioOutPut)
        self.audioOutPut.setSampleBufferDelegate(self, queue: self.dataOutputQueue)
    } else {
        print("Could not add audio device output to the session")
    }

    session.commitConfiguration()
}

Найти полный код здесь .

...