Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added output.mp3
Binary file not shown.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ limitations under the License.
<version>2.6.2</version>
</dependency>

<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-texttospeech</artifactId>
<version>0.80.0-beta</version>
</dependency>

</dependencies>

<build>
Expand Down
57 changes: 57 additions & 0 deletions src/main/java/com/google/codeu/data/QuickstartSample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.google.codeu.data;

// Imports the Google Cloud client library
import com.google.cloud.texttospeech.v1.AudioConfig;
import com.google.cloud.texttospeech.v1.AudioEncoding;
import com.google.cloud.texttospeech.v1.SsmlVoiceGender;
import com.google.cloud.texttospeech.v1.SynthesisInput;
import com.google.cloud.texttospeech.v1.SynthesizeSpeechResponse;
import com.google.cloud.texttospeech.v1.TextToSpeechClient;
import com.google.cloud.texttospeech.v1.VoiceSelectionParams;
import com.google.protobuf.ByteString;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.Exception;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment for the class.

public class QuickstartSample {

/**
* Demonstrates using the Text-to-Speech API.
*/
public static void main(String... args) throws Exception {
// Instantiates a client
try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create()) {
// Set the text input to be synthesized
SynthesisInput input = SynthesisInput.newBuilder()
.setText("Hello this is really nice haha.")
.build();

// Build the voice request, select the language code ("en-US") and the ssml voice gender
// ("neutral")
VoiceSelectionParams voice = VoiceSelectionParams.newBuilder()
.setLanguageCode("en-US")
// Try experimenting with the different voices
.setSsmlGender(SsmlVoiceGender.NEUTRAL) // Try experimenting with t
.build();

// Select the type of audio file you want returned
AudioConfig audioConfig = AudioConfig.newBuilder()
.setAudioEncoding(AudioEncoding.MP3)
.build();

// Perform the text-to-speech request on the text input with the selected voice parameters and
// audio file type
SynthesizeSpeechResponse response = textToSpeechClient.synthesizeSpeech(input, voice,
audioConfig);

// Get the audio contents from the response
ByteString audioContents = response.getAudioContent();

// Write the response to the output file.
try (OutputStream out = new FileOutputStream("/Users/minhphu/Desktop/GoogleCode/codeu-starter-project/output.mp3")) {
out.write(audioContents.toByteArray());
System.out.println("Audio content written to file \"/Users/minhphu/Desktop/GoogleCode/codeu-starter-project/output.mp3\"");
}
}
}
}
70 changes: 70 additions & 0 deletions src/main/java/com/google/codeu/servlets/MessageServlet2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.google.codeu.servlets;

import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.codeu.data.Message;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import com.google.cloud.texttospeech.v1.AudioConfig;
import com.google.cloud.texttospeech.v1.AudioEncoding;
import com.google.cloud.texttospeech.v1.SsmlVoiceGender;
import com.google.cloud.texttospeech.v1.SynthesisInput;
import com.google.cloud.texttospeech.v1.SynthesizeSpeechResponse;
import com.google.cloud.texttospeech.v1.TextToSpeechClient;
import com.google.cloud.texttospeech.v1.VoiceSelectionParams;
import com.google.protobuf.ByteString;
import java.util.stream.Collectors;

/** Handles fetching and saving {@link Message} instances. */
@WebServlet("/a11y/tts")
public class MessageServlet2 extends HttpServlet {
/** Responses with a bytestream from the Google Cloud
/* Text-to-Speech API
**/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

UserService userService = UserServiceFactory.getUserService();
if (!userService.isUserLoggedIn()) {
response.sendRedirect("/index.html");
return;
}
// To get clean messages, removed dangerous things, html
String userMessage = Jsoup.clean(request.getReader().lines().collect(Collectors.joining(System.lineSeparator())), Whitelist.none());

try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create()) {
// Set the text input to be synthesized
SynthesisInput input = SynthesisInput.newBuilder()
.setText(userMessage)
.build();

// Build the voice request, select the language code ("en-US") and the ssml voice gender
// ("neutral")
VoiceSelectionParams voice = VoiceSelectionParams.newBuilder()
.setLanguageCode("en-US")
.setSsmlGender(SsmlVoiceGender.NEUTRAL)
.build();

// Select the type of audio file you want returned
AudioConfig audioConfig = AudioConfig.newBuilder()
.setAudioEncoding(AudioEncoding.MP3)
.build();

// Perform the text-to-speech request on the text input with the selected voice parameters and
// audio file type
SynthesizeSpeechResponse apiResponse = textToSpeechClient.synthesizeSpeech(input, voice,
audioConfig);

// Get the audio contents from the response
ByteString audioContents = apiResponse.getAudioContent();

response.setContentType("audio/mpeg");
response.getOutputStream().write(audioContents.toByteArray());
}
}
}
34 changes: 34 additions & 0 deletions src/main/java/com/google/codeu/servlets/QuickstartServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.google.codeu.servlets;

import java.io.IOException;
import java.util.List;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.codeu.data.QuickstartSample;

/**
* Runs QuickstartSample class to demonstrate the text-to-speech API
*/
@WebServlet("/quickstart")
public class QuickstartServlet extends HttpServlet {

private QuickstartSample quickstartSample;

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
try {
quickstartSample = new QuickstartSample();
quickstartSample.main();
} catch (Exception e) {
System.out.println("An exception was thrown.");
}
response.setContentType("application/json");

response.getWriter().println("Have printed the file");
}

}
Binary file added src/main/webapp/audio/output.mp3
Binary file not shown.
48 changes: 42 additions & 6 deletions src/main/webapp/js/user-page-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,14 @@ function fetchMessages() {
return response.json();
})
.then((messages) => {
console.log(messages);
const messagesContainer = document.getElementById('message-container');
if (messages.length == 0) {
messagesContainer.innerHTML = '<p>This user has no posts yet.</p>';
} else {
messagesContainer.innerHTML = '';
}
messages.forEach((message) => {
const messageDiv = buildMessageDiv(message);
messages.forEach(async (message) => {
const messageDiv = await buildMessageDiv(message);
messagesContainer.appendChild(messageDiv);
});
});
Expand All @@ -76,7 +75,7 @@ function fetchMessages() {
* @param {Message} message
* @return {Element}
*/
function buildMessageDiv(message) {
async function buildMessageDiv(message) {
const headerDiv = document.createElement('div');
headerDiv.classList.add('message-header');
headerDiv.appendChild(document.createTextNode(
Expand All @@ -92,11 +91,48 @@ function buildMessageDiv(message) {
messageDiv.classList.add('message-div');
messageDiv.appendChild(headerDiv);
messageDiv.appendChild(bodyDiv);

audio = await createAudioTag(message.text);
messageDiv.appendChild(audio);
return messageDiv;
}

/** Fetches about me data from user's input and adds it to the page. */
/**
* Creates audio tag.
*/
async function createAudioTag(messageText) {
// Do nothing, can consider showing a simple error to the user.
if (messageText === "") {
return;
}

try {
let resp = await fetch("/a11y/tts", {
method: "POST",
body: messageText,
headers: {
"Content-Type": "text/plain"
},
})

let audio = await resp.blob();

var objectURL = URL.createObjectURL(audio);

var sound = document.createElement('audio');
sound.controls = 'controls';
sound.src = objectURL;
sound.type = 'audio/mpeg';

return sound;

} catch (err) {
throw new Error(`Unable to call the Text to Speech API: {err}`)
}
}

/**
* Fetches about me data from user's input and adds it to the page.
*/
function fetchAboutMe() {
const url = '/about?user=' + parameterUsername;
fetch(url)
Expand Down