Часть 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 доступна здесь.
Ваше здоровье!