

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Amazon Polly용 샘플 코드 및 애플리케이션
<a name="samples-and-examples"></a>

이 섹션에서는 Amazon Polly를 살펴보기 위해 사용할 수 있는 코드 샘플 및 예제 애플리케이션을 제공합니다.

**샘플 코드** 주제에는 프로그래밍 언어별로 정리된 코드 스니펫이 포함되어 있으며 다양한 Amazon Polly 기능에 대한 예제로 구분되어 있습니다. **예제 애플리케이션** 주제에는 Amazon Polly를 탐색할 때 독립적으로 사용할 수 있는 프로그래밍 언어별로 구성된 애플리케이션이 포함되어 있습니다.

이러한 예를 사용하기 전에 [Amazon Polly의 작동 방식](how-text-to-speech-works.md)에서 설명하는 단계를 먼저 읽고 [Amazon Polly 시작하기](getting-started.md)에서 설명하는 단계를 수행하는 것이 좋습니다.

**Topics**
+ [Java 샘플](java-samples.md)
+ [Python 샘플](python-samples.md)
+ [Java 예제](examples-java.md)
+ [Python 예제(HTML5 클라이언트 및 Python 서버)](examples-python.md)
+ [iOS 예제](examples-ios.md)
+ [Android 예제](examples-android.md)

# Java 샘플
<a name="java-samples"></a>

다음 코드 샘플은 Java 기반 애플리케이션을 사용하여 Amazon Polly에서 다양한 작업을 수행하는 방법을 보여줍니다. 이 샘플은 완전한 예제는 아니지만 [AWS SDK for Java](https://aws.amazon.com/documentation/sdk-for-java/)를 사용하는 대규모 Java 애플리케이션에 포함될 수 있습니다. 

**Topics**
+ [DeleteLexicon](DeleteLexiconSample.md)
+ [DescribeVoices](DescribeVoicesSample.md)
+ [GetLexicon](GetLexiconSample.md)
+ [ListLexicons](ListLexiconsSample.md)
+ [PutLexicon](PutLexiconSample.md)
+ [StartSpeechSynthesisTask](StartSpeechSynthesisTask.md)
+ [스피치 마크](SynthesizeSpeechMarksSample.md)
+ [SynthesizeSpeech](SynthesizeSpeechSample.md)

# DeleteLexicon
<a name="DeleteLexiconSample"></a>

다음 Java 코드 샘플은 Java 기반 애플리케이션을 사용하여 AWS 리전에 저장된 특정 어휘를 삭제하는 방법을 보여줍니다. 삭제된 어휘는 스피치 합성에 사용할 수 없으며 `GetLexicon` 또는 `ListLexicon` API를 사용하여 검색할 수도 없습니다.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_DeleteLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_DeleteLexicon.html) API 참조를 참조하세요.

## SDK v2
<a name="delete-sdk-v2"></a>

```
/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   SPDX-License-Identifier: Apache-2.0
*/

package com.example.polly;

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.PollyClient;
import software.amazon.awssdk.services.polly.model.DeleteLexiconRequest;
import software.amazon.awssdk.services.polly.model.DeleteLexiconResponse;
import software.amazon.awssdk.services.polly.model.PollyException ;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class DeleteLexiconSample {

    public static void main(String args[]) {

        PollyClient polly = PollyClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();

        deleteLexicon(polly) ;
        polly.close();
    }

    private static String LEXICON_NAME = "SampleLexicon";
    public static void deleteLexicon(PollyClient client) {

        try {
            DeleteLexiconRequest deleteLexiconRequest = DeleteLexiconRequest.builder()
                    .name(LEXICON_NAME).build();

            DeleteLexiconResponse deleteLexiconResult = client.deleteLexicon(deleteLexiconRequest);

        } catch (PollyException e) {
            System.err.println("Exception caught: " + e);
            System.exit(1);
        }
    }

}
```

## SDK v1
<a name="delete-sdk-v1"></a>

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.DeleteLexiconRequest;
 
public class DeleteLexiconSample {
    private String LEXICON_NAME = "SampleLexicon";
 
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();
 
