Часть 01
Как создать «говорящее приложение» с Amazon Polly
Начиная

Часть 02 доступна здесь.
Добро пожаловать в еще одно практическое руководство по AWS. Это письменная версия следующего видео на YouTube. Я бы порекомендовал вам посмотреть видео перед чтением блога. Используйте этот блог как источник, чтобы скопировать код и попрактиковаться в создании приложения самостоятельно.
Сервисы AWS, используемые в приложении
- Амазонка Полли
- Amazon S3
- AWS IAM
- AWS Lambda
Создание бессерверного проекта / службы
Установите бессерверный фреймворк с помощью npm и создайте новый проект / сервис nodejs под названием backend.
npm install serverless -g serverless create --template aws-nodejs --path backend
Теперь замените файл serverless.yml следующим кодом, который создает лямбда-функцию с именем «Speak».
service: talking-backend
provider:
name: aws
runtime: nodejs8.10
region: us-east-1
role: arn:aws:iam::<account-id>:role/talking-app-role
functions:
speak:
handler: handler.speak
events:
- http:
path: speak
method: post
cors: true
Лямбда-функция «говорит» отправит полезные текстовые данные в AWS Polly и вернет голосовой файл из корзины S3.
Создание сегмента S3
Нам нужна корзина S3 для хранения всех голосовых клипов, возвращаемых AWS Polly. Используйте консоль AWS, чтобы создать корзину с уникальным именем. В моем случае корзина S3 называется «мое-говорящее-приложение».
Создать роль IAM
Бессерверная структура создает две функции Lambda, которые взаимодействуют с сервисами AWS Polly и AWS S3. (Мы увидим код позже в блоге). Чтобы взаимодействовать с этими службами, нашей функции Lambda должна быть назначена роль IAM, у которой есть разрешение на общение с S3 и Polly. Итак, создайте роль IAM с предпочтительным именем, например, «говорящее-приложение-роль», со следующей политикой IAM.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"polly:*",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:HeadBucket"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-talking-app",
"arn:aws:s3:::my-talking-app/*"
]
}
]
}
Скопируйте ARN роли IAM и добавьте его в раздел провайдера файла serverless.yml.
provider: name: aws runtime: nodejs8.10 region: us-east-1 role: arn:aws:iam::885121665536:role/talking-app-role
«Говорить» лямбда-функция
Функция Speak Lambda выполняет три основные задачи.
- Вызовите AWS Polly synthesizeSpeech API и получите аудиопоток (формат mp3) для текста, введенного пользователем.
- Сохраните указанный выше аудиопоток в сегменте S3.
- Получите подписанный URL-адрес для сохраненного mp3-файла в S3 и отправьте его обратно во внешнее приложение.
Прежде всего, давайте установим необходимые модули npm внутри внутренней папки.
npm install aws-sdk npm install uuid
API AWS Polly synthesizeSpeech требует ввода текста и голосового идентификатора для преобразования текста в речь. Здесь мы используем голос «Джоанны» для озвучивания текста, передаваемого из внешнего интерфейса.
let AWS = require("aws-sdk");
let polly = new AWS.Polly();
let s3 = new AWS.S3();
const uuidv1 = require('uuid/v1');
module.exports.speak = (event, context, callback) => {
let data = JSON.parse(event.body);
const pollyParams = {
OutputFormat: "mp3",
Text: data.text,
VoiceId: data.voice
};
// 1. Getting the audio stream for the text that user entered
polly.synthesizeSpeech(pollyParams)
.on("success", function (response) {
let data = response.data;
let audioStream = data.AudioStream;
let key = uuidv1();
let s3BucketName = 'my-talking-app';
// 2. Saving the audio stream to S3
let params = {
Bucket: s3BucketName,
Key: key + '.mp3',
Body: audioStream
};
s3.putObject(params)
.on("success", function (response) {
console.log("S3 Put Success!");
})
.on("complete", function () {
console.log("S3 Put Complete!");
let s3params = {
Bucket: s3BucketName,
Key: key + '.mp3',
};
// 3. Getting a signed URL for the saved mp3 file
let url = s3.getSignedUrl("getObject", s3params);
// Sending the result back to the user
let result = {
bucket: s3BucketName,
key: key + '.mp3',
url: url
};
callback(null, {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*"
},
body: JSON.stringify(result)
});
})
.on("error", function (response) {
console.log(response);
})
.send();
})
.on("error", function (err) {
callback(null, {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*"
},
body: JSON.stringify(err)
});
})
.send();
};
Теперь разверните серверный API и функцию Lambda.
sls deploy
Фронтенд Angular-приложение
Чтобы протестировать наш бэкэнд, нам нужен интерфейс, который делает запрос речи с введенным пользователем текстом. Итак, давайте создадим угловое приложение.
ng new client ? Would you like to add Angular routing? No ? Which stylesheet format would you like to use? SCSS
Давайте создадим сервис angular, который общается с нашим сервером Amazon Polly.
ng g s API
Добавьте следующий код в файл api.service.ts. Он создаст функцию речи, которая вызывает лямбда-функцию с выбранным голосом и вставленным пользователем текстом.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class APIService {
ENDPOINT = '<YOUR_ENDPOINT_HERE>';
constructor(private http:HttpClient) {}
speak(data) {
return this.http.post(this.ENDPOINT, data);
}
}
Давайте воспользуемся основным компонентом приложения для визуализации пользовательского интерфейса Talking App. Перейдите к app.component.html и замените файл следующим HTML-кодом. Он добавит основную текстовую область, выбор предпочтительного голоса и кнопку действия произнесения.
<div style="margin: auto; padding: 10px; text-align: center;">
<h2>My Talking App</h2>
<div>
<textarea #userInput style="font-size: 15px; padding: 10px;" cols="60" rows="10"></textarea>
</div>
<div>
<select [(ngModel)]="selectedVoice">
<option *ngFor="let voice of voices" [ngValue]="voice">{{voice}}</option>
</select>
</div>
<div style="margin-top: 10px">
<button style="font-size: 15px;" (click)="speakNow(userInput.value)">Speak Now</button>
</div>
</div>
Перейдите к файлу app.component.ts и добавьте соответствующую функцию-обработчик для представления. Замените его следующим кодом.
import { Component } from '@angular/core';
import { APIService } from './api.service'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
voices = ["Matthew", "Joanna", "Ivy", "Justin"];
selectedVoice = "Mattew";
constructor(private api: APIService){}
playAudio(url){
let audio = new Audio();
audio.src = url;
audio.load();
audio.play();
}
speakNow(input){
let data = {
text: input,
voice: this.selectedVoice
}
this.api.speak(data).subscribe((result:any) => {
this.playAudio(result.url);
});
}
}
Поскольку мы используем ngModel в app.component.html, нам необходимо импортировать FormsModule в файл app.module.ts. Перейдите к файлу app.module.ts и замените содержимое на,
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
FormsModule,
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Запуск приложения
Теперь, когда наш бэкэнд и интерфейс готовы, давайте поиграем с нашим приложением.
Перейдите в каталог клиента и запустите приложение angular локально,
ng serve

Введите текст в текстовой области и выберите голос из раскрывающегося списка. Когда вы нажимаете Говорить, текст должен произноситься вслух!
Часть 02 доступна здесь.
Ваше здоровье!