[Swift] AVSpeechSynthesizerで読み上げ機能を使ってみる

2014.11.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

AVSpeechSynthesizerはiOS7で追加された音声読み上げライブラリです。 今更な感じもしますが、個人的に気になっていたので試してみます。

テキストに入力した文字をボタンを押したタイミングで読み上げる、シンプルすぎるサンプルを作ってみたいと思います。

実装

画面構成

プロジェクトはSingleViewApplicationで作成します。 そして、storyboardは下図のように配置しました。

Main_storyboard


ViewController.swift に UITextViewのアウトレットとボタンのアクションを設定します。

ソースコード

ViewController.swift

import UIKit
import AVFoundation

class ViewController: UIViewController
{
    /** 話す内容を入力するテキストフィールド */
    @IBOutlet weak var speechText: UITextField!
    /** SpeechSynthesizerクラス */
    var talker = AVSpeechSynthesizer()
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
    }
    
    /** ボタンが押された時の処理 */
    @IBAction func didTapButton(sender: UIButton)
    {
        guard let text = speechText.text else {
            return
        }
        // 話す内容をセット
        let utterance = AVSpeechUtterance(string: text)
        // 言語を日本に設定
        utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")
        // 実行
        self.talker.speakUtterance(utterance)
    }
}

最初にAVSpeechSynthesizerクラスを用意します。var talker = AVSpeechSynthesizer()

ボタンが押されたイベントでテキストの内容をセットします。 let utterance = AVSpeechUtterance(string: text)

そして、言語を設定して utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")

実行します。 self.talker.speakUtterance(utterance)

特にオプションを設定しなければ数行で読み上げ機能を実装することが出来ます。 上記では言語を日本語に設定してますが、設定しなければ端末の言語設定が適用されるみたいです。

オプション

下記のコードを28行目の前に追加すると話す速度を変更する事が出来ます。

// 話す速度を設定(0.0〜1.0)
utterance.rate = AVSpeechUtteranceMinimumSpeechRate

また、下記のコードで声の種類(雰囲気?)が変わります。

// 声の高さを設定(0.5〜2.0)
utterance.pitchMultiplier = 1.8

他にも文章間の読み上げ間隔やボリュームなど設定出来る様です。(AVSpeechUtterance Class Reference

Delegate

Delegateを設定する事により、読み上げの開始/終了のタイミングや読み上げ中の言葉を取得する事が出来ます。

AVSpeechSynthesizerDelegateを追加します。

class ViewController: UIViewController, AVSpeechSynthesizerDelegate

viewDidLoad内に下記を追加します。

self.talker.delegate = self

上記準備ができたら、必要に応じてDelegateメソッドを用意します。今回は下記を紹介します。

    • 読み上げ開始
func speechSynthesizer(synthesizer: AVSpeechSynthesizer!, didStartSpeechUtterance utterance: AVSpeechUtterance!)
{
   println("***開始***")
}
  • 読み上げ終了
func speechSynthesizer(synthesizer: AVSpeechSynthesizer!, didFinishSpeechUtterance utterance: AVSpeechUtterance!)
{
   println("***終了***")
}
  • 読み上げ中の言葉を取得
func speechSynthesizer(synthesizer: AVSpeechSynthesizer!, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance!) 
{
    let word = (utterance.speechString as NSString).substringWithRange(characterRange)
    println("Speech: \(word)")
}

最後に

今回、音声ライブラリをはじめて使ってみましたが、思った以上に簡単に出来る印象を受けました。話す速度や声の高さなどを変えることによってだいぶ印象が違う声になるので面白かったです。尚、シミュレーターでは動作しなかったので実機で動かす必要があると思います。

雑談対話API|ドコモのようなサービスと組み合わせて使ってみるとSiriのような感じのアプリが作れそうです。

参考