Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

}

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away