LoginSignup
38
40

More than 5 years have passed since last update.

[Swift] iOS でテキストの読み上げをする

Posted at

AVSpeechSynthesizer を使って音声読み上げをする

iOS アプリで音声読み上げをやりたくなったので調べてみたメモです。

AVSpeechSynthesizer というクラスを使うと簡単に読み上げができました。

  1. AVSpeechSynthesizer を生成
  2. 読み上げるテキストを引数に AVSpeechUtterance を生成
  3. voice プロパティに言語指定した Voice を指定(ここでは ja-JP)
  4. 読み上げ

という順で処理を行います。コードにすると下記の通り。

let talker = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")
talker.speakUtterance(utterance)        

テキストをひとつずつ読み上げていく

ただ上記の処理では複数のテキストを読み上げる場合などに同時に読み上げてしまいます。そこでシングルトンを作って読み上げ処理を1つずつ行うようにしてみました。

やっていることは簡単で、

  1. 1. 読み上げたいテキストをリストに追加
  2. リストにあるテキストを音声読み上げ(再生は同時にひとつだけ)
  3. 読み上げ終了、2に戻る

をやっています。

import UIKit
import AVFoundation

final class TtsManager: NSObject, AVSpeechSynthesizerDelegate {

    static let sharedInstance = TtsManager()

    var texts = [String]()
    let talker = AVSpeechSynthesizer()

    private override init() {
        super.init()
        talker.delegate = self
    }

    func append(text: String) {
        texts.append(text)
        if texts.count == 1 {
            play(texts[0])
        }
    }

    // MARK: AVSpeechSynthesizerDelegate
    func speechSynthesizer(synthesizer: AVSpeechSynthesizer, didFinishSpeechUtterance utterance: AVSpeechUtterance) {
        if texts.count > 0 {
            texts.removeFirst()
            if texts.count > 0 {
                play(texts[0])
            }
        } else {
            // speech finished
        }
    }

    func clear() {
        texts.removeAll()
        if talker.speaking {
            talker.stopSpeakingAtBoundary(.Immediate)
        }
    }

    private func play(text: String) {
        let utterance = AVSpeechUtterance(string: text)
        utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")
        talker.speakUtterance(utterance)
    }

}

38
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
40