CodeIQ MAGAZINECodeIQ MAGAZINE

iOS 7で追加された音声読み上げ機能(AVSpeech Synthesizer)でiPhoneにお喋りさせる #ios7yahoo

2013.12.13 Category:勉強会・イベント Tag: , ,

  • 5
  • このエントリーをはてなブックマークに追加

iOS 7では、「AVSpeech Synthesizer」という音声読み上げ機能が新たに搭載されました。

その機能を使ってiPhoneにお喋りさせるノウハウについて、ヤフーのiOS Developer千葉俊輝さんに寄稿をいただきました。
by 馬場美由紀 (CodeIQ中の人)

iOS 7の新機能、音声読み上げ機能について

今回は、iOS 7で新たに追加された AVSpeech Synthesizer について説明したいと思います。

AVSpeech Synthesizer とは

iOSデバイス上のテキストから合成音声を生成し、発話の進行を制御、状態の監視をすることでiPhoneがお喋りできるようになります。

AVSpeech Synthesizer のメソッドとプロパティ

/* AVSpeech Synthesizerのメソッド */
// 再生、キューに追加
- (void)speakUtterance:(AVSpeechUtterance *)utterance;
// 指定された定数で再生を停止
- (BOOL)stopSpeakingAtBoundary:(AVSpeechBoundary)boundary;
// 指定された定数で再生を一時停止
- (BOOL)pauseSpeakingAtBoundary:(AVSpeechBoundary)boundary;
// 再生を再開
- (BOOL)continueSpeaking;

/* AVSpeech Synthesizerのプロパティ */
// delegate
@property(nonatomic, assign) id<AVSpeechSynthesizerDelegate> delegate;
// 再生されているか
@property(nonatomic, readonly, getter=isSpeaking) BOOL speaking;
// 停止しているか
@property(nonatomic, readonly, getter=isPaused) BOOL paused;

/* AVSpeech Synthesizerの定数 */
typedef enum : NSInteger {
   AVSpeechBoundaryImmediate,//直ちに一時停止、停止
   AVSpeechBoundaryWord //現在再生している単語の後に一時停止、停止
} AVSpeechBoundary;

発話させるために、まずは再生したいテキストを含んだ AVSpeechUtterance のインスタンスを作成する必要があります。

AVSpeechUtterance とは

AVSpeechUtterance のプロパティには読み上げ時の音声指定、スピード、ボリューム、声のピッチ、再生までの待ち時間、再生終了後の待ち時間などが設定できます。

  • 音声は AVSpeechSynthesisVoice のインスタンスを指定、使用できる音声取得方法は下記メソッド一覧に記述。
  • スピードは0から1で指定。
  • ボリュームは0から1で指定。
  • 声のピッチは0.5から2で指定。

AVSpeechUtterance , AVSpeechSynthesisVoice のメソッドとプロパティ

/* AVSpeechUtteranceのメソッド */
// 再生するテキスト設定
+ (AVSpeechUtterance *)speechUtteranceWithString:(NSString *)string;
// オブジェクトの初期化と再生するテキスト設定
- (AVSpeechUtterance *)initWithString:(NSString *)string;

/* AVSpeechUtteranceのプロパティ*/
@property(nonatomic, retain) AVSpeechSynthesisVoice *voice;
@property(nonatomic, readonly) NSString *speechString; //再生テキスト
@property(nonatomic) float rate;             // はやさ
@property(nonatomic) float pitchMultiplier;  // 声のピッチ [0.5 - 2] Default = 1
@property(nonatomic) float volume;           // 大きさ [0-1] Default = 1
@property(nonatomic) NSTimeInterval preUtteranceDelay;    // 開始までの待機時間 Default is 0.0
@property(nonatomic) NSTimeInterval postUtteranceDelay;   // 終了後の待機時間 Default is 0.0

/* AVSpeechSynthesisVoiceのメソッド */
// 再生できる音声一覧
+ (NSArray *)speechVoices;
// 設定されている言語コード
+ (NSString *)currentLanguageCode;
// 音声の設定
+ (AVSpeechSynthesisVoice *)voiceWithLanguage:(NSString *)language;

/* AVSpeechSynthesisVoiceのプロパティ*/
// 設定音声
@property(nonatomic, readonly) NSString *language;

音声の読み上げ

AVSpeech SynthesizerspeakUtterance メソッドに AVSpeechUtterance のインスタンス与えることで発話が開始されます。
AVSpeech SynthesizerAVSpeechUtterance のインスタンスをキューで管理し、キューに追加した順番で再生されます。
AVSpeech Synthesizer が発話されていない場合は直ちに再生されます(待機時間を設定してる場合は待機時間後に発話が開始)。
すでに発話されている場合は AVSpeechUtterance のインスタンスをキューに追加します。

制御

発話開始後、音声を一時停止や停止する制御ができます。
Delegateを設定すると再生状態を監視できます。

