- 示例工程
- 教程
- 后端
【免费下载链接】aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
本文基于aws-doc-sdk-examples仓库中javav2/example_code/polly/目录的 README 及其配套源码,系统讲解如何使用 AWS SDK for Java 2.x 调用 Amazon Polly(文本转语音 TTS 云服务)完成查询音色、列出发音词典(Lexicon)以及合成并播放 MP3 语音等核心操作。读完后,你可以直接复制仓库中的示例代码,在本地完成 Amazon Polly 的构建、运行与测试验证。
示例目录总览
Amazon Polly 是一个文本转语音(Text-to-Speech, TTS)云服务,可将文本转换为接近真人的语音。javav2/example_code/polly/目录是仓库中针对该服务的 Java 2.x 示例模块,其结构如下:
- README:示例说明文档,列出前置条件、可用示例与测试方式;
- pom.xml:Maven 构建与依赖配置;
- metadata.yaml:声明四个源码文件均关联 Polly 服务;
- DescribeVoicesSample.java:按语言代码查询可用音色;
- ListLexicons.java:列出当前账户下的发音词典;
- PollyDemo.java:完整演示“查音色 → 合成语音 → 本地播放”的端到端流程;
- AWSPollyTest.java:基于 JUnit 5 的集成测试。
重要注意事项(来自原文档)
原 README 在醒目位置列出了运行前须知,这里完整继承:
- 可能产生费用:运行代码及测试会对你的 AWS 账户产生计费请求,请留意 AWS 定价与免费额度说明;
- 最小权限原则:建议为代码授予最小必要权限(least privilege),只授予完成任务所需的最小 IAM 权限;
- 区域支持:代码并非在每一个 AWS Region 都经过测试,Polly 的区域可用性请以 AWS 区域服务说明为准。
前置条件
Polly 示例复用javav2目录的统一前置条件(见 javav2/README.md):
- 本地克隆或下载了本仓库;
- 安装 Apache Maven(> 3.0);
- 所有 Java v2 示例都假定 AWS SDK 通过**默认凭证提供程序链(default credentials provider chain)**获取 AWS 凭证,例如:
- 在
~/.aws/config中配置 IAM Identity Center SSO 的默认 profile; - 或在
~/.aws/credentials中配置临时凭证;
- 在
- 默认 Region 配置。可以在默认 profile 中一并设置;如果未显式设置 Region,AWS SDK for Java 默认使用us-east-1。注意本目录的示例代码在构建客户端时显式指定了
Region.US_WEST_2,会覆盖默认值。
此外,从 pom.xml 可见,该模块要求Java 21(maven.compiler.source/target均设为 21),构建前请确保本地 JDK 版本匹配。
构建配置解读
pom.xml 是一个独立的 Maven 工程(pollyV2Project:pollyV2Project:1.0-SNAPSHOT),关键配置如下:
| 配置项 | 取值 | 说明 |
|---|---|---|
| Java 版本 | 21 | 编译器源码与目标字节码版本均为 21 |
software.amazon.awssdk:bom | 2.35.10 | 以 BOM 方式统一管理 AWS SDK 各模块版本 |
software.amazon.awssdk:polly | 由 BOM 管理 | Polly 服务客户端依赖 |
software.amazon.awssdk:sso/ssooidc | 由 BOM 管理 | 支持 IAM Identity Center SSO 凭证流程 |
com.googlecode.soundlibs:jlayer | 1.0.1.4 | MP3 解码库,供PollyDemo本地播放合成音频 |
org.apache.logging.log4j(log4j-bom 2.23.1) | log4j-core / log4j-slf4j2-impl / log4j-1.2-api | 日志实现,测试类通过 SLF4J 输出日志 |
org.junit.jupiter:junit-jupiter | 5.11.4 | JUnit 5 测试框架(test scope) |
maven-surefire-plugin | 3.5.2 | 控制mvn test的测试执行 |
其中sso与ssooidc两个依赖值得注意:它们保证当凭证链走到 SSO 流程时,SDK 能完成 IAM Identity Center 的令牌交换,这也是javav2各服务模块普遍引入这两个依赖的原因。
示例一:DescribeVoices 查询可用音色
第一个单点示例 DescribeVoicesSample.java 演示如何调用DescribeVoices接口,按语言代码筛选可用音色。完整代码:
package com.example.polly; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.polly.PollyClient; import software.amazon.awssdk.services.polly.model.DescribeVoicesRequest; import software.amazon.awssdk.services.polly.model.DescribeVoicesResponse; import software.amazon.awssdk.services.polly.model.PollyException; import software.amazon.awssdk.services.polly.model.Voice; import java.util.List; public class DescribeVoicesSample { public static void main(String args[]) { PollyClient polly = PollyClient.builder() .region(Region.US_WEST_2) .build(); describeVoice(polly); polly.close(); } public static void describeVoice(PollyClient polly) { try { DescribeVoicesRequest voicesRequest = DescribeVoicesRequest.builder() .languageCode("en-US") .build(); DescribeVoicesResponse enUsVoicesResult = polly.describeVoices(voicesRequest); List<Voice> voices = enUsVoicesResult.voices(); for (Voice myVoice : voices) { System.out.println("The ID of the voice is " + myVoice.id()); System.out.println("The gender of the voice is " + myVoice.gender()); } } catch (PollyException e) { System.err.println("Exception caught: " + e); System.exit(1); } } }源码级要点:
- 客户端构建:
PollyClient.builder().region(Region.US_WEST_2).build()显式指定us-west-2区域;凭证则走 SDK 默认凭证链(见前置条件); - 请求参数:
DescribeVoicesRequest通过 builder 设置languageCode("en-US"),即只查询美式英语音色;若省略该参数则会返回全部可用音色; - 响应处理:
DescribeVoicesResponse.voices()返回List<Voice>,每个Voice对象中取id()(后续合成语音时用作voiceId)与gender()两个字段打印; - 异常与资源管理:捕获
PollyException后输出错误并以退出码 1 结束进程;main方法在调用结束后显式polly.close()释放客户端资源。注意describeVoice被设计为接受客户端参数的静态方法,便于测试直接复用(见后文测试章节)。
示例二:ListLexicons 列出发音词典
第二个单点示例 ListLexicons.java 演示ListLexicons接口,用于列出账户下已创建的发音词典(Lexicon 用于让 Polly 按指定发音朗读特定词汇):
public class ListLexicons { public static void main(String args[]) { PollyClient polly = PollyClient.builder() .region(Region.US_WEST_2) .build(); listLexicons(polly); polly.close(); } public static void listLexicons(PollyClient client) { try { ListLexiconsRequest listLexiconsRequest = ListLexiconsRequest.builder() .build(); ListLexiconsResponse listLexiconsResult = client.listLexicons(listLexiconsRequest); List<LexiconDescription> lexiconDescription = listLexiconsResult.lexicons(); for (LexiconDescription lexDescription : lexiconDescription) { System.out.println("The name of the Lexicon is " + lexDescription.name()); } } catch (PollyException e) { System.err.println("Exception caught: " + e); System.exit(1); } } }源码级要点:
ListLexiconsRequest未设置任何过滤条件(空 builder),即列出全部词典;- 响应
ListLexiconsResponse.lexicons()返回List<LexiconDescription>,示例仅打印每个词典的name(); - 整体结构与
DescribeVoicesSample一致:US_WEST_2 区域、PollyException统一捕获、静态业务方法接受客户端参数,方便测试注入同一客户端实例。
示例三:SynthesizeSpeech 合成语音并本地播放
第三个示例 PollyDemo.java 是三者中最完整的端到端演示:先用DescribeVoices找到目标音色,再调用SynthesizeSpeech把一段英文文本合成为 MP3 语音流,最后用第三方 MP3 解码库 jlayer 在本地播放。完整代码:
public class PollyDemo { private static final String SAMPLE = "Congratulations. You have successfully built this working demo " + " of Amazon Polly in Java Version 2. 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 static void main(String args[]) { PollyClient polly = PollyClient.builder() .region(Region.US_WEST_2) .build(); talkPolly(polly); polly.close(); } public static void talkPolly(PollyClient polly) { try { DescribeVoicesRequest describeVoiceRequest = DescribeVoicesRequest.builder() .engine("standard") .build(); DescribeVoicesResponse describeVoicesResult = polly.describeVoices(describeVoiceRequest); Voice voice = describeVoicesResult.voices().stream() .filter(v -> v.name().equals("Joanna")) .findFirst() .orElseThrow(() -> new RuntimeException("Voice not found")); InputStream stream = synthesize(polly, SAMPLE, voice, OutputFormat.MP3); AdvancedPlayer player = new AdvancedPlayer(stream, javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice()); player.setPlayBackListener(new PlaybackListener() { public void playbackStarted(PlaybackEvent evt) { System.out.println("Playback started"); System.out.println(SAMPLE); } public void playbackFinished(PlaybackEvent evt) { System.out.println("Playback finished"); } }); // play it! player.play(); } catch (PollyException | JavaLayerException | IOException e) { System.err.println(e.getMessage()); System.exit(1); } } public static InputStream synthesize(PollyClient polly, String text, Voice voice, OutputFormat format) throws IOException { SynthesizeSpeechRequest synthReq = SynthesizeSpeechRequest.builder() .text(text) .voiceId(voice.id()) .outputFormat(format) .build(); ResponseInputStream<SynthesizeSpeechResponse> synthRes = polly.synthesizeSpeech(synthReq); return synthRes; } }(源码中还包含javazoom.jl.player.advanced与software.amazon.awssdk.core.ResponseInputStream等导入,见 PollyDemo.java 的文件头导入段。)
分步解析:
- 按引擎筛选音色:
DescribeVoicesRequest.builder().engine("standard")只查询标准(standard)引擎下的音色,再用 Stream 过滤出名字为Joanna的音色;若找不到则抛出RuntimeException("Voice not found"),避免后续使用空音色。这与示例一按languageCode过滤形成对照——DescribeVoices同时支持languageCode与engine两类过滤条件; - 合成语音:synthesize 方法 构建
SynthesizeSpeechRequest,三个核心参数分别为待朗读文本text、音色voiceId(取自Voice.id())、输出格式OutputFormat.MP3。返回值不是普通文件,而是ResponseInputStream<SynthesizeSpeechResponse>——音频以流的形式返回,可直接交给播放器边收边放,无需先落盘; - 本地播放:使用 pom.xml 中声明的 jlayer 1.0.1.4 依赖,
AdvancedPlayer以“流 + 系统音频设备”创建播放器,并通过PlaybackListener回调在播放开始/结束时分别打印提示文本与原文。运行该示例需要本地具备可用的音频设备; - 多异常统一处理:
catch (PollyException | JavaLayerException | IOException e)同时覆盖 AWS 服务异常、MP3 解码异常与 I/O 异常,任一发生即打印消息并以退出码 1 结束。
从源码结构看,synthesize方法被抽成独立的静态方法并返回InputStream,说明示例的意图是展示“合成结果即音频流”的用法,便于读者替换为写入文件或上传到 S3 等其它消费方式。
运行示例
依据 javav2/README.md 的统一构建说明,在本目录下的操作步骤如下:
- 构建:进入
javav2/example_code/polly目录后执行mvn package。Maven 会自动从 BOM 拉取 AWS SDK for Java 2.35.10 的polly模块及其它依赖; - 运行:构建后在
target目录下会得到pollyV2Project-1.0-SNAPSHOT.jar。由于 pom.xml 未配置 maven-shade-plugin,直接以-cp方式运行单个类时需自行补齐依赖 classpath;更稳妥的方式是使用 IDE 打开该 Maven 工程后直接运行com.example.polly.DescribeVoicesSample、com.example.polly.ListLexicons或com.example.polly.PollyDemo的main方法; - 观察输出:
DescribeVoicesSample在控制台逐行打印美式英语音色的 ID 与性别;ListLexicons打印账户下各词典的名称(若从未创建过词典,列表为空);PollyDemo打印 “Playback started” 与原文文本,随后从扬声器播放合成的英文语音,结束时打印 “Playback finished”。
⚠ 再次提醒:这些操作会调用真实的 AWS 服务,可能产生费用;示例本身均为只读或生成语音的操作,不涉及删除等破坏性资源变更。
测试验证
测试文件 AWSPollyTest.java 使用 JUnit 5 验证前两个示例的静态业务方法,关键结构如下:
@TestInstance(TestInstance.Lifecycle.PER_METHOD) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class AWSPollyTest { private static PollyClient polly; private static final Logger logger = LoggerFactory.getLogger(AWSPollyTest.class); @BeforeAll public static void setUp() { polly = PollyClient.builder() .region(Region.US_WEST_2) .build(); } @Test @Tag("IntegrationTest") @Order(1) public void testDescribeVoicesSample() { assertDoesNotThrow(() -> DescribeVoicesSample.describeVoice(polly)); logger.info("Test 1 passed"); } @Test @Tag("IntegrationTest") @Order(2) public void testListLexicons() { assertDoesNotThrow(() -> ListLexicons.listLexicons(polly)); logger.info("Test 2 passed"); } }测试设计要点:
@BeforeAll中构建一次共享的PollyClient(区域 US_WEST_2),各测试方法通过assertDoesNotThrow断言业务方法不抛异常;@Order(1)/@Order(2)配合@TestMethodOrder(MethodOrderer.OrderAnnotation.class)明确执行顺序;@Tag("IntegrationTest")标记为集成测试;- 这正是前文将
describeVoice、listLexicons设计为“接受客户端参数的静态方法”的原因——测试可注入统一客户端,而不必各方法重复构建; - 该测试类没有读取
config.properties,区域、语言代码、词典等参数均硬编码在示例代码中,运行前只需保证本地凭证链可用即可; - 运行方式与
javav2目录统一说明一致:cd javav2/example_code/polly && mvn test,由 pom.xml 中配置的 maven-surefire-plugin 3.5.2 执行。
⚠ 原文档特别强调:运行这些集成测试会操作真实的 AWS 资源并可能产生费用。本目录的测试调用DescribeVoices与ListLexicons两个只读接口,费用风险较低,但仍应遵守最小权限原则,仅授予polly:DescribeVoices、polly:ListLexicons等完成测试所需的最小权限。
小结与延伸阅读
本模块的三个示例覆盖了 Amazon Polly 在 Java 2.x SDK 下的典型使用面:
| 示例文件 | 演示接口 | 核心知识点 |
|---|---|---|
| DescribeVoicesSample.java | DescribeVoices | 按languageCode过滤音色,读取Voice.id()/Voice.gender() |
| ListLexicons.java | ListLexicons | 列出LexiconDescription并读取词典名 |
| PollyDemo.java | DescribeVoices+SynthesizeSpeech | 按engine筛选音色、MP3 流式合成、jlayer 本地播放 |
三者共享同一套工程约定:PollyClient显式指定区域、PollyException统一捕获、静态业务方法便于测试注入、客户端用完即close()。如需扩展(例如创建/上传发音词典、保存合成音频文件到 S3),可参照上述请求 builder 与流式响应的写法继续组合 Polly 的其他 API。仓库中同语言的其他服务示例(如 S3、SQS 等)遵循相同的目录与构建组织方式,均位于javav2/example_code/下,可作为横向参考。
- 示例工程
- 教程
- 后端
【免费下载链接】aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
相关推荐
AWS SDK for Java 2.x 操作 Amazon Pinpoint 实战:aws-doc-sdk-examples 中的 Pinpoint 代码示例详解
AWS SDK for Java 2.x 操作 Amazon Pinpoint 实战:aws doc sdk examples 中的 Pinpoint 代码示例
示例工程教程后端AWS SDK for Java 2.x 实战:在 aws-doc-sdk-examples 中运行与测试 Amazon MQ 的 Java 示例
AWS SDK for Java 2.x 实战:在 aws doc sdk examples 中运行与测试 Amazon MQ 的 Java 示例 本文基于 j
示例工程教程后端aws-doc-sdk-examples 仓库中的 Amazon Bedrock .NET 示例:从 ListFoundationModels 入门 AWS SDK for .NET
aws doc sdk examples 仓库中的 Amazon Bedrock .NET 示例:从 ListFoundationModels 入门 AWS S
示例工程教程后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考