SSML で住所を読み上げる

このチュートリアルでは、音声合成マークアップ言語(SSML)を使用して住所のテキスト ファイルを読み上げる方法を説明します。SSML タグで文字列をマークアップして、Text-to-Speech から合成音声をカスタマイズできます。

平文 平文の SSML レンダリング

123 Street Ln

<speak>123 Street Ln</speak>

1 Number St

<speak>1 Number St</speak>

1 Piazza del Fibonacci

<speak>1 Piazza del Fibonacci</speak>

目標

SSML と Text-to-Speech クライアント ライブラリを使用して、Text-to-Speech に合成音声リクエストを送信します。

料金

費用の詳細は、Text-to-Speech の料金ページをご覧ください。

始める前に

コードサンプルのダウンロード

コードサンプルをダウンロードするには、使用するプログラミング言語の Google Cloud GitHub サンプルのクローンを作成します。

Java

このチュートリアルでは、Google Cloud Platform Java サンプルtexttospeech/cloud-client/src/main/java/com/example/texttospeech/ ディレクトリのコードを使用します。

このチュートリアルのコードをダウンロードし、そのコードに移動するには、次のコマンドをターミナルから実行します。

git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
cd java-docs-samples/texttospeech/cloud-client/src/main/java/com/example/texttospeech/

Node.js

このチュートリアルでは、googleapis リポジトリnodejs-text-to-speech/samples ディレクトリのコードを使用します。

このチュートリアルのコードをダウンロードし、そのコードに移動するには、次のコマンドをターミナルから実行します。

git clone https://github.com/googleapis/nodejs-text-to-speech.git
cd nodejs-text-to-speech/samples/

Python

このチュートリアルでは、Python Text-to-Speech Librarysamples/snippets ディレクトリにあるコードを使用します。

このチュートリアルのコードをダウンロードし、そのコードに移動するには、次のコマンドをターミナルから実行します。

git clone https://github.com/googleapis/python-texttospeech.git
cd samples/snippets

クライアント ライブラリのインストール

このチュートリアルでは、Text-to-Speech クライアント ライブラリを使用します。

Java

このチュートリアルでは、次の依存関係を使用します。

<!--  Using libraries-bom to manage versions.
See https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/The-Google-Cloud-Platform-Libraries-BOM -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>libraries-bom</artifactId>
      <version>16.1.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-texttospeech</artifactId>
  </dependency>
</dependencies>

Node.js

ターミナルから、次のコマンドを実行します。

npm install @google-cloud/text-to-speech

Python

ターミナルから、次のコマンドを実行します。

pip install --upgrade google-cloud-texttospeech

Google Cloud Platform 認証情報の設定

環境変数 GOOGLE_APPLICATION_CREDENTIALS を設定して、アプリケーション コードに認証情報を指定します。[PATH] は、サービス アカウント キーが含まれる JSON ファイルのファイルパスに置き換えます。この変数は現在のシェル セッションにのみ適用されるため、新しいセッションを開く場合は、変数を再度設定します。

Linux または macOS

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

例:

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/my-key.json"

Windows

PowerShell を使用する場合:

$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

例:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\my-key.json"

コマンド プロンプトを使用する場合:

set GOOGLE_APPLICATION_CREDENTIALS=[PATH]

ライブラリのインポート

このチュートリアルでは、次のシステム ライブラリとクライアント ライブラリを使用します。

Java

// 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.common.html.HtmlEscapers;
import com.google.protobuf.ByteString;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

Node.js

// Imports the Google Cloud client library
const textToSpeech = require('@google-cloud/text-to-speech');

// Import other required libraries
const fs = require('fs');
//const escape = require('escape-html');
const util = require('util');

Python

import html

from google.cloud import texttospeech

Text-to-Speech API の使用

次の関数は、SSML でタグ付けされた文字列と MP3 ファイルの名前を受け取ります。SSML でタグ付けされたテキストは、合成音声の生成に使用されます。パラメータとして指定された MP3 ファイル名で合成音声が保存されます。