AVSpeechSynthesizerDelegate のメソッド

/* AVSpeechSynthesizerDelegateのメソッド */
// 再生が始まった時
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance;
// 再生が終わった時
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance;
// 再生が一時停止した時
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance;
// 再生が再開されたとき
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance;
// 読み上げが停止した時
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance;
// 再生中のテキスト範囲
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance;

iPhoneにお喋りしてもらう


1.AVFoundation.frameworkをimport
ProjectのLinked Frameworks and Libraries にAVFoundation.frameworkを追加します。

次に

  • 音声読み上げをしたいクラスで、#import <AVFoundation/AVFoundation.h>このコードを追加
  • AVSpeechSynthesizerDelegate プロトコルの採用
  • AVSpeechSynthesizer のプロパティを作成

宣言部

//
//  ASSViewController.h
//  AVSpeechSynthesizer
//
//  Created by Toshiki Chiba on 2013/12/08.
//  Copyright (c) 2013年 Toshiki Chiba. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ASSViewController : UIViewController <AVSpeechSynthesizerDelegate> // プロトコルの採用
@property (nonatomic,strong) AVSpeechSynthesizer *speechSynthesizer; // プロパティ作成
@end

2.AVSpeechSynthesizer のインスタンスを作成し、デリゲートを設定

実装部

//
//  ASSViewController.m
//  AVSpeechSynthesizer
//
//  Created by Toshiki Chiba on 2013/12/08.
//  Copyright (c) 2013年 Toshiki Chiba. All rights reserved.
//

#import "ASSViewController.h"

@interface ASSViewController ()

@end

@implementation ASSViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
    // initialize AVSpeechSynthesizer インスタンスを作成し、デリゲートを設定する
    _speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
    _speechSynthesizer.delegate = self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

3.再生ボタン、一時停止ボタン、終了ボタンを作る

  • Storyboardを選択し、UIButtonをDrag&Dropで3つ作ります。
  • ボタンのタイトルもそれぞれ設定します。

  • Buttonのアクションを下記のように定義します
    • 喋るボタンを押すとspeak
    • 止めるボタンを押すとpause
    • 終わるボタンを押すとfinish

4.再生したいタイミングで、 AVSpeechSynthesizerspeakUtterance:AVSpeechUtterance のインスタンスを与えると再生が開始

- (IBAction)speak:(id)sender {
    // AVSpeechUtteranceに再生テキストを設定し、インスタンス作成
    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@"Yahoo! JAPAN"];
    // 英語に設定し、AVSpeechSynthesisVoiceのインスタンス作成
    AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"];
    // AVSpeechSynthesisVoiceをAVSpeechUtterance.voiceに指定。
    utterance.voice =  voice;
    // デフォルトは早すぎるので、聞き取りやすいように低い数値を入れる
    utterance.rate = 0.2;
    // ピッチを低くすることで男性ぽい声にする
    utterance.pitchMultiplier = 0.5;
    // 少しだけ発話前にためを作りたいので、Delayに値を設定
  utterance.preUtteranceDelay = 0.2f;
    // 再生開始
    [self.speechSynthesizer speakUtterance:utterance];
}

再生はここまでの処理でできます。
もう一手間加えると、もっと便利に使えます。

5.再生の制御

- (IBAction)pause:(id)sender {
    // 停止していたら再開、停止していなかったら停止
    self.speechSynthesizer.paused?
    [self.speechSynthesizer continueSpeaking]:
    [self.speechSynthesizer pauseSpeakingAtBoundary:AVSpeechBoundaryImmediate];
}