    public void deleteLexicon() {
        DeleteLexiconRequest deleteLexiconRequest = new DeleteLexiconRequest().withName(LEXICON_NAME);
 
        try {
            client.deleteLexicon(deleteLexiconRequest);
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# DescribeVoices
<a name="DescribeVoicesSample"></a>

다음 Java 코드 예에서는 Java 기반 애플리케이션을 사용하여 스피치 합성을 요청할 때 사용할 수 있는 음성 목록을 생성하는 방법을 보여줍니다. 필요한 경우 언어 코드를 지정하여 사용 가능한 음성을 필터링할 수 있습니다. 예를 들어 en-US를 지정하면 사용 가능한 모든 미국 영어 음성 목록을 반환합니다.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_DescribeVoices.html](https://docs.aws.amazon.com/polly/latest/dg/API_DescribeVoices.html) API 참조를 참조하세요.

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.DescribeVoicesRequest;
import com.amazonaws.services.polly.model.DescribeVoicesResult;
 
public class DescribeVoicesSample {
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();
 
    public void describeVoices() {
        DescribeVoicesRequest allVoicesRequest = new DescribeVoicesRequest();
        DescribeVoicesRequest enUsVoicesRequest = new DescribeVoicesRequest().withLanguageCode("en-US");
 
        try {
            String nextToken;
            do {
                DescribeVoicesResult allVoicesResult = client.describeVoices(allVoicesRequest);
                nextToken = allVoicesResult.getNextToken();
                allVoicesRequest.setNextToken(nextToken);
 
                System.out.println("All voices: " + allVoicesResult.getVoices());
            } while (nextToken != null);
 
            do {
                DescribeVoicesResult enUsVoicesResult = client.describeVoices(enUsVoicesRequest);
                nextToken = enUsVoicesResult.getNextToken();
                enUsVoicesRequest.setNextToken(nextToken);
 
                System.out.println("en-US voices: " + enUsVoicesResult.getVoices());
            } while (nextToken != null);
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# GetLexicon
<a name="GetLexiconSample"></a>

다음 Java 코드 샘플은 Java 기반 애플리케이션을 사용하여 AWS 리전에 저장된 특정 발음 어휘의 내용을 생성하는 방법을 보여줍니다.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_GetLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_GetLexicon.html) API 참조를 참조하세요.

## SDK v2
<a name="get-sdk-v2"></a>

```
/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   SPDX-License-Identifier: Apache-2.0
*/

package com.example.polly;

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.PollyClient;
import software.amazon.awssdk.services.polly.model.GetLexiconRequest;
import software.amazon.awssdk.services.polly.model.GetLexiconResponse;
import software.amazon.awssdk.services.polly.model.PollyException ;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class GetLexiconSample {

    public static void main(String args[]) {

        PollyClient polly = PollyClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();

        getLexicon(polly) ;
        polly.close();
    }

    private static String LEXICON_NAME = "SampleLexicon";
    public static void getLexicon(PollyClient client) {

        try {
            GetLexiconRequest getLexiconRequest = GetLexiconRequest.builder()
                    .name(LEXICON_NAME).build();

            GetLexiconResponse getLexiconResult = client.getLexicon(getLexiconRequest);
            System.out.println("The name of the Lexicon is " + getLexiconResult.lexicon().name());

        } catch (PollyException e) {
            System.err.println("Exception caught: " + e);
            System.exit(1);
        }
    }

}
```

## SDK v1
<a name="get-sdk-v1"></a>

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.GetLexiconRequest;
import com.amazonaws.services.polly.model.GetLexiconResult;
 
public class GetLexiconSample {
    private String LEXICON_NAME = "SampleLexicon";
 
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();
 
    public void getLexicon() {
        GetLexiconRequest getLexiconRequest = new GetLexiconRequest().withName(LEXICON_NAME);
 
        try {
            GetLexiconResult getLexiconResult = client.getLexicon(getLexiconRequest);
            System.out.println("Lexicon: " + getLexiconResult.getLexicon());
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# ListLexicons
<a name="ListLexiconsSample"></a>

다음 Java 코드 샘플은 Java 기반 애플리케이션을 사용하여 AWS 리전에 저장된 발음 어휘 목록을 생성하는 방법을 보여줍니다.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_ListLexicons.html](https://docs.aws.amazon.com/polly/latest/dg/API_ListLexicons.html) API 참조를 참조하세요.

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.LexiconAttributes;
import com.amazonaws.services.polly.model.LexiconDescription;
import com.amazonaws.services.polly.model.ListLexiconsRequest;
import com.amazonaws.services.polly.model.ListLexiconsResult;
 
public class ListLexiconsSample {
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();
 
    public void listLexicons() {
        ListLexiconsRequest listLexiconsRequest = new ListLexiconsRequest();
 
        try {
            String nextToken;
            do {
                ListLexiconsResult listLexiconsResult = client.listLexicons(listLexiconsRequest);
                nextToken = listLexiconsResult.getNextToken();
                listLexiconsRequest.setNextToken(nextToken);
 
                for (LexiconDescription lexiconDescription : listLexiconsResult.getLexicons()) {
                    LexiconAttributes attributes = lexiconDescription.getAttributes();
                    System.out.println("Name: " + lexiconDescription.getName()
                            + ", Alphabet: " + attributes.getAlphabet()
                            + ", LanguageCode: " + attributes.getLanguageCode()
                            + ", LastModified: " + attributes.getLastModified()
                            + ", LexemesCount: " + attributes.getLexemesCount()
                            + ", LexiconArn: " + attributes.getLexiconArn()
                            + ", Size: " + attributes.getSize());
                }
            } while (nextToken != null);
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# PutLexicon
<a name="PutLexiconSample"></a>

다음 Java 코드 샘플은 Java 기반 애플리케이션을 사용하여 AWS 리전에 발음 어휘를 저장하는 방법을 보여줍니다.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_PutLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_PutLexicon.html) API 참조를 참조하세요.

## SDK v2
<a name="put-sdk-v2"></a>

```
/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   SPDX-License-Identifier: Apache-2.0
*/

package com.example.polly;

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.PollyClient;
import software.amazon.awssdk.services.polly.model.PutLexiconRequest;
import software.amazon.awssdk.services.polly.model.PutLexiconResponse;
import software.amazon.awssdk.services.polly.model.PollyException ;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class PutLexiconSample {

    public static void main(String args[]) {

        PollyClient polly = PollyClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();

        putLexicon(polly) ;
        polly.close();
    }

    private static String LEXICON_CONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<lexicon version=\"1.0\" xmlns=\"http://www.w3.org/2005/01/pronunciation-lexicon\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
            "xsi:schemaLocation=\"http://www.w3.org/2005/01/pronunciation-lexicon http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd\" " +
            "alphabet=\"ipa\" xml:lang=\"en-US\">" +
            "<lexeme><grapheme>test1</grapheme><alias>test2</alias></lexeme>" +
            "</lexicon>";
    private static String LEXICON_NAME = "SampleLexicon";
    public static void putLexicon(PollyClient client) {

        try {
            PutLexiconRequest putLexiconRequest = PutLexiconRequest.builder()
                    .name(LEXICON_NAME).content(LEXICON_CONTENT).build();

            PutLexiconResponse putLexiconResult = client.putLexicon(putLexiconRequest);

        } catch (PollyException e) {
            System.err.println("Exception caught: " + e);
            System.exit(1);
        }
    }

}
```

## SDK v1
<a name="put-sdk-v1"></a>

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.PutLexiconRequest;
 
public class PutLexiconSample {
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();

    private String LEXICON_CONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<lexicon version=\"1.0\" xmlns=\"http://www.w3.org/2005/01/pronunciation-lexicon\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
            "xsi:schemaLocation=\"http://www.w3.org/2005/01/pronunciation-lexicon http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd\" " +
            "alphabet=\"ipa\" xml:lang=\"en-US\">" +
            "<lexeme><grapheme>test1</grapheme><alias>test2</alias></lexeme>" +
            "</lexicon>";   
    private String LEXICON_NAME = "SampleLexicon";
 
    public void putLexicon() {
        PutLexiconRequest putLexiconRequest = new PutLexiconRequest()
                .withContent(LEXICON_CONTENT)
                .withName(LEXICON_NAME);
 
        try {
            client.putLexicon(putLexiconRequest);
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# StartSpeechSynthesisTask
<a name="StartSpeechSynthesisTask"></a>

다음 Java 코드 샘플은 Java 기반 애플리케이션을 사용하여 긴 스피치(최대 100,000 유료 문자)을 합성하고 Amazon S3 버킷에 직접 저장하는 방법을 보여줍니다.

자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_StartSpeechSynthesisTask.html](https://docs.aws.amazon.com/polly/latest/dg/API_StartSpeechSynthesisTask.html) API 참조를 참조하세요.

## SDK v2
<a name="start-sdk-v2"></a>

```
/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   SPDX-License-Identifier: Apache-2.0
*/

package com.example.polly;

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.PollyClient;
import software.amazon.awssdk.services.polly.model.*;

import java.time.Duration;
import org.awaitility.Durations;
import org.awaitility.Awaitility;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class StartSpeechSynthesisTaskSample {

    public static void main(String args[]) {

        PollyClient polly = PollyClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();

        startSpeechSynthesisTask(polly) ;
        polly.close();
    }

    private static final String PLAIN_TEXT = "This is a sample text to be synthesized.";
    private static final String OUTPUT_FORMAT_MP3 = OutputFormat.MP3.toString();
    private static final String OUTPUT_BUCKET = "synth-books-buckets";
    private static final String SNS_TOPIC_ARN = "arn:aws:sns:eu-west-2:123456789012:synthesize-finish-topic";
    private static final Duration SYNTHESIS_TASK_POLL_INTERVAL = Durations.FIVE_SECONDS;
    private static final Duration SYNTHESIS_TASK_POLL_DELAY = Durations.TEN_SECONDS;
    private static final Duration SYNTHESIS_TASK_TIMEOUT = Durations.FIVE_MINUTES;
    public static void startSpeechSynthesisTask(PollyClient client) {

        try {
            StartSpeechSynthesisTaskRequest startSpeechSynthesisTaskRequest = StartSpeechSynthesisTaskRequest.builder()
                    .outputFormat(OUTPUT_FORMAT_MP3).text(PLAIN_TEXT).textType(TextType.TEXT)
                    .voiceId(VoiceId.AMY).outputS3BucketName(OUTPUT_BUCKET).snsTopicArn(SNS_TOPIC_ARN)
                    .engine("neural").build();

            StartSpeechSynthesisTaskResponse startSpeechSynthesisTaskResponse =
                    client.startSpeechSynthesisTask(startSpeechSynthesisTaskRequest);
            String taskId = startSpeechSynthesisTaskResponse.synthesisTask().taskId();

            Awaitility.await().with()
                    .pollInterval(SYNTHESIS_TASK_POLL_INTERVAL)
                    .pollDelay(SYNTHESIS_TASK_POLL_DELAY)
                    .atMost(SYNTHESIS_TASK_TIMEOUT)
                    .until(
                            () -> getSynthesisTaskStatus(client, taskId).equals(TaskStatus.COMPLETED.toString())
                    );

        } catch (PollyException e) {
            System.err.println("Exception caught: " + e);
            System.exit(1);
        }
    }

    private static String getSynthesisTaskStatus(PollyClient client, String taskId) {
        GetSpeechSynthesisTaskRequest getSpeechSynthesisTaskRequest = GetSpeechSynthesisTaskRequest.builder()
                .taskId(taskId).build();
        GetSpeechSynthesisTaskResponse result = client.getSpeechSynthesisTask(getSpeechSynthesisTaskRequest);
        return result.synthesisTask().taskStatusAsString();
    }

}
```

## SDK v1
<a name="start-sdk-v1"></a>

```
package com.amazonaws.parrot.service.tests.speech.task;

import com.amazonaws.parrot.service.tests.AbstractParrotServiceTest;
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.model.*;
import org.awaitility.Duration;

import java.util.concurrent.TimeUnit;

import static org.awaitility.Awaitility.await;

public class StartSpeechSynthesisTaskSample {

    private static final int SYNTHESIS_TASK_TIMEOUT_SECONDS = 300;
    private static final AmazonPolly AMAZON_POLLY_CLIENT = AmazonPollyClientBuilder.defaultClient();
    private static final String PLAIN_TEXT = "This is a sample text to be synthesized.";
    private static final String OUTPUT_FORMAT_MP3 = OutputFormat.Mp3.toString();
    private static final String OUTPUT_BUCKET = "synth-books-buckets";
    private static final String SNS_TOPIC_ARN = "arn:aws:sns:eu-west-2:123456789012:synthesize-finish-topic";
    private static final Duration SYNTHESIS_TASK_POLL_INTERVAL = Duration.FIVE_SECONDS;
    private static final Duration SYNTHESIS_TASK_POLL_DELAY = Duration.TEN_SECONDS;

    public static void main(String... args) {
        StartSpeechSynthesisTaskRequest request = new StartSpeechSynthesisTaskRequest()
                .withOutputFormat(OUTPUT_FORMAT_MP3)
                .withText(PLAIN_TEXT)
                .withTextType(TextType.Text)
                .withVoiceId(VoiceId.Amy)
                .withOutputS3BucketName(OUTPUT_BUCKET)
                .withSnsTopicArn(SNS_TOPIC_ARN)
                .withEngine("neural");

        StartSpeechSynthesisTaskResult result = AMAZON_POLLY_CLIENT.startSpeechSynthesisTask(request);
        String taskId = result.getSynthesisTask().getTaskId();

        await().with()
                .pollInterval(SYNTHESIS_TASK_POLL_INTERVAL)
                .pollDelay(SYNTHESIS_TASK_POLL_DELAY)
                .atMost(SYNTHESIS_TASK_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                .until(
                        () -> getSynthesisTaskStatus(taskId).equals(TaskStatus.Completed.toString())
                );
    }

    private static SynthesisTask getSynthesisTask(String taskId) {
        GetSpeechSynthesisTaskRequest getSpeechSynthesisTaskRequest = new GetSpeechSynthesisTaskRequest()
                .withTaskId(taskId);
        GetSpeechSynthesisTaskResult result =AMAZON_POLLY_CLIENT.getSpeechSynthesisTask(getSpeechSynthesisTaskRequest);
        return result.getSynthesisTask();
    }

    private static String getSynthesisTaskStatus(String taskId) {
        GetSpeechSynthesisTaskRequest getSpeechSynthesisTaskRequest = new GetSpeechSynthesisTaskRequest()
                .withTaskId(taskId);
        GetSpeechSynthesisTaskResult result =AMAZON_POLLY_CLIENT.getSpeechSynthesisTask(getSpeechSynthesisTaskRequest);
        return result.getSynthesisTask().getTaskStatus();
    }

}
```

# 스피치 마크
<a name="SynthesizeSpeechMarksSample"></a>

다음 코드 샘플은 Java 기반 애플리케이션을 사용하여 입력된 텍스트의 스피치 마크를 합성하는 방법을 보여줍니다. 이 기능은 SynthesizeSpeech API를 사용합니다.

이 기능에 대한 자세한 내용은 [스피치 마크](speechmarks.md)을(를) 참조하세요.

해당 API에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html](https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html) API 참조를 참조하세요.

## SDK v2
<a name="synth-sdk-v2"></a>

```
/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   SPDX-License-Identifier: Apache-2.0
*/

package com.example.polly;

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.polly.PollyClient;
import software.amazon.awssdk.services.polly.model.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SpeechMarksSample {

    public static void main(String args[]) {

        PollyClient polly = PollyClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();

        speechMarksSample(polly) ;
        polly.close();
    }

    private static final String OUTPUT_FILE = "./speechMarks.json";
    public static void speechMarksSample(PollyClient client) {

        try {
            SynthesizeSpeechRequest speechMarksSampleRequest = SynthesizeSpeechRequest.builder()
                    .outputFormat(OutputFormat.JSON)
                    .speechMarkTypes(SpeechMarkType.VISEME, SpeechMarkType.WORD)
                    .voiceId(VoiceId.JOANNA)
                    .text("This is a sample text to be synthesized")
                    .build();
            try (FileOutputStream outputStream = new FileOutputStream(new File(OUTPUT_FILE))) {
                ResponseInputStream<SynthesizeSpeechResponse> synthesizeSpeechResponse = client
                        .synthesizeSpeech(speechMarksSampleRequest);
                byte[] buffer = new byte[2 * 1024];
                int readBytes;

                try (InputStream in = synthesizeSpeechResponse){
                    while ((readBytes = in.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, readBytes);
                    }
                }
            } catch (Exception e) {
                System.err.println("Exception caught: " + e);
            }

        } catch (PollyException e) {
            System.err.println("Exception caught: " + e);
            System.exit(1);
        }
    }

}
```

## SDK v1
<a name="synth-sdk-v1"></a>

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.OutputFormat;
import com.amazonaws.services.polly.model.SpeechMarkType;
import com.amazonaws.services.polly.model.SynthesizeSpeechRequest;
import com.amazonaws.services.polly.model.SynthesizeSpeechResult;
import com.amazonaws.services.polly.model.VoiceId;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
 
public class SynthesizeSpeechMarksSample {
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();
 
    public void synthesizeSpeechMarks() {
        String outputFileName = "/tmp/speechMarks.json";
 
        SynthesizeSpeechRequest synthesizeSpeechRequest = new SynthesizeSpeechRequest()
                .withOutputFormat(OutputFormat.Json)
                .withSpeechMarkTypes(SpeechMarkType.Viseme, SpeechMarkType.Word)
                .withVoiceId(VoiceId.Joanna)
                .withText("This is a sample text to be synthesized.");
 
        try (FileOutputStream outputStream = new FileOutputStream(new File(outputFileName))) {
            SynthesizeSpeechResult synthesizeSpeechResult = client.synthesizeSpeech(synthesizeSpeechRequest);
            byte[] buffer = new byte[2 * 1024];
            int readBytes;
 
            try (InputStream in = synthesizeSpeechResult.getAudioStream()){
                while ((readBytes = in.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, readBytes);
                }
            }
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# SynthesizeSpeech
<a name="SynthesizeSpeechSample"></a>

다음 Java 코드 샘플은 Java 기반 애플리케이션을 사용하여 스피치를 짧은 텍스트로 합성하여 거의 실시간으로 처리하는 방법을 보여줍니다.

자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html](https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html) API 참조를 참조하세요.

```
package com.amazonaws.polly.samples;
 
import com.amazonaws.services.polly.AmazonPolly;
import com.amazonaws.services.polly.AmazonPollyClientBuilder;
import com.amazonaws.services.polly.model.OutputFormat;
import com.amazonaws.services.polly.model.SynthesizeSpeechRequest;
import com.amazonaws.services.polly.model.SynthesizeSpeechResult;
import com.amazonaws.services.polly.model.VoiceId;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
 
public class SynthesizeSpeechSample {
    AmazonPolly client = AmazonPollyClientBuilder.defaultClient();
 
    public void synthesizeSpeech() {
        String outputFileName = "/tmp/speech.mp3";
 
        SynthesizeSpeechRequest synthesizeSpeechRequest = new SynthesizeSpeechRequest()
                .withOutputFormat(OutputFormat.Mp3)
                .withVoiceId(VoiceId.Joanna)
                .withText("This is a sample text to be synthesized.")
                .withEngine("neural");
 
        try (FileOutputStream outputStream = new FileOutputStream(new File(outputFileName))) {
            SynthesizeSpeechResult synthesizeSpeechResult = client.synthesizeSpeech(synthesizeSpeechRequest);
            byte[] buffer = new byte[2 * 1024];
            int readBytes;
 
            try (InputStream in = synthesizeSpeechResult.getAudioStream()){
                while ((readBytes = in.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, readBytes);
                }
            }
        } catch (Exception e) {
            System.err.println("Exception caught: " + e);
        }
    }
}
```

# Python 샘플
<a name="python-samples"></a>

다음 코드 샘플은 Python(boto3) 기반 애플리케이션을 사용하여 Amazon Polly에서 다양한 작업을 수행하는 방법을 보여줍니다. 이들 샘플은 전체 예제를 위한 것은 아니지만 [AWS SDK for Python (Boto)](https://aws.amazon.com/sdk-for-python/)를 사용하는 대규모 Python 애플리케이션에 포함될 수 있습니다.

**Topics**
+ [DeleteLexicon](DeleteLexiconPython.md)
+ [GetLexicon](GetLexiconSamplePython.md)
+ [ListLexicon](ListLexiconSamplePython.md)
+ [PutLexicon](PutLexiconSamplePython.md)
+ [StartSpeechSynthesisTask](StartSpeechSynthesisTaskSamplePython.md)
+ [SynthesizeSpeech](SynthesizeSpeechSamplePython.md)

# DeleteLexicon
<a name="DeleteLexiconPython"></a>

다음 Python 코드 예제는 AWS SDK for Python (Boto)를 사용하여 로컬 AWS 구성에 지정한 리전의 어휘를 삭제합니다. 이 예에서는 지정한 어휘만 삭제합니다. 실제로 어휘를 삭제하기 전에 계속 진행할 것인지 묻는 메시지가 표시됩니다.

다음 코드 예제는 AWS SDK 구성 파일에 저장된 기본 자격 증명을 사용합니다. 구성 파일 생성에 대한 자세한 내용은 [설정AWS CLI](setup-cli.md)을 참조하세요.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_DeleteLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_DeleteLexicon.html) API 참조를 참조하세요.

```
from argparse import ArgumentParser
from sys import version_info

from boto3 import Session
from botocore.exceptions import BotoCoreError, ClientError


# Define and parse the command line arguments
cli = ArgumentParser(description="DeleteLexicon example")
cli.add_argument("name", type=str, metavar="LEXICON_NAME")
arguments = cli.parse_args()

# Create a client using the credentials and region defined in the adminuser
# section of the AWS credentials and configuration files
session = Session(profile_name="adminuser")
polly = session.client("polly")

# Request confirmation
prompt = input if version_info >= (3, 0) else raw_input
proceed = prompt((u"This will delete the \"{0}\" lexicon,"
                  " do you want to proceed? [y,n]: ").format(arguments.name))

if proceed in ("y", "Y"):
    print(u"Deleting {0}...".format(arguments.name))

    try:
        # Request deletion of a lexicon by name
        response = polly.delete_lexicon(Name=arguments.name)
    except (BotoCoreError, ClientError) as error:
        # The service returned an error, exit gracefully
        cli.error(error)

    print("Done.")
else:
    print("Cancelled.")
```

# GetLexicon
<a name="GetLexiconSamplePython"></a>

다음 Python 코드는 AWS SDK for Python (Boto)를 사용하여 AWS 리전에 저장된 모든 어휘를 검색합니다. 이 예제는 어휘 이름을 명령줄 파라미터로 받아들이고 해당 어휘만 가져와서 로컬에 저장된 tmp 경로를 출력합니다.

다음 코드 예제는 AWS SDK 구성 파일에 저장된 기본 자격 증명을 사용합니다. 구성 파일 생성에 대한 자세한 내용은 [설정AWS CLI](setup-cli.md)을 참조하세요.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_GetLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_GetLexicon.html) API 참조를 참조하세요.

```
from argparse import ArgumentParser
from os import path
from tempfile import gettempdir

from boto3 import Session
from botocore.exceptions import BotoCoreError, ClientError

# Define and parse the command line arguments
cli = ArgumentParser(description="GetLexicon example")
cli.add_argument("name", type=str, metavar="LEXICON_NAME")
arguments = cli.parse_args()

# Create a client using the credentials and region defined in the adminuser
# section of the AWS credentials and configuration files
session = Session(profile_name="adminuser")
polly = session.client("polly")

print(u"Fetching {0}...".format(arguments.name))

try:
    # Fetch lexicon by name
    response = polly.get_lexicon(Name=arguments.name)
except (BotoCoreError, ClientError) as error:
    # The service returned an error, exit gracefully
    cli.error(error)

# Get the lexicon data from the response
lexicon = response.get("Lexicon", {})

# Access the lexicon's content
if "Content" in lexicon:
    output = path.join(gettempdir(), u"%s.pls" % arguments.name)
    print(u"Saving to %s..." % output)

    try:
        # Save the lexicon contents to a local file
        with open(output, "w") as pls_file:
            pls_file.write(lexicon["Content"])
    except IOError as error:
        # Could not write to file, exit gracefully
        cli.error(error)
else:
    # The response didn't contain lexicon data, exit gracefully
    cli.error("Could not fetch lexicons contents")

print("Done.")
```

# ListLexicon
<a name="ListLexiconSamplePython"></a>

다음 Python 코드 예제는 AWS SDK for Python (Boto)를 사용하여 로컬 AWS 구성에 지정된 리전의 계정에 있는 어휘를 목록으로 표시합니다. 구성 파일 생성에 대한 자세한 내용은 [설정AWS CLI](setup-cli.md)을 참조하세요.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_ListLexicons.html](https://docs.aws.amazon.com/polly/latest/dg/API_ListLexicons.html) API 참조를 참조하세요.

```
import sys

from boto3 import Session
from botocore.exceptions import BotoCoreError, ClientError

# Create a client using the credentials and region defined in the adminuser
# section of the AWS credentials and configuration files
session = Session(profile_name="adminuser")
polly = session.client("polly")

try:
    # Request the list of available lexicons
    response = polly.list_lexicons()
except (BotoCoreError, ClientError) as error:
    # The service returned an error, exit gracefully
    print(error)
    sys.exit(-1)

# Get the list of lexicons in the response
lexicons = response.get("Lexicons", [])
print("{0} lexicon(s) found".format(len(lexicons)))

# Output a formatted list of lexicons with some of the attributes
for lexicon in lexicons:
    print((u" - {Name} ({Attributes[LanguageCode]}), "
           "{Attributes[LexemesCount]} lexeme(s)").format(**lexicon))
```

# PutLexicon
<a name="PutLexiconSamplePython"></a>

다음 코드 샘플은 Python(boto3) 기반 애필리케이션을 사용하여 AWS 리전에 발음 어휘를 저장하는 방법을 보여줍니다. 

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_PutLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_PutLexicon.html) API 참조를 참조하세요.

다음 사항에 유의하세요.
+ 로컬 어휘 파일 이름과 저장된 어휘 이름을 제공하여 코드를 업데이트해야 합니다.
+ 이 예제에서는 `pls`라는 하위 디렉토리에 사전 파일이 생성되었다고 가정합니다. 경로를 적절히 업데이트해야 합니다.

다음 코드 예제는 AWS SDK 구성 파일에 저장된 기본 자격 증명을 사용합니다. 구성 파일 생성에 대한 자세한 내용은 [설정AWS CLI](setup-cli.md)을 참조하세요.

이 작업에 대한 자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_PutLexicon.html](https://docs.aws.amazon.com/polly/latest/dg/API_PutLexicon.html) API 참조를 참조하세요.



```
from argparse import ArgumentParser

from boto3 import Session
from botocore.exceptions import BotoCoreError, ClientError

# Define and parse the command line arguments
cli = ArgumentParser(description="PutLexicon example")
cli.add_argument("path", type=str, metavar="FILE_PATH")
cli.add_argument("-n", "--name", type=str, required=True,
                 metavar="LEXICON_NAME", dest="name")
arguments = cli.parse_args()

# Create a client using the credentials and region defined in the adminuser
# section of the AWS credentials and configuration files
session = Session(profile_name="adminuser")
polly = session.client("polly")

# Open the PLS lexicon file for reading
try:
    with open(arguments.path, "r") as lexicon_file:
        # Read the pls file contents
        lexicon_data = lexicon_file.read()

        # Store the PLS lexicon on the service.
        # If a lexicon with that name already exists,
        # its contents will be updated
        response = polly.put_lexicon(Name=arguments.name,
                                      Content=lexicon_data)
except (IOError, BotoCoreError, ClientError) as error:
    # Could not open/read the file or the service returned an error,
    # exit gracefully
    cli.error(error)

print(u"The \"{0}\" lexicon is now available for use.".format(arguments.name))
```



# StartSpeechSynthesisTask
<a name="StartSpeechSynthesisTaskSamplePython"></a>

다음 Python 코드 예제는 AWS SDK for Python (Boto)를 사용하여 로컬 AWS 구성에 지정된 리전의 계정에 있는 어휘를 목록으로 표시합니다. 구성 파일 생성에 대한 자세한 내용은 [설정AWS CLI](setup-cli.md)을 참조하세요.

자세한 내용은 [https://docs.aws.amazon.com/polly/latest/dg/API_StartSpeechSynthesisTask.html](https://docs.aws.amazon.com/polly/latest/dg/API_StartSpeechSynthesisTask.html) API 참조를 참조하세요.

```
import boto3
import time

polly_client = boto3.Session(
                aws_access_key_id='',                  
    aws_secret_access_key='',
    region_name='eu-west-2').client('polly')

response = polly_client.start_speech_synthesis_task(VoiceId='Joanna',
                OutputS3BucketName='synth-books-buckets',
                OutputS3KeyPrefix='key',
                OutputFormat='mp3', 
                Text='This is a sample text to be synthesized.',
                Engine='neural')

taskId = response['SynthesisTask']['TaskId']

print( "Task id is {} ".format(taskId))

task_status = polly_client.get_speech_synthesis_task(TaskId = taskId)

print(task_status)
```

# SynthesizeSpeech
<a name="SynthesizeSpeechSamplePython"></a>

다음 Python 코드 예제는 AWS SDK for Python (Boto)를 사용하여 스피치를 짧은 텍스트로 합성하여 거의 실시간으로 처리하는 방법을 보여줍니다. 자세한 내용은 [SynthesizeSpeech](API_SynthesizeSpeech.md) 작업에 대한 참조를 참조하세요.

이 예제에서는 짧은 일반 텍스트 문자열을 사용합니다. SSML 텍스트를 사용하여 출력을 더 세밀하게 제어할 수 있습니다. 자세한 내용은 [SSML 문서에서 스피치 생성](ssml.md) 섹션을 참조하세요.

```
import boto3

polly_client = boto3.Session(
                aws_access_key_id=,                     
    aws_secret_access_key=,
    region_name='us-west-2').client('polly')

response = polly_client.synthesize_speech(VoiceId='Joanna',
                OutputFormat='mp3', 
                Text = 'This is a sample text to be synthesized.',
                Engine = 'neural')

file = open('speech.mp3', 'wb')
file.write(response['AudioStream'].read())
file.close()
```

# Java 예제
<a name="examples-java"></a>

이 예제에서는 Amazon Polly를 사용하여 Java 기반 애플리케이션에서 스피치를 스트리밍하는 방법을 보여 줍니다. 이 예제에서는 [AWS SDK for Java](https://aws.amazon.com/documentation/sdk-for-java/)를 사용하여 목록에서 선택한 음성으로 지정된 텍스트를 읽습니다.

표시된 코드는 주요 작업을 다루지만 최소한의 오류 검사만 수행합니다. Amazon Polly에서 오류가 발생하면 애플리케이션이 종료됩니다.

이 예제 애플리케이션을 실행하려면 다음이 필요합니다.
+  Java 8 Development Kit(JDK) 
+  [AWS SDK for Java](https://aws.amazon.com/documentation/sdk-for-java/) 
+  [Apache Maven](http://maven.apache.org/) 

**애플리케이션을 테스트하려면**

1. JDK에 JAVA\$1HOME 환경 변수가 설정되어 있어야 합니다.

   예를 들어, Windows의 `C:\Program Files\Java\jdk1.8.0_121`에 JDK 1.8.0\$1121을 설치한 경우 명령 프롬프트에 다음을 입력합니다. 

   ```
   set JAVA_HOME=""C:\Program Files\Java\jdk1.8.0_121""
   ```

   Linux의 `/usr/lib/jvm/java8-openjdk-amd64`에 JDK 1.8.0\$1121을 설치한 경우 명령 프롬프트에 다음을 입력합니다.

   ```
   export JAVA_HOME=/usr/lib/jvm/java8-openjdk-amd64
   ```

1. 명령줄에서 Maven을 실행하도록 Maven 환경 변수를 설정합니다.

   예를 들어 Windows의 `C:\Program Files\apache-maven-3.3.9`에 Maven 3.3.9를 설치한 경우 다음을 입력합니다.

   ```
   set M2_HOME=""C:\Program Files\apache-maven-3.3.9""
   set M2=%M2_HOME%\bin
   set PATH=%M2%;%PATH%
   ```

   Linux의 `/home/ec2-user/opt/apache-maven-3.3.9`에 Maven 3.3.9를 설치한 경우 다음을 입력합니다.

   ```
   export M2_HOME=/home/ec2-user/opt/apache-maven-3.3.9
   export M2=$M2_HOME/bin
   export PATH=$M2:$PATH
   ```

1. 이름이 `polly-java-demo`인 디렉터리를 새로 생성합니다.

1. `polly-java-demo` 디렉터리에 이름이 `pom.xml`인 파일을 생성하고 그 안에 다음 코드를 붙여 넣습니다.

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" 
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   	<modelVersion>4.0.0</modelVersion>
   	<groupId>com.amazonaws.polly</groupId>
   	<artifactId>java-demo</artifactId>
   	<version>0.0.1-SNAPSHOT</version>
   
   	<dependencies>
   		<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-polly -->
   		<dependency>
   			<groupId>com.amazonaws</groupId>
   			<artifactId>aws-java-sdk-polly</artifactId>
   			<version>1.11.77</version>
   		</dependency>
   		<!-- https://mvnrepository.com/artifact/com.googlecode.soundlibs/jlayer -->
   		<dependency>
   			<groupId>com.googlecode.soundlibs</groupId>
   			<artifactId>jlayer</artifactId>
   			<version>1.0.1-1</version>
   		</dependency>
   
   	</dependencies>
   	<build>
   		<plugins>
   			<plugin>
   				<groupId>org.codehaus.mojo</groupId>
   				<artifactId>exec-maven-plugin</artifactId>
   				<version>1.2.1</version>
   				<executions>
   					<execution>
   						<goals>
   							<goal>java</goal>
   						</goals>
   					</execution>
   				</executions>
   				<configuration>
   					<mainClass>com.amazonaws.demos.polly.PollyDemo</mainClass>
   				</configuration>
   			</plugin>
   		</plugins>
   	</build>
   </project>
   ```

1.  `src/main/java/com/amazonaws/demos`에 이름이 `polly`인 디렉터리를 새로 생성합니다.

1.  `polly` 디렉터리에서 이름이 `PollyDemo.java`인 새 Java 소스 파일을 만들고 그 안에 다음 코드를 붙여 넣습니다.

   ```
   package com.amazonaws.demos.polly;
   
   import java.io.IOException;
   import java.io.InputStream;
   
   import com.amazonaws.ClientConfiguration;
   import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
   import com.amazonaws.regions.Region;
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.polly.AmazonPollyClient;
   import com.amazonaws.services.polly.model.DescribeVoicesRequest;
   import com.amazonaws.services.polly.model.DescribeVoicesResult;
   import com.amazonaws.services.polly.model.OutputFormat;
   import com.amazonaws.services.polly.model.SynthesizeSpeechRequest;
   import com.amazonaws.services.polly.model.SynthesizeSpeechResult;
   import com.amazonaws.services.polly.model.Voice;
   
   import javazoom.jl.player.advanced.AdvancedPlayer;
   import javazoom.jl.player.advanced.PlaybackEvent;
   import javazoom.jl.player.advanced.PlaybackListener;
   
   public class PollyDemo {
   
   	private final AmazonPollyClient polly;
   	private final Voice voice;
   	private static final String SAMPLE = "Congratulations. You have successfully built this working demo 
   	of Amazon Polly in Java. Have fun building voice enabled apps with Amazon Polly (that's me!), and always 
   	look at the AWS website for tips and tricks on using Amazon Polly and other great services from AWS";
   
   	public PollyDemo(Region region) {
   		// create an Amazon Polly client in a specific region
   		polly = new AmazonPollyClient(new DefaultAWSCredentialsProviderChain(), 
   		new ClientConfiguration());
   		polly.setRegion(region);
   		// Create describe voices request.
   		DescribeVoicesRequest describeVoicesRequest = new DescribeVoicesRequest();
   
   		// Synchronously ask Amazon Polly to describe available TTS voices.
   		DescribeVoicesResult describeVoicesResult = polly.describeVoices(describeVoicesRequest);
   		voice = describeVoicesResult.getVoices().get(0);
   	}
   
   	public InputStream synthesize(String text, OutputFormat format) throws IOException {
   		SynthesizeSpeechRequest synthReq = 
   		new SynthesizeSpeechRequest().withText(text).withVoiceId(voice.getId())
   				.withOutputFormat(format).withEngine("neural");
   		SynthesizeSpeechResult synthRes = polly.synthesizeSpeech(synthReq);
   
   		return synthRes.getAudioStream();
   	}
   
   	public static void main(String args[]) throws Exception {
   		//create the test class
   		PollyDemo helloWorld = new PollyDemo(Region.getRegion(Regions.US_EAST_1));
   		//get the audio stream
   		InputStream speechStream = helloWorld.synthesize(SAMPLE, OutputFormat.Mp3);
   
   		//create an MP3 player
   		AdvancedPlayer player = new AdvancedPlayer(speechStream,
   				javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice());
   
   		player.setPlayBackListener(new PlaybackListener() {
   			@Override
   			public void playbackStarted(PlaybackEvent evt) {
   				System.out.println("Playback started");
   				System.out.println(SAMPLE);
   			}
   			
   			@Override
   			public void playbackFinished(PlaybackEvent evt) {
   				System.out.println("Playback finished");
   			}
   		});
   		
   		
   		// play it!
   		player.play();
   		
   	}
   }
   ```

1.  `polly-java-demo` 디렉터리로 돌아가서 데모를 정리하고, 컴파일하고, 실행합니다.

   ```
   mvn clean compile exec:java
   ```

# Python 예제(HTML5 클라이언트 및 Python 서버)
<a name="examples-python"></a>

이 예제 애플리케이션은 다음과 같은 요소로 구성됩니다.
+ HTTP 청크 전송 코딩을 사용하는 HTTP 1.1 서버([청크 전송 코딩](https://tools.ietf.org/html/rfc2616#section-3.6.1) 참조)
+ HTTP 1.1 서버와 상호 작용하는 간단한 HTML5 사용자 인터페이스(아래 그림 참조)

     
![\[Text-to-speech interface with voice selection dropdown and text input field.\]](http://docs.aws.amazon.com/ko_kr/polly/latest/dg/images/app1-10.png)

이 예제의 목표는 Amazon Polly를 사용하여 브라우저 기반 HTML5 애플리케이션에서 스피치를 스트리밍하는 방법을 보여주는 것입니다. 응답성이 중요한 요소인 사용 사례(예: 대화 시스템, 스크린 리더 등)에서는 텍스트가 합성될 때 Amazon Polly에서 생성된 오디오 스트림을 사용하는 것이 좋습니다.

이 예제 애플리케이션을 실행하려면 다음이 필요합니다.
+ HTML5 및 EcmaScript5 표준을 준수하는 웹 브라우저(예: Chrome 23.0 이상, Firefox 21.0 이상, Internet Explorer 9.0 이상)
+ Python 버전 3.0 이상

**애플리케이션을 테스트하려면**

1. 서버 코드를 `server.py`로 저장합니다. 코드는 [Python 예제: Python 서버 코드(server.py)](example-Python-server-code.md)을(를) 참조하세요.

1. HTML5 클라이언트 코드를 `index.html`로 저장합니다. 코드는 [Python 예제: HTML5 사용자 인터페이스(index.html)](example-html-app.md)을(를) 참조하세요.

1. server.py를 저장한 경로에서 다음 명령을 실행하여 애플리케이션을 시작합니다(일부 시스템에서는 명령을 실행할 때 `python` 대신 `python3`를 사용해야 할 수도 있음).

   ```
   $ python  server.py
   ```

   애플리케이션이 시작되면 터미널에 URL이 표시됩니다.

1. 터미널에 표시된 URL을 웹 브라우저에서 엽니다.

   파라미터로 사용할 애플리케이션 서버의 주소와 포트를 `server.py`로 전달할 수 있습니다. 자세한 내용을 보려면 `python server.py -h`을(를) 실행하세요.

1. 스피치를 들으려면 목록에서 음성을 선택하고 텍스트를 입력한 다음 **읽기**를 선택합니다. Amazon Polly가 사용 가능한 첫 번째 오디오 데이터 청크를 전송하는 즉시 스피치가 재생되기 시작합니다.

1. 애플리케이션 테스트를 마치고 Python 서버를 중지하려면 서버를 실행하는 터미널에서 Ctrl\$1C를 누릅니다.

**참고**  
서버에서 AWS SDK for Python (Boto)를 사용하여 Boto3 클라이언트를 만듭니다. 클라이언트는 컴퓨터의 AWS 구성 파일에 저장된 자격 증명을 사용하여 Amazon Polly에 대한 요청에 서명하고 인증합니다. AWS 구성 파일을 생성하고 자격 증명을 저장하는 방법에 대한 자세한 내용은 *AWS Command Line Interface 사용 설명서*의 [구성을 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) 참조하세요.

# Python 예제: HTML5 사용자 인터페이스(index.html)
<a name="example-html-app"></a>

이 섹션에서는 [Python 예제(HTML5 클라이언트 및 Python 서버)](examples-python.md)에 설명된 HTML5 클라이언트를 위한 코드를 제공합니다.

```
<html>

<head>
    <title>Text-to-Speech Example Application</title>
    <script>
        /*
         * This sample code requires a web browser with support for both the
         * HTML5 and ECMAScript 5 standards; the following is a non-comprehensive
         * list of compliant browsers and their minimum version:
         *
         * - Chrome 23.0+
         * - Firefox 21.0+
         * - Internet Explorer 9.0+
         * - Edge 12.0+
         * - Opera 15.0+
         * - Safari 6.1+
         * - Android (stock web browser) 4.4+
         * - Chrome for Android 51.0+
         * - Firefox for Android 48.0+
         * - Opera Mobile 37.0+
         * - iOS (Safari Mobile and Chrome) 3.2+
         * - Internet Explorer Mobile 10.0+
         * - Blackberry Browser 10.0+
         */

        // Mapping of the OutputFormat parameter of the SynthesizeSpeech API
        // and the audio format strings understood by the browser
        var AUDIO_FORMATS = {
            'ogg_vorbis': 'audio/ogg',
            'mp3': 'audio/mpeg',
            'pcm': 'audio/wave; codecs=1'
        };

        /**
         * Handles fetching JSON over HTTP
         */
        function fetchJSON(method, url, onSuccess, onError) {
            var request = new XMLHttpRequest();
            request.open(method, url, true);
            request.onload = function () {
                // If loading is complete
                if (request.readyState === 4) {
                    // if the request was successful
                    if (request.status === 200) {
                        var data;

                        // Parse the JSON in the response
                        try {
                            data = JSON.parse(request.responseText);
                        } catch (error) {
                            onError(request.status, error.toString());
                        }

                        onSuccess(data);
                    } else {
                        onError(request.status, request.responseText)
                    }
                }
            };

            request.send();
        }

        /**
         * Returns a list of audio formats supported by the browser
         */
        function getSupportedAudioFormats(player) {
            return Object.keys(AUDIO_FORMATS)
                .filter(function (format) {
                    var supported = player.canPlayType(AUDIO_FORMATS[format]);
                    return supported === 'probably' || supported === 'maybe';
                });
        }

        // Initialize the application when the DOM is loaded and ready to be
        // manipulated
        document.addEventListener("DOMContentLoaded", function () {
            var input = document.getElementById('input'),
                voiceMenu = document.getElementById('voice'),
                text = document.getElementById('text'),
                player = document.getElementById('player'),
                submit = document.getElementById('submit'),
                supportedFormats = getSupportedAudioFormats(player);

            // Display a message and don't allow submitting the form if the
            // browser doesn't support any of the available audio formats
            if (supportedFormats.length === 0) {
                submit.disabled = true;
                alert('The web browser in use does not support any of the' +
                      ' available audio formats. Please try with a different' +
                      ' one.');
            }

            // Play the audio stream when the form is submitted successfully
            input.addEventListener('submit', function (event) {
                // Validate the fields in the form, display a message if
                // unexpected values are encountered
                if (voiceMenu.selectedIndex <= 0 || text.value.length === 0) {
                    alert('Please fill in all the fields.');
                } else {
                    var selectedVoice = voiceMenu
                                            .options[voiceMenu.selectedIndex]
                                            .value;

                    // Point the player to the streaming server
                    player.src = '/read?voiceId=' +
                        encodeURIComponent(selectedVoice) +
                        '&text=' + encodeURIComponent(text.value) +
                        '&outputFormat=' + supportedFormats[0];
                    player.play();
                }

                // Stop the form from submitting,
                // Submitting the form is allowed only if the browser doesn't
                // support Javascript to ensure functionality in such a case
                event.preventDefault();
            });

            // Load the list of available voices and display them in a menu
            fetchJSON('GET', '/voices',
                // If the request succeeds
                function (voices) {
                    var container = document.createDocumentFragment();

                    // Build the list of options for the menu
                    voices.forEach(function (voice) {
                        var option = document.createElement('option');
                        option.value = voice['Id'];
                        option.innerHTML = voice['Name'] + ' (' +
                            voice['Gender'] + ', ' +
                            voice['LanguageName'] + ')';
                        container.appendChild(option);
                    });

                    // Add the options to the menu and enable the form field
                    voiceMenu.appendChild(container);
                    voiceMenu.disabled = false;
                },
                // If the request fails
                function (status, response) {
                    // Display a message in case loading data from the server
                    // fails
                    alert(status + ' - ' + response);
                });
        });

    </script>
    <style>
        #input {
            min-width: 100px;
            max-width: 600px;
            margin: 0 auto;
            padding: 50px;
        }

        #input div {
            margin-bottom: 20px;
        }

        #text {
            width: 100%;
            height: 200px;
            display: block;
        }

        #submit {
            width: 100%;
        }
    </style>
</head>

<body>
    <form id="input" method="GET" action="/read">
        <div>
            <label for="voice">Select a voice:</label>
            <select id="voice" name="voiceId" disabled>
                <option value="">Choose a voice...</option>
            </select>
        </div>
        <div>
            <label for="text">Text to read:</label>
            <textarea id="text" maxlength="1000" minlength="1" name="text"
                    placeholder="Type some text here..."></textarea>
        </div>
        <input type="submit" value="Read" id="submit" />
    </form>
    <audio id="player"></audio>
</body>

</html>
```

# Python 예제: Python 서버 코드(server.py)
<a name="example-Python-server-code"></a>

이 섹션에서는 [Python 예제(HTML5 클라이언트 및 Python 서버)](examples-python.md)에 설명된 Python 서버의 코드를 제공합니다.

```
""" 
Example Python 2.7+/3.3+ Application

This application consists of a HTTP 1.1 server using the HTTP chunked transfer
coding (https://tools.ietf.org/html/rfc2616#section-3.6.1) and a minimal HTML5
user interface that interacts with it.

The goal of this example is to start streaming the speech to the client (the
HTML5 web UI) as soon as the first consumable chunk of speech is returned in
order to start playing the audio as soon as possible.
For use cases where low latency and responsiveness are strong requirements,
this is the recommended approach.

The service documentation contains examples for non-streaming use cases where
waiting for the speech synthesis to complete and fetching the whole audio stream
at once are an option.

To test the application, run 'python server.py' and then open the URL
displayed in the terminal in a web browser (see index.html for a list of
supported browsers). The address and port for the server can be passed as
parameters to server.py. For more information, run: 'python server.py -h'
"""
from argparse import ArgumentParser
from collections import namedtuple
from contextlib import closing
from io import BytesIO
from json import dumps as json_encode
import os
import sys

if sys.version_info >= (3, 0):
    from http.server import BaseHTTPRequestHandler, HTTPServer
    from socketserver import ThreadingMixIn
    from urllib.parse import parse_qs
else:
    from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
    from SocketServer import ThreadingMixIn
    from urlparse import parse_qs

from boto3 import Session
from botocore.exceptions import BotoCoreError, ClientError

ResponseStatus = namedtuple("HTTPStatus",
                            ["code", "message"])

ResponseData = namedtuple("ResponseData",
                          ["status", "content_type", "data_stream"])

# Mapping the output format used in the client to the content type for the
# response
AUDIO_FORMATS = {"ogg_vorbis": "audio/ogg",
                 "mp3": "audio/mpeg",
                 "pcm": "audio/wave; codecs=1"}
CHUNK_SIZE = 1024
HTTP_STATUS = {"OK": ResponseStatus(code=200, message="OK"),
               "BAD_REQUEST": ResponseStatus(code=400, message="Bad request"),
               "NOT_FOUND": ResponseStatus(code=404, message="Not found"),
               "INTERNAL_SERVER_ERROR": ResponseStatus(code=500, message="Internal server error")}
PROTOCOL = "http"
ROUTE_INDEX = "/index.html"
ROUTE_VOICES = "/voices"
ROUTE_READ = "/read"


# Create a client using the credentials and region defined in the adminuser
# section of the AWS credentials and configuration files
session = Session(profile_name="adminuser")
polly = session.client("polly")


class HTTPStatusError(Exception):
    """Exception wrapping a value from http.server.HTTPStatus"""

    def __init__(self, status, description=None):
        """
        Constructs an error instance from a tuple of
        (code, message, description), see http.server.HTTPStatus
        """
        super(HTTPStatusError, self).__init__()
        self.code = status.code
        self.message = status.message
        self.explain = description


class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """An HTTP Server that handle each request in a new thread"""
    daemon_threads = True


class ChunkedHTTPRequestHandler(BaseHTTPRequestHandler):
    """"HTTP 1.1 Chunked encoding request handler"""
    # Use HTTP 1.1 as 1.0 doesn't support chunked encoding
    protocol_version = "HTTP/1.1"

    def query_get(self, queryData, key, default=""):
        """Helper for getting values from a pre-parsed query string"""
        return queryData.get(key, [default])[0]

    def do_GET(self):
        """Handles GET requests"""

        # Extract values from the query string
        path, _, query_string = self.path.partition('?')
        query = parse_qs(query_string)

        response = None

        print(u"[START]: Received GET for %s with query: %s" % (path, query))

        try:
            # Handle the possible request paths
            if path == ROUTE_INDEX:
                response = self.route_index(path, query)
            elif path == ROUTE_VOICES:
                response = self.route_voices(path, query)
            elif path == ROUTE_READ:
                response = self.route_read(path, query)
            else:
                response = self.route_not_found(path, query)

            self.send_headers(response.status, response.content_type)
            self.stream_data(response.data_stream)

        except HTTPStatusError as err:
            # Respond with an error and log debug
            # information
            if sys.version_info >= (3, 0):
                self.send_error(err.code, err.message, err.explain)
            else:
                self.send_error(err.code, err.message)

            self.log_error(u"%s %s %s - [%d] %s", self.client_address[0],
                           self.command, self.path, err.code, err.explain)

        print("[END]")

    def route_not_found(self, path, query):
        """Handles routing for unexpected paths"""
        raise HTTPStatusError(HTTP_STATUS["NOT_FOUND"], "Page not found")

    def route_index(self, path, query):
        """Handles routing for the application's entry point'"""
        try:
            return ResponseData(status=HTTP_STATUS["OK"], content_type="text_html",
                                # Open a binary stream for reading the index
                                # HTML file
                                data_stream=open(os.path.join(sys.path[0],
                                                              path[1:]), "rb"))
        except IOError as err:
            # Couldn't open the stream
            raise HTTPStatusError(HTTP_STATUS["INTERNAL_SERVER_ERROR"],
                                  str(err))

    def route_voices(self, path, query):
        """Handles routing for listing available voices"""
        params = {}
        voices = []

        while True:
            try:
                # Request list of available voices, if a continuation token
                # was returned by the previous call then use it to continue
                # listing
                response = polly.describe_voices(**params)
            except (BotoCoreError, ClientError) as err:
                # The service returned an error
                raise HTTPStatusError(HTTP_STATUS["INTERNAL_SERVER_ERROR"],
                                      str(err))

            # Collect all the voices
            voices.extend(response.get("Voices", []))

            # If a continuation token was returned continue, stop iterating
            # otherwise
            if "NextToken" in response:
                params = {"NextToken": response["NextToken"]}
            else:
                break

        json_data = json_encode(voices)
        bytes_data = bytes(json_data, "utf-8") if sys.version_info >= (3, 0) \
            else bytes(json_data)

        return ResponseData(status=HTTP_STATUS["OK"],
                            content_type="application/json",
                            # Create a binary stream for the JSON data
                            data_stream=BytesIO(bytes_data))

    def route_read(self, path, query):
        """Handles routing for reading text (speech synthesis)"""
        # Get the parameters from the query string
        text = self.query_get(query, "text")
        voiceId = self.query_get(query, "voiceId")
        outputFormat = self.query_get(query, "outputFormat")

        # Validate the parameters, set error flag in case of unexpected
        # values
        if len(text) == 0 or len(voiceId) == 0 or \
                outputFormat not in AUDIO_FORMATS:
            raise HTTPStatusError(HTTP_STATUS["BAD_REQUEST"],
                                  "Wrong parameters")
        else:
            try:
                # Request speech synthesis
                response = polly.synthesize_speech(Text=text,
                                                    VoiceId=voiceId,
                                                    OutputFormat=outputFormat,
                                                    Engine="neural")
            except (BotoCoreError, ClientError) as err:
                # The service returned an error
                raise HTTPStatusError(HTTP_STATUS["INTERNAL_SERVER_ERROR"],
                                      str(err))

            return ResponseData(status=HTTP_STATUS["OK"],
                                content_type=AUDIO_FORMATS[outputFormat],
                                # Access the audio stream in the response
                                data_stream=response.get("AudioStream"))

    def send_headers(self, status, content_type):
        """Send out the group of headers for a successful request"""
        # Send HTTP headers
        self.send_response(status.code, status.message)
        self.send_header('Content-type', content_type)
        self.send_header('Transfer-Encoding', 'chunked')
        self.send_header('Connection', 'close')
        self.end_headers()

    def stream_data(self, stream):
        """Consumes a stream in chunks to produce the response's output'"""
        print("Streaming started...")

        if stream:
            # Note: Closing the stream is important as the service throttles on
            # the number of parallel connections. Here we are using
            # contextlib.closing to ensure the close method of the stream object
            # will be called automatically at the end of the with statement's
            # scope.
            with closing(stream) as managed_stream:
                # Push out the stream's content in chunks
                while True:
                    data = managed_stream.read(CHUNK_SIZE)
                    self.wfile.write(b"%X\r\n%s\r\n" % (len(data), data))

                    # If there's no more data to read, stop streaming
                    if not data:
                        break

                # Ensure any buffered output has been transmitted and close the
                # stream
                self.wfile.flush()

            print("Streaming completed.")
        else:
            # The stream passed in is empty
            self.wfile.write(b"0\r\n\r\n")
            print("Nothing to stream.")

# Define and parse the command line arguments
cli = ArgumentParser(description='Example Python Application')
cli.add_argument(
    "-p", "--port", type=int, metavar="PORT", dest="port", default=8000)
cli.add_argument(
    "--host", type=str, metavar="HOST", dest="host", default="localhost")
arguments = cli.parse_args()

# If the module is invoked directly, initialize the application
if __name__ == '__main__':
    # Create and configure the HTTP server instance
    server = ThreadedHTTPServer((arguments.host, arguments.port),
                                ChunkedHTTPRequestHandler)
    print("Starting server, use <Ctrl-C> to stop...")
    print(u"Open {0}://{1}:{2}{3} in a web browser.".format(PROTOCOL,
                                                            arguments.host,
                                                            arguments.port,
                                                            ROUTE_INDEX))

    try:
        # Listen for requests indefinitely
        server.serve_forever()
    except KeyboardInterrupt:
        # A request to terminate has been received, stop the server
        print("\nShutting down...")
        server.socket.close()
```

# iOS 예제
<a name="examples-ios"></a>

다음 예제에서는 Amazon Polly용 iOS SDK를 사용하여 음성 목록에서 선택한 음성으로 지정된 텍스트를 읽습니다.

여기에 표시된 코드는 주요 작업을 다루지만 오류는 처리하지 않습니다. 전체 코드는 [AWS Mobile SDK for iOS Amazon Polly 데모](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/Polly-Sample/Swift)를 참조하세요.

**초기화**  


```
// Region of Amazon Polly.
let AwsRegion = AWSRegionType.usEast1
 
// Cognito pool ID. Pool needs to be unauthenticated pool with
// Amazon Polly permissions.
let CognitoIdentityPoolId = "YourCognitoIdentityPoolId"
 
// Initialize the Amazon Cognito credentials provider.
let credentialProvider = AWSCognitoCredentialsProvider(regionType: AwsRegion, identityPoolId: CognitoIdentityPoolId)

// Create an audio player
var audioPlayer = AVPlayer()
```

**사용 가능한 음성 목록 가져오기**  


```
// Use the configuration as default
AWSServiceManager.default().defaultServiceConfiguration = configuration

// Get all the voices (no parameters specified in input) from Amazon Polly
// This creates an async task.
let task = AWSPolly.default().describeVoices(AWSPollyDescribeVoicesInput())
 
// When the request is done, asynchronously do the following block
// (we ignore all the errors, but in a real-world scenario they need
// to be handled)
task.continue(successBlock: { (awsTask: AWSTask) -> Any? in
      // awsTask.result is an instance of AWSPollyDescribeVoicesOutput in
      // case of the "describeVoices" method
      let voices = (awsTask.result! as AWSPollyDescribeVoicesOutput).voices
 
      return nil
})
```

**스피치 합성**  


```
// First, Amazon Polly requires an input, which we need to prepare.
// Again, we ignore the errors, however this should be handled in
// real applications. Here we are using the URL Builder Request,
// since in order to make the synthesis quicker we will pass the
// presigned URL to the system audio player.
let input = AWSPollySynthesizeSpeechURLBuilderRequest()

// Text to synthesize
input.text = "Sample text"

// We expect the output in MP3 format
input.outputFormat = AWSPollyOutputFormat.mp3

// Choose the voice ID
input.voiceId = AWSPollyVoiceId.joanna

// Create an task to synthesize speech using the given synthesis input
let builder = AWSPollySynthesizeSpeechURLBuilder.default().getPreSignedURL(input)

// Request the URL for synthesis result
builder.continueOnSuccessWith(block: { (awsTask: AWSTask<NSURL>) -> Any? in
	// The result of getPresignedURL task is NSURL.
	// Again, we ignore the errors in the example.
	let url = awsTask.result!

	// Try playing the data using the system AVAudioPlayer
	self.audioPlayer.replaceCurrentItem(with: AVPlayerItem(url: url as URL))
	self.audioPlayer.play()

	return nil
})
```

# Android 예제
<a name="examples-android"></a>

다음 예제에서는 Amazon Polly용 Android SDK를 사용하여 음성 목록에서 선택한 음성으로 지정된 텍스트를 읽습니다.

여기에 표시된 코드는 주요 작업을 다루지만 오류는 처리하지 않습니다. 전체 코드는 [AWS Mobile SDK for Android Amazon Polly 데모](https://github.com/awslabs/aws-sdk-android-samples/tree/master/PollyDemo)를 참조하세요.

**초기화**  


```
// Cognito pool ID. Pool needs to be unauthenticated pool with
// Amazon Polly permissions.
String COGNITO_POOL_ID = "YourCognitoIdentityPoolId";

// Region of Amazon Polly.
Regions MY_REGION = Regions.US_EAST_1;
 
// Initialize the Amazon Cognito credentials provider.
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
        getApplicationContext(),
        COGNITO_POOL_ID,
        MY_REGION
);

// Create a client that supports generation of presigned URLs.
AmazonPollyPresigningClient client = new AmazonPollyPresigningClient(credentialsProvider);
```

**사용 가능한 음성 목록 가져오기**  


```
// Create describe voices request.
DescribeVoicesRequest describeVoicesRequest = new DescribeVoicesRequest();

// Synchronously ask Amazon Polly to describe available TTS voices.
DescribeVoicesResult describeVoicesResult = client.describeVoices(describeVoicesRequest);
List<Voice> voices = describeVoicesResult.getVoices();
```

**오디오 스트림용 URL 가져오기**  


```
// Create speech synthesis request.
SynthesizeSpeechPresignRequest synthesizeSpeechPresignRequest =
        new SynthesizeSpeechPresignRequest()
        // Set the text to synthesize.
        .withText("Hello world!")
        // Select voice for synthesis.
        .withVoiceId(voices.get(0).getId()) // "Joanna"
        // Set format to MP3.
        .withOutputFormat(OutputFormat.Mp3);

// Get the presigned URL for synthesized speech audio stream.
URL presignedSynthesizeSpeechUrl =
        client.getPresignedSynthesizeSpeechUrl(synthesizeSpeechPresignRequest);
```

**합성 스피치 재생**  


```
// Use MediaPlayer: https://developer.android.com/guide/topics/media/mediaplayer.html

// Create a media player to play the synthesized audio stream.
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

try {
    // Set media player's data source to previously obtained URL.
    mediaPlayer.setDataSource(presignedSynthesizeSpeechUrl.toString());
} catch (IOException e) {
    Log.e(TAG, "Unable to set data source for the media player! " + e.getMessage());
}

// Prepare the MediaPlayer asynchronously (since the data source is a network stream).
mediaPlayer.prepareAsync();

// Set the callback to start the MediaPlayer when it's prepared.
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
});

// Set the callback to release the MediaPlayer after playback is completed.
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
	mp.release();
    }
});
```