SSML 入力全体を 1 つの音声でしか読み込めません。音声は VoiceSelectionParams オブジェクトで設定できます。

Java

/**
 * Generates synthetic audio from a String of SSML text.
 *
 * <p>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.
 *
 * @param ssmlText String of tagged SSML text
 * @param outFile String name of file under which to save audio output
 * @throws Exception on errors while closing the client
 */
public static void ssmlToAudio(String ssmlText, String outFile) throws Exception {
  // Instantiates a client
  try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create()) {
    // Set the ssml text input to synthesize
    SynthesisInput input = SynthesisInput.newBuilder().setSsml(ssmlText).build();

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

    // Select the audio file type
    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(outFile)) {
      out.write(audioContents.toByteArray());
      System.out.println("Audio content written to file " + outFile);
    }
  }
}

Node.js

/**
 * Generates synthetic audio from a String of SSML text.
 *
 * 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
 * ssmlText: String of tagged SSML text
 * outfile: String name of file under which to save audio output
 * RETURNS
 * nothing
 *
 */
async function ssmlToAudio(ssmlText, outFile) {
  // Creates a client
  const client = new textToSpeech.TextToSpeechClient();

  // Constructs the request
  const request = {
    // Select the text to synthesize
    input: {ssml: ssmlText},
    // Select the language and SSML Voice Gender (optional)
    voice: {languageCode: 'en-US', ssmlGender: 'MALE'},
    // Select the type of audio encoding
    audioConfig: {audioEncoding: 'MP3'},
  };

  // Performs the Text-to-Speech request
  const [response] = await client.synthesizeSpeech(request);
  // Write the binary audio content to a local file
  const writeFile = util.promisify(fs.writeFile);
  await writeFile(outFile, response.audioContent, 'binary');
  console.log('Audio content written to file ' + outFile);
}

