

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 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 任务。这些示例不是完整示例，但可以包含在使用 [适用于 Java 的 AWS SDK](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 的应用程序来合成长语音（多达十万个计费字符）并将其直接存储在 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 软件开发工具包配置文件中的默认凭证。有关创建配置文件的信息，请参阅 [设置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 软件开发工具包配置文件中的默认凭证。有关创建配置文件的信息，请参阅 [设置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 软件开发工具包配置文件中的默认凭证。有关创建配置文件的信息，请参阅 [设置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 的应用程序流式传输语音。该示例使用[适用于 Java 的 AWS SDK](https://aws.amazon.com/documentation/sdk-for-java/)，借助从列表中选择的语音来读取指定文本。

显示的代码涵盖主要任务，但只能进行微小错误检查。如果 Amazon Polly 遇到错误，应用程序将终止。

要运行此示例应用程序，您需要以下条件：
+  Java 8 Java 开发工具包 (JDK) 
+  [适用于 Java 的 AWS SDK](https://aws.amazon.com/documentation/sdk-for-java/) 
+  [ – Apache Maven](http://maven.apache.org/) 

**测试应用程序**

1. 确保针对 JDK 设置了 JAVA\$1HOME 环境变量。

   例如，如果您在 Windows 上安装了 JDK 1.8.0\$1121（路径为 `C:\Program Files\Java\jdk1.8.0_121`），则您应在命令提示符下键入以下内容：

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

   如果您在 Linux 中安装了 JDK 1.8.0\$1121（路径为`/usr/lib/jvm/java8-openjdk-amd64`），您可以在命令提示符下键入以下内容：

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

1. 设置 Maven 环境变量以便从命令行中运行 Maven。

   例如，如果您在 Windows 上安装了 Maven 3.3.9（路径为 `C:\Program Files\apache-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 上安装了 Maven 3.3.9（路径为 `/home/ec2-user/opt/apache-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.  在 `polly` 创建名为 `src/main/java/com/amazonaws/demos` 的新目录。

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/zh_cn/polly/latest/dg/images/app1-10.png)

此示例的目的是展示如何使用 Amazon Polly 从基于浏览器的 HTML5 应用程序流式传输语音。推荐将随着文本的合成而使用 Amazon Polly 制作的音频流的方法用于注重响应性的用例（例如对话系统、屏幕阅读器等）。

要运行此示例应用程序，您需要以下条件：
+ 符合 HTML5 和 EcmaScript 5 标准的 Web 浏览器（例如 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 的路径运行以下命令以启动应用程序（在某些系统中，在运行命令时，您需要使用 `python3` 而不是 `python`）。

   ```
   $ python  server.py
   ```

   在应用程序启动后，终端会显示 URL。

1. 在 Web 浏览器中打开在终端中显示的 URL。

   您可以通过向应用程序服务器传输地址和端口以用作 `server.py` 的参数。有关更多信息，请运行 `python server.py -h`。

1. 要收听语音，请从列表中选择一个语音，键入一些文本，然后选择 **Read**。在 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>

本节提供中所述的 HTML5 客户端代码[Python 示例（HTML5 客户端和 Python 服务器）](examples-python.md)。

```
<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 软件开发工具包，借助从语音列表中选择的语音来读取指定文本。

此处显示的代码涵盖主要任务，但不处理错误。有关完整代码，请参阅[AWS Mobile SDK for iOSAmazon 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 软件开发工具包，借助从列表中选择的语音读取指定文本。

此处显示的代码涵盖主要任务，但不处理错误。有关完整代码，请参阅[适用于 Android 的 AWS Mobile SDKAmazon 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();
    }
});
```