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)
}
}