How to fix AV Speech Synthesizer error "Unable to list voice folder" even after moving synthesizer outside class?
Asked Answered
K

4

6

I'm trying to use AV Speech Synthesizer on an ARKit app (I've never used it before), but I keep getting the same error message "Unable to list voice folder."

I saw the same question being asked before, and all the answers mentioned ios 16 being the difference, so they suggested moving the synthesizer declaration line outside the function or moving it directly under where I import AVFoundation.

let synthesizer = AVSpeechSynthesizer()

However, I still get the same error message no matter where I put this line. I'm pretty new to Swift and app development, so I suspect there's another problem, but the relevant code roughly looks like this:

import AVFoundation
let synthesizer = AVSpeechSynthesizer()

//within the view controller class:
func testSpeak() {
    
    let utterance = AVSpeechUtterance(string: "screen has been tapped")
    utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
    synthesizer.speak(utterance)

}

Are there any alternatives to using AVSpeechSynthesizer if I can't get it to work? I just need something that can read a few strings aloud to users.

Kennakennan answered 27/7, 2023 at 3:10 Comment(0)
C
5

Change let to var, then its works fine.

Declare synthesizer outside of the function and it should be var, not let

var synthesizer = AVSpeechSynthesizer()
Coaction answered 6/1 at 16:9 Comment(0)
A
4

Using SwiftUI

When I combined both of the answers above, so from @Vinoth Vino and @devdchaudhary I made it work.

  1. take AVSpeechSynthesizer outside of the local scope and made it @State variable
  2. handled audio session

here is the full code, btw I am working with Czech language, therefore you will see cs text in the code

import SwiftUI
import AVFoundation
struct ContentView: View {
    
    @State private var speechSynthesizer: AVSpeechSynthesizer? // 1) taking outside of the local scope of function `speak()`
    
    var body: some View {
        Button {
            speak()
        } label: {
            Text("Dotkni se mě.")
        }
        .buttonStyle(.borderedProminent)
        
        
    }
    
    func speak() {
        
        let audioSession = AVAudioSession() // 2) handle audio session first, before trying to read the text
        do {
            try audioSession.setCategory(.playback, mode: .default, options: .duckOthers)
            try audioSession.setActive(false)
        } catch let error {
            print("❓", error.localizedDescription)
        }
        
        speechSynthesizer = AVSpeechSynthesizer()
        
        let speechUtterance = AVSpeechUtterance(string: "Vepřík")
        speechUtterance.voice = AVSpeechSynthesisVoice(language: "cs")
        
        speechSynthesizer?.speak(speechUtterance)
    }
}
#Preview {
    ContentView()
}
Arnold answered 8/2 at 16:11 Comment(0)
B
3

In SwiftUI, it worked when I added the synthesizer property with the @State property wrapper. It's not working when I create the property inside the speak method.

struct SpeechView: View {
    @State private var speechSynthesizer: AVSpeechSynthesizer?
    
    var body: some View {
        Button("Speak") {
            speak(text: "Hello World")
        }
    }
    
    func speak(text: String) {
        let utterance = AVSpeechUtterance(string: text)
        utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
        utterance.rate = 0.1

        speechSynthesizer = AVSpeechSynthesizer()
        speechSynthesizer?.speak(utterance)
    }
}
Balk answered 27/1 at 18:19 Comment(1)
Could you explain this? Why I need to add the synthesizer to view?Hoyos
C
1

It means that you haven't changed a previous audioSession's category back to playback.

Are you also recording somewhere else?

If so set your audioSession back to playback when you finish recording like this.

do {
    try audioSession?.setCategory(.playback, mode: .default, options: .duckOthers)
    try audioSession?.setActive(false)
} catch {
    // handle errors
}
Chaulmoogra answered 27/7, 2023 at 3:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.