【iOS】Microsoft Translator APIを使用した翻訳からのTTSをAVSpeechSynthesizerで作ってみた【Objective-C】

2020年8月27日

前回、Microsoft Translator APIを使用したテキスト翻訳を作ってみましたが今回は翻訳したテキストを読み上げてくれる機能を実装し、TTS(Text To Speak)が実装できるようになりたいと思います。

テキストを読み上げくれるライブラリやAPIは数多くありますが、今回はiOS標準のAVSpeechSynthesizerを使用して実装します。

Microsoft Translator APIを使用したテキスト翻訳の実装については前回の記事をご覧ください。

1.AVSpeechSynthesizerのサンプルを動かしてみよう

ますはフレームワークをインポートします。

@import AVFoundation;

次にサンプルコードを動かしてみましょう。

AVSpeechSynthesizer* speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@"こんちにわ"];
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"ja-JP"];
[speechSynthesizer speakUtterance:utterance];

以上です。とっても簡単ですね!

もちろんサンプルでは「こんにちわ」と日本語で読み上げてくれますが、「Hellow」を英語で読み上げも可能です。また「Hellow」を日本語で読み上げることも可能です。発音がかなり違うので設定には注意しましょう。

発音の設定はこちらで設定しています。

utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"ja-JP"];

対応している発音は以下になります。

ar-SAArabic (Saudi Arabia)
en-ZAEnglish (South Africa)
th-THThai (Thailand)
nl-BEDutch (Belgium)
en-AUEnglish (Australia)
de-DEGerman (Germany)
en-USEnglish (United States)
pt-BRPortuguese (Brazil)
pl-PLPolish (Poland)
en-IEEnglish (Ireland)
el-GRGreek (Greece)
id-IDIndonesian (Indonesia)
sv-SESwedish (Sweden)
tr-TRTurkish (Turkey)
pt-PTPortuguese (Portugal)
ja-JPJapanese (Japan)
ko-KRKorean (Korea)
hu-HUHungarian (Hungary)
cs-CZCzech (Czech Republic)
da-DKDanish (Denmark)
es-MXSpanish (Mexico)
fr-CAFrench (Canada)
nl-NLDutch (Netherlands)
fi-FIFinnish (Finland)
es-ESSpanish (Spain)
it-ITItalian (Italy)
ro-RORomanian (Romania)
no-NONorwegian(Norway)
zh-HKChinese (Hong Kong)
zh-TWChinese (Taiwan)
sk-SKSlovak (Slovakia)
zh-CNChinese (China)
ru-RURussian (Russia)
en-GBEnglish (United Kingdom)
fr-FRFrench (France)
hi-INHindi (India)

2.AVSpeechSynthesizerのプロパティ

AVSpeechSynthesizerはテキストを読み上げるスピードや読み上げる声の高さの設定も可能です。また読み上げるまでの待ち時間や読み上げたあとの待ち時間なども設定可能です。
とても便利ですね!

// 読み上げるスピード
 @property(nonatomic) float rate;
// 読み上げる声の高さ
 @property(nonatomic) float pitchMultiplier;
// 読み上げる声のボリューム
 @property(nonatomic) float volume;
// 読み上げ前の待ち時間
 @property(nonatomic) NSTimeInterval preUtteranceDelay;
// 読み上げ後の待ち時間
 @property(nonatomic) NSTimeInterval postUtteranceDelay;

3.AVSpeechSynthesizerのデリゲート

AVSpeechSynthesizerはデリゲートを設定することで様々な通知を受け取れることが可能です。

// 読み上げが始まった通知
- (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;

4.まとめ

AVSpeechSynthesizerは思いのほか扱いやすく作られていました!

しかし、AVSpeechSynthesizerは同時に二つの読み上げができないという難点もあるみたいです。この場合はデリゲートをうまく駆使する必要がありそうです。

試しにAVSpeechSynthesizerを二つ用意して「読み上げが終わった通知」のデリゲート内でif文により1つめの再生が終わったら2つめを再生というプログラムを組んでみましたが成功しました。

なんにせよ、覚えておくと便利そうな機能なので試してみて損はないと思います!