適当な日本語文章を形態素解析し、英語に翻訳して音声読み上げさせる
適当な日本語文章を形態素解析し、英語に翻訳して音声読み上げさせる:
表題のままです
Elasticsearchで日本語文章をバラバラの単語に分解して、そいつを AWS Translate で翻訳。
翻訳した単語を今度は AWS Polly で読み上げさせる(音声ファイル出力)サンプルです。
環境・コードは以下に置いてます
https://github.com/satooon/elasticsearch-test
軽くリポジトリ内の説明を
ついでにdocker-compose.ymlも
検証目的のための構成です
コンテナ立てた後はcomposerインストールを実行して、 .env ファイルも作成しておいてください
.env にはご自身のAWSユーザーの access_key と secret_access_key を設定してください。
日本語の形態素解析には
プラグインは docker/elasticsearch/Dockerfile 内ですでにインストールしてますので、後は設定だけです。
今回は以下のように設定しました。
※設定されているかの確認はkibanaで行いました
PHPUnitでテストコードを書いてます
『こんにちは世界』が 『こんにちは』 と 『世界』 で別々の単語で返ってたらテストOK
で、テスト実行...
\(^o^)/トオタ
ドキュメント: Class Aws\Translate\TranslateClient | AWS SDK for PHP 3.x
↓で対象の言語に翻訳
テストを実行すると
こんにちは => Hello
世界 => World
が表示されるはず
ドキュメント: Class Aws\Polly\PollyClient | AWS SDK for PHP 3.x
↓で音声に変換
テストを実行すると
Pollyで再生した音声はキャッシュしてる
追加コストなしで再生できるのは良い
表題のままです
Elasticsearchで日本語文章をバラバラの単語に分解して、そいつを AWS Translate で翻訳。
翻訳した単語を今度は AWS Polly で読み上げさせる(音声ファイル出力)サンプルです。
環境・コードは以下に置いてます
https://github.com/satooon/elasticsearch-test
軽くリポジトリ内の説明を
elasticsearch-test ├── README.md ├── docker │ └── elasticsearch # Elasticsearchコンテナイメージ定義 │ ├── Dockerfile │ └── config ├── docker-compose.yml # dockerコンテナ定義 └── php ├── composer.json ├── composer.lock ├── composer.phar └── test # テストコードディレクトリ
検証目的のための構成です
docker-compose.yml
version: '3' services: elasticsearch: build: ./docker/elasticsearch volumes: - ./docker/elasticsearch/config:/usr/share/elasticsearch/config ports: - 9200:9200 expose: - 9300 environment: - discovery.type=single-node ulimits: nofile: soft: 65536 hard: 65536 kibana: image: docker.elastic.co/kibana/kibana:6.4.2 depends_on: - elasticsearch ports: - 5601:5601
.env にはご自身のAWSユーザーの access_key と secret_access_key を設定してください。
Elasticsearchのアナライザの設定
日本語の形態素解析にはkuromoji
を利用しますが、辞書の更新が止まっているので今回はneologd
を使用します。プラグインは docker/elasticsearch/Dockerfile 内ですでにインストールしてますので、後は設定だけです。
今回は以下のように設定しました。
curl -H 'Content-Type: application/json' -XPUT 'http://localhost:9200/neologd/?pretty' -d' { "settings": { "index":{ "analysis":{ "analyzer" : { "default" : { "tokenizer" : "kuromoji_neologd_tokenizer" } } } } } }'
動作確認
PHPUnitでテストコードを書いてますphp/test/ElasticsearchTest.php
<?php require dirname(__DIR__) . '/vendor/autoload.php'; class ElasticsearchTest extends PHPUnit\Framework\TestCase { public function test_neologdA() { $client = new \GuzzleHttp\Client([ 'base_uri' => 'http://localhost:9200' ]); $response = $client->request('GET', '/neologd/_analyze', [ 'json' => ['text' => 'こんにちは世界'], ]); self::assertEquals(200, $response->getStatusCode()); $expected = '{"tokens":[{"token":"こんにちは","start_offset":0,"end_offset":5,"type":"word","position":0},{"token":"世界","start_offset":5,"end_offset":7,"type":"word","position":1}]}'; self::assertJsonStringEqualsJsonString($expected, $response->getBody()->getContents()); } ... 以下略
で、テスト実行...
$ ./php/vendor/bin/phpunit php/test/ElasticsearchTest.php PHPUnit 7.4.0 by Sebastian Bergmann and contributors. .... 4 / 4 (100%) Time: 84 ms, Memory: 4.00MB OK (4 tests, 16 assertions)
AWS Translate の確認
ドキュメント: Class Aws\Translate\TranslateClient | AWS SDK for PHP 3.xphp/test/TranslateTest.php
<?php require dirname(__DIR__) . '/vendor/autoload.php'; class TranslateTest extends PHPUnit\Framework\TestCase { public static function setUpBeforeClass() { parent::setUpBeforeClass(); (new Dotenv\Dotenv(dirname(__DIR__)))->load(); } ... 略 ... public function test_translateTextC() { $client = new \GuzzleHttp\Client([ 'base_uri' => 'http://localhost:9200' ]); $response = $client->request('GET', '/neologd/_analyze', [ 'json' => ['text' => 'こんにちは世界'], ]); self::assertEquals(200, $response->getStatusCode()); $json = json_decode($response->getBody()->getContents()); $credentials = new Aws\Credentials\Credentials( getenv('aws_access_key'), getenv('aws_secret_access_key') ); $client = new Aws\Translate\TranslateClient([ 'region' => 'us-east-1', 'version' => 'latest', 'credentials' => $credentials, ]); foreach ($json->tokens as $token) { $result = $client->translateText([ 'SourceLanguageCode' => 'ja', 'TargetLanguageCode' => 'en', 'Text' => $token->token, ]); self::assertNotEmpty($result->get('TranslatedText')); echo sprintf("\n%s => %s", $token->token, $result->get('TranslatedText')); } } }
$result = $client->translateText([ 'SourceLanguageCode' => 'ja', 'TargetLanguageCode' => 'en', 'Text' => $token->token, ]);
こんにちは => Hello
世界 => World
が表示されるはず
AWS Polly の確認
ドキュメント: Class Aws\Polly\PollyClient | AWS SDK for PHP 3.xphp/test/PollyTest.php
<?php require dirname(__DIR__) . '/vendor/autoload.php'; class PollyTest extends PHPUnit\Framework\TestCase { public static function setUpBeforeClass() { parent::setUpBeforeClass(); (new Dotenv\Dotenv(dirname(__DIR__)))->load(); } ... 略 ... public function test_pollyB() { $client = new \GuzzleHttp\Client([ 'base_uri' => 'http://localhost:9200' ]); $response = $client->request('GET', '/neologd/_analyze', [ 'json' => ['text' => 'こんにちは世界'], ]); self::assertEquals(200, $response->getStatusCode()); $json = json_decode($response->getBody()->getContents()); $credentials = new Aws\Credentials\Credentials( getenv('aws_access_key'), getenv('aws_secret_access_key') ); $translateClient = new Aws\Translate\TranslateClient([ 'region' => 'us-east-1', 'version' => 'latest', 'credentials' => $credentials, ]); $pollyClient = new Aws\Polly\PollyClient([ 'region' => 'us-east-1', 'version' => 'latest', 'credentials' => $credentials, ]); foreach ($json->tokens as $token) { $text = $translateClient->translateText([ 'SourceLanguageCode' => 'ja', 'TargetLanguageCode' => 'en', 'Text' => $token->token, ]); self::assertNotEmpty($text->get('TranslatedText')); $speech = $pollyClient->synthesizeSpeech([ 'LanguageCode' => 'en-US', 'OutputFormat' => 'mp3', 'Text' => $text->get('TranslatedText'), 'TextType' => 'text', 'VoiceId' => 'Salli', ]); /** @var \GuzzleHttp\Psr7\Stream $stream */ $stream = $speech->get('AudioStream'); self::assertTrue($stream instanceof \GuzzleHttp\Psr7\Stream); self::assertNotFalse(file_put_contents(sprintf("%s/test_pollyB_%s.mp3", __DIR__, $text->get('TranslatedText')), $stream)); } } }
$speech = $pollyClient->synthesizeSpeech([ 'LanguageCode' => 'en-US', 'OutputFormat' => 'mp3', 'Text' => $text->get('TranslatedText'), 'TextType' => 'text', 'VoiceId' => 'Salli', ]);
VoiceId
はLanguageCode
で使用可能なものが決まっている模様テストを実行すると
php/test
配下にmp3
ファイルが出力されるので、再生して確認Pollyで再生した音声はキャッシュしてる
追加コストなしで再生できるのは良い
コメント
コメントを投稿