AVSpeechSynthesizerとロケール

11
AVSpeechSynthesizerとロケール @TachibanaKaoru 2013/11/13

description

Cookpad Potatotips #1 で発表しました。

Transcript of AVSpeechSynthesizerとロケール

Page 1: AVSpeechSynthesizerとロケール

AVSpeechSynthesizerとロケール

@TachibanaKaoru2013/11/13

Page 2: AVSpeechSynthesizerとロケール

自己紹介

• @TachibanaKaoru

• http://www.toyship.org/

• 渋谷の genesix で働く iOSエンジニア。

• 個人的にはこんなアプリを作ったりしています。

• Cookpad歴 11年 ( http://cookpad.com/kitchen/18627)

Toy Jigsaw

Page 3: AVSpeechSynthesizerとロケール

• iOS7から導入されたAPIが公開された音声読み上げ機能。

• 文字列を与えると読み上げをしてくれます。

• delegateを使うと、「今読んでいる単語」なども取り出せます。

• 詳しい使い方はこちら。

• https://github.com/toyship/StoryTeller

• http://www.toyship.org/archives/1483

AVSpeechSynthesizerとは

Page 4: AVSpeechSynthesizerとロケール

ロケールの設定

• 文章を正しく読ませるためには、AVSpeechSynthesizerに読み上げる文の言語に対応したロケール(NSLocale)を設定しないと正しく読み上げてくれません。

• AVSpeechSynthesizerが文章の言語を自動判別してくれるわけではありません。

• 今のところ、36個のロケールに対応しています。! AVSpeechSynthesizer* mySpeechSynthesizer = [[AVSpeechSynthesizer alloc] init];! mySpeechSynthesizer.delegate = self;!! NSString* targetText = @"Hello World!";! AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:targetText];! AVSpeechSynthesisVoice* englishVoice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"];! utterance.voice = englishVoice;!! [myspeechSynthesizer speakUtterance:utterance];

Page 5: AVSpeechSynthesizerとロケール

でも言語判定めんどくさいよね……。Web APIは有料だし……。

Page 6: AVSpeechSynthesizerとロケール

システムの挙動は……

• iOSの純正アプリ(メールなど)では選択した文章に応じて、ちゃんと適切に言語を判断。

• 例えばiPhoneのシステムロケールを日本語にした状態でも、英語の文章を選択すると英語の声で読んでくれます。

Page 7: AVSpeechSynthesizerとロケール

探したらありました、NSStringの言語判定

• CFStringTokenizerCopyBestStringLanguageを利用

!! CFStringRef text =

(CFStringRef)CFBridgingRetain(self.inputText.text);! CFRange range = CFRangeMake(0, CFStringGetLength(text));! NSString *language = (NSString*)CFBridgingRelease(CFStringTokenizerCopyBestStringLanguage(text, range));

Page 8: AVSpeechSynthesizerとロケール

CFStringTokenizerCopyBestStringLanguage仕様

• 指定した文字列の言語コードを返す。判別にはおよそ200から400文字が必要。

• 30言語を判別可能。(アラビア語、ブルガリア語、チェコ語、デンマーク語、ドイツ語、ギリシャ語、英語、スペイン語、フィンランド語、フランス語、ヘブライ語、クロアチア語、ハンガリー語、アイスランド語、イタリア語、日本語、韓国語、ノルウェー語、オランダ語、ポーランド語、ポルトガル語、ルーマニア語、ロシア語、スロバキア語、スウェーデン語、タイ語、トルコ語、ウクライナ語、簡体中国語、繁体中国語)

• でも実際の判別はちょっと微妙かも……。

Page 9: AVSpeechSynthesizerとロケール

AVSpeechSynthesizer Tips

• AVSpeechSynthesizerを使うときには、CFStringTokenizerCopyBestStringLanguageを使って文章の言語判定をしましょう!

Page 10: AVSpeechSynthesizerとロケール

おまけその1

• なぜ、AVSpeechSynthesizerに指定するのは言語コードではなくて、ロケールのなんでしょうか。言語だけ指定すれば読んでくれるんじゃない?という気もしますが……。

• ヒント:「12/3/2012」をen-GB(イギリス英語)とen-US(アメリカ英語)で読ませてみてください。

Page 11: AVSpeechSynthesizerとロケール

おまけその2

• AVSpeechSynthesizerに設定する「ロケール」ですが、iPhoneでは、システム言語とシステムロケールとは別々に設定できますよね。

• 例えばシステムの言語は日本語だけど、ロケールはen-GBになっていた場合はAVSpeechSynthesizerのロケールはどうなるでしょうか。

• ja-JPになります。

• システム言語とシステムロケールを言語を優先してAVSpeechSynthesizerのデフォルトロケールが決定されるようです。([NSLocale currentLocale]がAVSpeechSynthesizerのデフォルトロケールではないことに注意。)