The Util Designer
iOS Text to Speech 閱讀文字
xcode 13.4.1, swift 5.5, iOS 15.4
2022-09-24
Text to Speech功能是用來把文字讀出來,這功能可以省去很多的音頻的制作,也可以讓App的大小減少很多。
1. 下面演示最簡單的方式讀出英文句子,先創建一個AVSpeechSynthesizer,然後創建AVSpeechSynthesizer來初始化要讀的句子和聲音,下面的聲音類型為美語en-US:
import SwiftUI
import AVFoundation

struct ContentView: View {
    let speechSynthesizer = AVSpeechSynthesizer()
    
    var body: some View {
        Button {
            speak("Hello! How are you!")
        } label: {
            Text("Speech")
        }

    }
    
    func speak(_ inputMessage : String) {
        let utterance = AVSpeechUtterance(string: inputMessage)
        utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
        speechSynthesizer.speak(utterance)
    }
}
2. iOS提供的聲音類型其實有很多,以下就來看看你的iOS device提供了多少個英語類型聲音:
import SwiftUI
import AVFoundation


struct ContentView: View {
    
    let voices : [AVSpeechSynthesisVoice] = {
        return AVSpeechSynthesisVoice.speechVoices().filter { voice in
            return voice.language.starts(with: "en")
        }
    }()
    
    var body: some View {
        VStack {
            ForEach(0..<voices.count, id:\.self) { index in
                VStack {
                    Text("\(voices[index].language)").font(.title2).foregroundColor(.blue)
                    Text("\(voices[index].identifier)").foregroundColor(.black)
                }
            }
        }

    }
}
以上列了英文可以用的聲音類型,藍色代表語言(如:en-AU 澳洲英語),黑色代表聲音的identifier。
3. 以下把可以讀的英語聲音類型做成可以選擇,再以選擇的聲音類型讀出Hello How are you:
import SwiftUI
import AVFoundation

struct ContentView: View {
    let speechSynthesizer = AVSpeechSynthesizer()
    @State private var selectedVoiceIndex = 0
    
    let voices : [AVSpeechSynthesisVoice] = {
        return AVSpeechSynthesisVoice.speechVoices().filter { voice in
            return voice.language.starts(with: "en")
        }
    }()
    
    var body: some View {
        VStack {
            Picker(selection: $selectedVoiceIndex) {
                ForEach(0..<voices.count, id:\.self) { index in
                    Text("\(voices[index].name)(\(voices[index].language))").tag(index)
                }
            } label: {
                Text("Voice")
            }
            Button {
                speak("Hello! How are you!")
            } label: {
                Text("Speech")
            }
        }

    }
    
    func speak(_ inputMessage : String) {
        let utterance = AVSpeechUtterance(string: inputMessage)
        utterance.voice = self.voices[self.selectedVoiceIndex]
        speechSynthesizer.speak(utterance)
    }
}
4. 可以讀中文:
import SwiftUI
import AVFoundation

struct ContentView : View {
    let speechSynthesizer = AVSpeechSynthesizer()
    @State private var selectedVoiceIndex = 0
    
    let voices : [AVSpeechSynthesisVoice] = {
        return AVSpeechSynthesisVoice.speechVoices().filter { voice in
            return voice.language.starts(with: "zh")
        }
    }()
    
    var body: some View {
        VStack {
            Picker(selection: $selectedVoiceIndex) {
                ForEach(0..<voices.count, id:\.self) { index in
                    Text("\(voices[index].name)(\(voices[index].language))").tag(index)
                }
            } label: {
                Text("Voice")
            }
            Button {
                speak("你好嗎")
            } label: {
                Text("Speech")
            }
        }

    }
    
    func speak(_ inputMessage : String) {
        let utterance = AVSpeechUtterance(string: inputMessage)
        utterance.voice = self.voices[self.selectedVoiceIndex]
        speechSynthesizer.speak(utterance)
    }
}