【Objective-C】AWSのAmazonPollyでText to Speachを実装する方法【iOS11】
AWSにあるAmazoPollyを使い文字を読み上げる機能を作成する方法をご紹介します。
1. PoolIDの作成
AWSの管理画面からAmazonPollyのPoolIDを作成します
ap-sortheast-1:xxxxxxxxx-xxxxxxxx-xxxxxxxx
このような値がPoolIDになります。
2. ロールの設定
次にAWSの管理画面より、作成したPoolIDにロールを設定してください。
ロールの設定をしないと、音声ファイル取得ようのurlを叩いても
CognitoIdentityCredentials is not authorized to perform: polly:SynthesizeSpeech
というエラーになり音声ファイルをダウンロードすることができません。
3. CocoapodによるAWSPollyのインストール
pod 'AWSPolly'
Podfileに追記してください。
pod install
ターミナルでpodを更新します。
4. プログラムの実装
#import <AWSPolly/AWSPolly.h>
#import <AVFoundation/AVFoundation.h>
AWSPollyと再生用PlayerのためのAVFoundationをimportします。
@interface ViewController () {
// 音声再生用のプレイヤーを用意
AVAudioPlayer *audioPlayer;
}
音声再生用のプレイヤーを用意します。
- (void)textToSpeach:(NSString *)text {
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionAPSoutheast1
identityPoolId:@"ap-sortheast-1:xxxxxxxxx-xxxxxxxx-xxxxxxxx"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionAPSoutheast1
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
AWSPollySynthesizeSpeechURLBuilderRequest *input = [[AWSPollySynthesizeSpeechURLBuilderRequest alloc] init];
input.text = text;
input.outputFormat = AWSPollyOutputFormatMp3;
input.voiceId = AWSPollyVoiceIdMizuki;
AWSTask *builder = [[AWSPollySynthesizeSpeechURLBuilder defaultPollySynthesizeSpeechURLBuilder] getPreSignedURL:input];
[builder continueWithBlock:^id(AWSTask *awsTask){
// 非同期処理にしないと音声ファイルのダウンロードにより画面が止まる
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 音声ファイル取得用urlの取得
NSURL *url = awsTask.result;
// 音声ファイルの取得
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];
if (error) {
NSLog(@"error:%@",error);
}
else {
NSLog(@"play")
[audioPlayer play];
}
});
return nil;
}];
}
PoolIDとRegionを設定して任意の文字を送るだけです。
注意点として、AWSより取得したURLからさらに音声ファイルを取得しているのですが、音声ファイルを取得するタイミングでサブスレッドにしています。
この処理を入れておかないと、音声ファイルのダウンロードが完了するまでアプリが固まります。
必ずサブスレッド化しておきましょう。
4. まとめ
全ての実装コードは以下になります。
#import "ViewController.h"
#import <AWSPolly/AWSPolly.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController () {
AVAudioPlayer *audioPlayer;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self textToSpeach:@"こんにちわ"];
}
- (void)textToSpeach:(NSString *)text {
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionAPSoutheast1
identityPoolId:@"ap-sortheast-1:xxxxxxxxx-xxxxxxxx-xxxxxxxx"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionAPSoutheast1
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
AWSPollySynthesizeSpeechURLBuilderRequest *input = [[AWSPollySynthesizeSpeechURLBuilderRequest alloc] init];
input.text = text;
input.outputFormat = AWSPollyOutputFormatMp3;
input.voiceId = AWSPollyVoiceIdMizuki;
AWSTask *builder = [[AWSPollySynthesizeSpeechURLBuilder defaultPollySynthesizeSpeechURLBuilder] getPreSignedURL:input];
[builder continueWithBlock:^id(AWSTask *awsTask){
// 非同期処理にしないと音声ファイルのダウンロードにより画面が止まる
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 音声ファイル取得用urlの取得
NSURL *url = awsTask.result;
// 音声ファイルの取得
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];
if (error) {
NSLog(@"error:%@",error);
}
else {
NSLog(@"play")
[audioPlayer play];
}
});
return nil;
}];
}
@end