Swift

AVSpeechSynthesizerで複数言語を話す

結論

AVSpeechSynthesizerDelegateのdidFinishメソッドを使って言語を切り替え、読み上げる関数を使う

環境

  • macOS Sierra 10.12.6
  • Swift4
  • Xcode 9.2

読み上げ

AVSpeechSynthesizerを使うと、渡した文字列を読み上げてくれます。
使い方は次のように書きます。

import AVFoundation

let syntherizer = AVSpeechSynthesizer()
let voice = AVSpeechSynthesisVoice(language: "ja-JP")
let utterance = AVSpeechUtterance(string: "おはよう")
utterance.voice = voice
syntherizer.speak(utterance)

使える言語はiPhoneにインストールされているもので、日本語は"ja-JP",英語は"en-US","en-AU"など、中国語は"zh-CN","zh-HK"など、国のなまりもと反映できるらしいです。
なお、指定した言葉に対して言語が合ってなければ、何も反応しません。

複数言語の読み上げ

例えば最初の文は英語で、次の文は日本語を読み上げる、という風にしたい場合があります。

例)Hello World こんにちは、世界

この時、最初に"Hello world"という文字列を渡して、英語を指定し、次に"こんにちは、世界"という文字列を渡して、日本語を指定すれば大丈夫だと思ってたんですが、読み終えたところで読み上げる関数をよびださないと最初の読み上げと重なって次の文が読み上げられませんでした。

結果的にAVSpeechSynthesizerDelegateのdidFinishメソッドを使って言語を切り替えることで対応できました
これは、didFinishつまり、読み上げが終わったときに呼ばれる関数です。この関数の中で次の読み上げの設定を行います。
また、そのままだと読み終える度に関数が呼ばれるので、2回め以降は止めるようにします。
ここでは、languageが日本語の場合は、終了するようにしています。

//Deleagte先を設定すること
extension ViewController:AVSpeechSynthesizerDelegate{

    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        //連続で同じスピーチしない
        if utterance.voice!.language == language.ja.rawValue{
            return
        }

    let syntherizer = AVSpeechSynthesizer()
    let voice = AVSpeechSynthesisVoice(language: "ja-JP")
    let utterance = AVSpeechUtterance(string: "こんにちは、世界")
    utterance.voice = voice
    syntherizer.speak(utterance)
    }
}

最後に

スマートスピーカーの普及のため、音声UIが今後増えていき、これから音声APIを使う機会が増えるかもしれません

参考