- (IBAction)finish:(id)sender {
    // 直ちに停止
    [self.speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
}

ここまでの処理で再生、停止、終了の制御ができるようになります。
喋るボタンを押すとネイティブな発音で 「Yahoo! JAPAN」 とiPhoneがお話してくれます。

おまけ
6.再生状況に応じて処理を付加したい場合

#pragma mark - Private Methods
-(void)p_setUpPauseButton {
    // 再生状況でボタンのタイトルを変える
    NSString *buttonTitle = self.speechSynthesizer.paused? @"始める":@"止める";
    [self.pauseButton setTitle:buttonTitle forState:UIControlStateNormal];
}

-(void)p_initilaizeButtonAndText {
    // ボタンのタイトルを初期化する
    [self.pauseButton setTitle:@"止める" forState:UIControlStateNormal];
}

#pragma mark - AVSpeechSynthesizerDelegate

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance{
    NSLog(@"読み上げを開始しました");
}

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{
    [self p_initilaizeButtonAndText];
    NSLog(@"読み上げを終了しました");
}

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance{
    [self p_setUpPauseButton];
    NSLog(@"読み上げを一時停止しました");
}

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance{
    [self p_setUpPauseButton];
    NSLog(@"読み上げを再開しました");
}

- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance{
    [self p_initilaizeButtonAndText];
    NSLog(@"読み上げを停止しました");
}

このように再生状況によってボタンの文字を変えることができます。

音声読み上げ機能の注意事項

  • iPhoneのマナーモードが解除されないと再生されません。
  • 日本語の再生の場合、意図しない位置で区切られてしまい、精度があまりよくありません。

最後に

iPhoneではSiriのように発話する機能がありませんでした。iOS 7からの新機能で音声合成機能が使えるようになり、これからのアプリの可能性を広げていく機能だと私は思います。

Yahoo! JAPAN Tech Blogでは、iOS 7勉強会に関する様々な資料を公開しています。ぜひご覧ください。

寄稿者プロフィール 千葉俊輝
ヤフー株式会社 iOS Developer。
日本最大のポータルサイト「Yahoo! JAPAN」のiOSアプリ開発を行う。

iOS6から導入されたAuto Layout問題に挑戦してみない?

ヤフー山口恭兵さんからのiOSの問題が出題中です。iOSならお任せ!というエンジニアの皆さん、ぜひ挑戦してみてくださいね。

Autolayoutを設定して画面のサイズ・向きの変化に対応できるレイアウトを作成する問題です。

  • 締切4月14日(月)AM10:00まで
  • 問題挑戦はこちらから

CodeIQコード銀行にあなたのコードを預けてみませんか?

  • CodeIQコード銀行ではあなたのコードを財産と考えます。
  • お預かりいただいたコードは、CodeIQコード銀行がしっかり評価し、フィードバックいたします。
  • 当コード銀行にお預けいただいたコードは、企業がみてスカウトをかける可能性があります。
  • 転職したい方や将来転職することを考えている方で、今の自分のスキルレベルを知りたい方はぜひ挑戦してみてください。
  • 企業からスカウトがきたら困る人は挑戦しないでください。

興味を持った方はこちらからチャレンジを!

  • 5
  • このエントリーをはてなブックマークに追加

■関連記事

アドテクは新しい技術の宝庫!?──ヨッピーさんがインターネット広告の未来、面白さを探る... 1994年のバナー広告から始まったアドテク発展の歴史 今回インターネット広告とアドテクをテーマを選んだ理由は、「アドテクに携わっているエンジニアがすごく少ない」」っていう話を聞いたからなんですね。でもインターネットにおける広告の役割はビジネスにとってすごく大事なことだし、新しい技術もあれこれ入っ...
ヤフー・クックパッド・ピクシブの現場エンジニアが語った、HTTPS化の裏側と対応のコツとは?... 3名の登壇者と川田氏によるパネルディスカッション 2014年にGoogleがHTTPS化対応サイトを検索結果で優遇するロジックを実装したが、日本ではなかなかHTTPS化が進んでこなかった。 セキュリティリスクの低減、開発・運用の効率化、安全性や信頼性のアピールなどHTTPS化には多くのメリットが...
ソフトバンク・ヤフー・HDE人事責任者が明かした「最先端の採用手法」とは?... 事業とともに変化する採用への挑戦―ソフトバンク 第一部のセッションを務めたのはソフトバンクの小山亮氏。セッションタイトルは「新たな道を切り開け!『事業とともに変化する採用への挑戦』」。 小山氏は5年前にソフトバンクに転職。3年前より新卒採用をメインに担当している。 ▲ソフトバンク株式会社 人事...
ヤフーがAndroidアプリに関する技術や開発事例を共有する「CAMPFIRE Android」を開... Yahoo!知恵袋をRxJavaでフルリニューアル ヤフーのAndroidにおける技術情報を共有するMeetup「CAMPFIRE Android #1」が、4月19日にヤフーのコワーキングスペース「LODGE」で開催された。 「Yahoo! Japanでの取り組みや開発のコツを知ることができる...
聖夜のアイデアソン -Pepper Loves LINE BOT-... LINE BOT AWARDSとは 「LINE BOT AWARDS」とは、LINEのchatbot開発促進及びユーザーへの普及を目的に開催するAwards。個人・法人問わず誰でも参加可能なAwardsで、応募〆切は2月22日です。 ▲▲LINE株式会社 ビジネスプラットフォーム事業室 戦略企画...
最高賞金1000万円!LINE・砂金信一郎氏に聞いた「LINE BOT AWARDS」の全容と狙い─... LINE・砂金信一郎氏がプロデュースするビッグイベント これまでサービスを提供する企業がユーザーと密接な関係を結ぶためには、スマホアプリを提供してユーザーに使ってもらうというのが一つの方法だった。 しかし、アプリ開発には手間がかかるだけでなく、一度はダウンロードしてみたユーザーも、毎日それを使う...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

CodeIQ(コードアイキュー)とは、自分の実力を知りたいITエンジニア向けの、実務スキル評価サービスです。

CodeIQご利用にあたって
関連サイト
codeiq

リクルートグループサイトへ