SwiftUI screen freezes upon ending of AVSpeech

80 Views Asked by At

In the UI there is a button that, when pressed, plays a short greeting. To test performance I scroll the screen's carousel endlessly. All is well while the voice speaks however, ~1 second after it concludes, the scrolling stopps as the screen freezes for 1 second before again returning to normal. I removed the speech upon clicking, to test if it were any other logic but the problem went away once I did.

When running, this message gets printed to the console:

Failed to deactivate audio session: Session deactivation failed

    struct UIScreen: View {
        let speechSynthesizer = SpeechSynthesizerManager()
        var body: some View {
            ZStack{
                CarouselView()
                Button {
                    speechSynthesizer.speak(say: "Pause")
                } label: {
                    Text("Press Me")
                }
            }
        }
    }

    import AVFoundation

    class SpeechSynthesizerManager: NSObject, AVSpeechSynthesizerDelegate {
        var synthesizer = AVSpeechSynthesizer()

        override init() {
            super.init()
            synthesizer.delegate = self
        }

        func speak(say: String) {
            DispatchQueue.global(qos: .userInitiated).async {
                do {
                    try AVAudioSession.sharedInstance().setCategory(.playback, options: [.duckOthers])
                    try AVAudioSession.sharedInstance().setActive(true)

                    let utterance = AVSpeechUtterance(string: say)
                    utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
                    utterance.rate = 0.5

                    DispatchQueue.main.async {
                        self.synthesizer.speak(utterance)
                    }
                } catch {
                    print("Audio session error: \(error.localizedDescription)")
                }
            }
        }

        func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
            do {
                try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
            } catch {
                print("Failed to deactivate audio session: \(error.localizedDescription)")
            }
        }
    }

I was running on the main thread then updated the code to run on a background thread, but both caused the same issue and prints the same error to the console.

1

There are 1 best solutions below

0
Naiyer Aghaz On

I hope this will help you, try once.

do {
            try audioSession.setCategory(.playback)
            try audioSession.setActive(false)
            print("Audio session reset and deactivated successfully")
        } catch let error {
            print("Error resetting and deactivating audio session: \(error.localizedDescription)")
        }