Polly Reads the Yijing Ball Z

April 12, 2020 | 3 minute read

Playing with AWS Services - Would You Read For Me Polly?

In order to improve my deployment skills, I began playing with AWS Services.

A really cool service is Amazon Polly a cloud Text-to-Speech (TTS) service that converts text to lifelike speech. It supports multiple languages and can add engagement and accessibility to your app.

Talk to me Shenron!

I implemented Polly TTS in Yijing Ball Z (YBZ), our favorite iChing oracle.

Since YBZ is Vanilla JS app, I used the AWS SDK for JavaScript to implement this service and have Polly read the YBZ for us!

Here is the implementation:

1) Setup:

  • Make sure to npm install aws-sdk and then npm add aws-sdk so we can use it in YBZ.

2) Add read-out-loud button on navbar:

  • The first thing we’ll do is modify our UI to add a button that we will then attach our AWS.Polly read listener.
<div class="navbar-end"> 
 <a class="navbar-item button readpolly">
 Talk to me Shenron!</a>
</div> 

3) Let’s include AWS and config so you can communicate with AWS, then instantiate our Polly service.

  • Note: Amazon Translate does not work with Amazon Cognito Identity, so we need to add our own credentials. Read up on IAM to learn more.

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';

AWS.config.credentials = new AWS.Credentials("ACCESS_ID__HERE", 
"INSERT_SECRET_ACCESS_KEY_HERE");

var polly = new AWS.Polly();

4) Create a function doSynthesize() that will execute the Polly script and read out loud the text when button is pressed.

  • synthesizeSpeech() from AWS.Polly takes a params argument that takes the text argument we passed on doSynthesize().
  • Read here and here to learn more.

function doSynthesize(text) {
 var pollyParams = {
     OutputFormat: "mp3", 
     SampleRate: "8000", 
     Text: text, 
     TextType: "text", 
     VoiceId: "Joanna"
 };

polly.synthesizeSpeech(pollyParams, function(err, data) {
  if (err) {
      console.log(err, err.stack); // an error occurred
      alert("Error calling Amazon Polly. " + err.message);
  }
  else {
      var uInt8Array = new Uint8Array(data.AudioStream);
      var arrayBuffer = uInt8Array.buffer;
      var blob = new Blob([arrayBuffer]);
      var url = URL.createObjectURL(blob);

      audioElement = new Audio([url]);
      audioElement.play();
  }
});
}

5) Add our event listener and call doSynthesize() if triggered

const pollyBtn = document.querySelector(".readpolly")

pollyBtn.addEventListener("click", function(){
 // all our text is inside of main.content, so we grab it all
 const pollyText = document.querySelector("main.content").innerText
 doSynthesize(pollyText)
 })

6) Click the button and let Polly read the YBZ for you!

That wasn’t that bad right? :)