Python

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.SynthesisInput(ssml=ssml_text)

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

    # Selects the type of audio file to return
    audio_config = texttospeech.AudioConfig(
        audio_encoding=texttospeech.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(
        input=synthesis_input, voice=voice, audio_config=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)

合成音声のカスタマイズ

次の関数は、テキスト ファイルの名前を受け取り、そのファイルの内容を SSML でタグ付けされたテキストの文字列に変換します。

Java

/**
 * Generates SSML text from plaintext.
 *
 * <p>Given an input filename, this function converts the contents of the input text file into a
 * String of tagged 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.
 *
 * @param inputFile String name of plaintext file
 * @return a String of SSML text based on plaintext input.
 * @throws IOException on files that don't exist
 */
public static String textToSsml(String inputFile) throws Exception {

  // Read lines of input file
  String rawLines = new String(Files.readAllBytes(Paths.get(inputFile)));

  // Replace special characters with HTML Ampersand Character Codes
  // These codes prevent the API from confusing text with SSML tags
  // For example, '<' --> '&lt;' and '&' --> '&amp;'
  String escapedLines = HtmlEscapers.htmlEscaper().escape(rawLines);

  // Convert plaintext to SSML
  // Tag SSML so that there is a 2 second pause between each address
  String expandedNewline = escapedLines.replaceAll("\\n", "\n<break time='2s'/>");
  String ssml = "<speak>" + expandedNewline + "</speak>";

  // Return the concatenated String of SSML
  return ssml;
}

Node.js

/**
 * Generates SSML text from plaintext.
 *
 * Given an input filename, this function converts the contents of the input text file
 * into a String of tagged 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
 *
 */
function textToSsml(inputFile) {
  let rawLines = '';
  // Read input file
  try {
    rawLines = fs.readFileSync(inputFile, 'utf8');
  } catch (e) {
    console.log('Error:', e.stack);
    return;
  }

  // Replace special characters with HTML Ampersand Character Codes
  // These codes prevent the API from confusing text with SSML tags
  // For example, '<' --> '&lt;' and '&' --> '&amp;'
  let escapedLines = rawLines;
  escapedLines = escapedLines.replace(/&/g, '&amp;');
  escapedLines = escapedLines.replace(/"/g, '&quot;');
  escapedLines = escapedLines.replace(/</g, '&lt;');
  escapedLines = escapedLines.replace(/>/g, '&gt;');

  // Convert plaintext to SSML
  // Tag SSML so that there is a 2 second pause between each address
  const expandedNewline = escapedLines.replace(/\n/g, '\n<break time="2s"/>');
  const ssml = '<speak>' + expandedNewline + '</speak>';

  // Return the concatenated String of SSML
  return ssml;
}

Python

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

すべてを組み合わせる

このプログラムは次の内容を入力に使用します。

123 Street Ln, Small Town, IL 12345 USA
1 Jenny St & Number St, Tutone City, CA 86753
1 Piazza del Fibonacci, 12358 Pisa, Italy

上記のテキストを text_to_ssml() に渡すと、次のタグ付きテキストが生成されます。

<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>

コードの実行

合成音声のオーディオ ファイルを生成するには、コマンドラインから次のコードを実行します。

Java

Linux または macOS

java-docs-samples/texttospeech/cloud-client/ ディレクトリから、コマンドラインで次のコマンドを実行します。

$ mvn clean package

Windows

java-docs-samples/texttospeech/cloud-client/ ディレクトリから、コマンドラインで次のコマンドを実行します。

$ mvn clean package

Node.js

Linux または macOS

hybridGlossaries.js ファイルの、コメントアウトされた変数 TODO (developer) のコメント化を解除します。

次のコマンドで、projectId は、Google Cloud プロジェクト ID に置き換えます。nodejs-text-to-speech/samples ディレクトリから、コマンドラインで次のコマンドを実行します。

$ node ssmlAddresses.js projectId

Windows

hybridGlossaries.js ファイルの、コメントアウトされた変数 TODO (developer) のコメント化を解除します。

次のコマンドで、projectId は、Google Cloud プロジェクト ID に置き換えます。nodejs-text-to-speech/samples ディレクトリから、コマンドラインで次のコマンドを実行します。

$env: C:/Node.js/node.exe C: ssmlAddresses.js projectId

Python

Linux または macOS

python-texttospeech/samples/snippets ディレクトリから、コマンドラインで次のコマンドを実行します。

$ python ssml_addresses.py

Windows

python-texttospeech/samples/snippets ディレクトリから、コマンドラインで次のコマンドを実行します。

$env: C:/Python3/python.exe C: ssml_addresses.py

出力の確認

このプログラムは、合成音声の example.mp3 音声ファイルを出力します。

Java

java-docs-samples/texttospeech/cloud-client/resources/ディレクトリに移動します。

resources ディレクトリで example.mp3 ファイルを確認します。

Node.js

nodejs-text-tospeech/samples/resources/ディレクトリに移動します。

resources ディレクトリで example.mp3 ファイルを確認します。

Python

python-texttospeech/samples/snippets/resources に移動します。

resources ディレクトリで example.mp3 ファイルを確認します。

次の音声クリップを聴いて example.mp3 ファイルが同じように聞こえることを確認します。


トラブルシューティング

  • コマンドラインで GOOGLE_APPLICATION_CREDENTIALS 環境変数を設定し忘れると、エラー メッセージが表示されます。

    The Application Default Credentials are not available.

  • 存在しないファイルの名前を text_to_ssml() に渡すと、次のエラー メッセージが出力されます。

    IOError: [Errno 2] No such file or directory
    

  • None を含む ssml_text パラメータを ssml_to_audio() に渡すと、次のエラー メッセージが出力されます。

    InvalidArgument: 400 Invalid input type. Type has to be text or SSML
    

  • 正しいディレクトリでコードを実行していることを確認してください。

次のステップ

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにするには、プロジェクトが不要であれば Google Cloud Console を使用して削除します。

プロジェクトの削除

  1. Cloud Console で、プロジェクト ページに移動します。
  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログ ボックスで、プロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。