Skip to content

Commit

Permalink
fix: MP3 file test for Text-to-Speech SSML addresses [(#2378)](Google…
Browse files Browse the repository at this point in the history
…CloudPlatform/python-docs-samples#2378)

* fix: refactored MP3 file tests

* fix: moving resources to cloud-client/resources

* fix: removing expected_example.mp3
  • Loading branch information
crowdus authored and busunkim96 committed May 20, 2020
1 parent 4cf0d66 commit 2a5e254
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<speak>123 Street Ln, Small Town, IL 12345 USA
<break time="2s"/>1 Jenny St &amp; Number St, Tutone City, CA 86753
<break time="2s"/>1 Piazza del Fibonacci, 12358 Pisa, Italy
<break time="2s"/></speak>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
123 Street Ln, Small Town, IL 12345 USA
1 Jenny St & Number St, Tutone City, CA 86753
1 Piazza del Fibonacci, 12358 Pisa, Italy
112 changes: 112 additions & 0 deletions packages/google-cloud-texttospeech/samples/ssml_addresses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# [START tts_ssml_address_imports]
from google.cloud import texttospeech

import html
# [END tts_ssml_address_imports]


# [START tts_ssml_address_audio]
def ssml_to_audio(ssml_text, outfile):
# Generates SSML text from plaintext.
#
# Given a string of SSML text and an output file name, this function
# calls the Text-to-Speech API. The API returns a synthetic audio
# version of the text, formatted according to the SSML commands. This
# function saves the synthetic audio to the designated output file.
#
# Args:
# ssml_text: string of SSML text
# outfile: string name of file under which to save audio output
#
# Returns:
# nothing

# Instantiates a client
client = texttospeech.TextToSpeechClient()

# Sets the text input to be synthesized
synthesis_input = texttospeech.types.SynthesisInput(ssml=ssml_text)

# Builds the voice request, selects the language code ("en-US") and
# the SSML voice gender ("MALE")
voice = texttospeech.types.VoiceSelectionParams(
language_code='en-US',
ssml_gender=texttospeech.enums.SsmlVoiceGender.MALE)

# Selects the type of audio file to return
audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3)

# Performs the text-to-speech request on the text input with the selected
# voice parameters and audio file type
response = client.synthesize_speech(synthesis_input, voice, audio_config)

# Writes the synthetic audio to the output file.
with open(outfile, 'wb') as out:
out.write(response.audio_content)
print('Audio content written to file ' + outfile)
# [END tts_ssml_address_audio]


# [START tts_ssml_address_ssml]
def text_to_ssml(inputfile):
# Generates SSML text from plaintext.
# Given an input filename, this function converts the contents of the text
# file into a string of formatted SSML text. This function formats the SSML
# string so that, when synthesized, the synthetic audio will pause for two
# seconds between each line of the text file. This function also handles
# special text characters which might interfere with SSML commands.
#
# Args:
# inputfile: string name of plaintext file
#
# Returns:
# A string of SSML text based on plaintext input

# Parses lines of input file
with open(inputfile, 'r') as f:
raw_lines = f.read()

# Replace special characters with HTML Ampersand Character Codes
# These Codes prevent the API from confusing text with
# SSML commands
# For example, '<' --> '&lt;' and '&' --> '&amp;'

escaped_lines = html.escape(raw_lines)

# Convert plaintext to SSML
# Wait two seconds between each address
ssml = '<speak>{}</speak>'.format(
escaped_lines.replace('\n', '\n<break time="2s"/>'))

# Return the concatenated string of ssml script
return ssml
# [END tts_ssml_address_ssml]


# [START tts_ssml_address_test]
def main():
# test example address file
plaintext = 'resources/example.txt'
ssml_text = text_to_ssml(plaintext)
ssml_to_audio(ssml_text, 'resources/example.mp3')
# [END tts_ssml_address_test]


if __name__ == '__main__':
main()
49 changes: 49 additions & 0 deletions packages/google-cloud-texttospeech/samples/ssml_addresses_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from ssml_addresses import text_to_ssml
from ssml_addresses import ssml_to_audio

import filecmp
import os


def test_text_to_ssml(capsys):

# Read expected SSML output from resources
with open('resources/example.ssml', 'r') as f:
expected_ssml = f.read()

# Assert plaintext converted to SSML
input_text = 'resources/example.txt'
tested_ssml = text_to_ssml(input_text)
assert expected_ssml == tested_ssml


def test_ssml_to_audio(capsys):

# Read SSML input from resources
with open('resources/example.ssml', 'r') as f:
input_ssml = f.read()

# Assert audio file generated
ssml_to_audio(input_ssml, 'test_example.mp3')
out, err = capsys.readouterr()

# Assert MP3 file created
assert os.path.isfile('test_example.mp3')
assert "Audio content written to file test_example.mp3" in out

# Delete MP3 test file
os.remove("test_example.mp3")

0 comments on commit 2a5e254

Please sign in to comment.