一、实验目的

  • 利用 AWS Lambda 和 AWS Polly 服务搭建一个文本转语音转换器,并将生成的语音文件上传至 Amazon S3 存储桶,实现将输入文本转换为语音音频文件并进行存储的功能,深入理解无服务器架构下的语音合成技术及与 S3 服务的集成应用。

二、实验要求

  • 了解 Amazon Web Services(AWS)的基本概念和使用方法。
  • 熟悉无服务器架构,掌握 AWS Lambda 的工作原理和操作流程。
  • 对语音合成技术有初步认识,知晓 AWS Polly 的功能和使用场景。
  • 掌握 Amazon S3 存储桶的创建、权限设置及文件上传操作。

三、实验原理

(一)AWS Lambda

AWS Lambda 是一种计算服务,允许用户在无需配置或管理服务器的情况下运行代码。它具备自动扩展能力,能根据请求量动态调整资源,用户只需为实际消耗的计算时间付费,代码未运行时不产生费用,极大地降低了开发和运营成本,适用于各种应用程序和后端服务的代码执行。

(二)AWS Polly

AWS Polly 是一种文本转语音服务,它利用先进的语音合成技术,可将输入的文本转换为逼真的语音。支持多种语言和不同风格的语音,能满足不同场景下的语音合成需求,如为网站、应用程序添加语音功能等。但需注意,不同的 VoiceID(语音 ID)支持不同的语言,在使用时要确保语音 ID 与输入文本的语言相匹配,否则可能生成无效(无声)的 MP3 文件。可参考AWS Polly 可用语音文档来选择合适的语音 ID。

(三)Amazon S3

Amazon S3(Simple Storage Service)是一种对象存储服务,提供可扩展的存储,用于存储和检索任意数量的数据。在本实验中,将用于存储由 AWS Polly 生成的语音文件。

在本实验中,将通过 AWS Lambda 调用 AWS Polly 的 API,实现文本转语音的功能,并将生成的语音文件上传至 Amazon S3 存储桶。

四、实验步骤

(一)创建Lambda函数

  1. 登录AWS管理控制台,在搜索框中输入“Lambda”,选择【Lambda】服务进入。
    1741708313964.png
  2. 在Lambda页面左侧导航栏中点击【函数】,接着点击页面上方的【创建函数】按钮。
    1741708406827.png
  3. 在“创建函数”页面,选择【从头开始制作】选项。
  4. 在“基本信息”部分,进行如下配置:

    • 函数名称:自定义一个有意义的名称,例如“text-to-speech-converter”。
    • 运行语言:选择【python3.9】(可根据实际情况选择支持的Python版本)。
      权限:点击【选择或创建执行角色】,若已有具备相关权限的角色,选择【使用现有角色】,并指定角色名称;若没有,则选择【创建新角色】。在创建新角色时,需确保该角色拥有调用 AWS Polly 服务和 Amazon S3 服务的权限。可以在创建角色的权限策略中添加 “PollyFullAccess” 策略,赋予其对 Polly 的完全访问权限,同时添加 “S3FullAccess” 策略(在实际生产中,建议根据最小权限原则进行更细粒度的权限设置,如仅授予对特定存储桶的读写权限),赋予对 S3 的操作权限。完成配置后,点击【创建函数】。

    1741708875258.png

1741708909755.png

(二)编写函数代码

  1. 在【函数代码】模块中,编写如下Python代码:

    import boto3
    import os
    from datetime import datetime
    
    
    def lambda_handler(event, context):
     polly = boto3.client('polly')
     text = event.get('text', 'Default Text')
     # 根据英文文本选择合适的VoiceID,例如Joanna
     voice_id = 'Joanna'
     response = polly.synthesize_speech(
         OutputFormat='mp3',
         Text=text,
         VoiceId=voice_id
     )
     audio_stream = response.get('AudioStream')
     if audio_stream:
         # 生成时间戳,确保时分秒正确输出
         timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
         s3 = boto3.client('s3')
         bucket_name = 'text-to-speech-converter-s3'  # 替换为你的S3存储桶名称
         s3_file_key = f'output_{timestamp}.mp3'  # S3存储桶中的对象键
         try:
             s3.put_object(Body=audio_stream.read(), Bucket=bucket_name, Key=s3_file_key)
             return {
                'statusCode': 200,
                 'body': '文本转语音成功,音频文件已上传到S3',
                 'audio_s3_path': f's3://{bucket_name}/{s3_file_key}'
             }
         except Exception as e:
             return {
                'statusCode': 500,
                 'body': f'上传音频文件到S3时出错: {str(e)}'
             }
     else:
         return {
            'statusCode': 500,
             'body': '文本转语音失败'
         }

    这段代码首先导入boto3库用于与 AWS 服务交互,导入os库用于可能的文件操作(这里虽未直接进行本地文件操作,但保留以防扩展需求),导入datetime库用于生成时间戳。在lambda_handler函数中,获取输入事件中的文本内容,如果没有则使用默认的英文文本。然后通过boto3.client('polly')创建一个 Polly 客户端,根据英文文本选择合适的VoiceId为 “Joanna”,调用synthesize_speech方法将文本转换为语音,指定输出格式为mp3。如果获取到音频流,生成带有精确到秒的时间戳的文件名,创建 S3 客户端,尝试将音频流直接上传至指定的 S3 存储桶。若上传成功,返回成功信息和音频文件在 S3 中的路径;若上传失败或文本转语音过程失败,则返回相应的错误信息。

代码编写完成后,点击页面上的【Deploy】(保存)按钮。
1741709127992.png

(三)创建 Amazon S3 存储桶并设置权限

  1. 登录 AWS 管理控制台,在搜索框中输入 “S3”,选择【S3】服务进入。
  2. 在 S3 页面,点击【创建存储桶】按钮。
  3. 在 “创建存储桶” 页面,进行如下配置:
    存储桶名称:输入一个唯一的名称,例如 “text-to-speech-converter-s3”,该名称在所有 AWS 账户的 S3 服务中必须是唯一的。
    AWS 区域:选择一个合适的区域,尽量选择与 Lambda 函数所在区域相同的区域,以减少网络延迟。
    其他设置可保持默认,然后点击【创建】按钮。
  4. 存储桶创建完成后,找到并点击该存储桶名称进入存储桶详情页面。
  5. 在存储桶详情页面,点击【权限】选项卡。

公共访问设置:根据实际需求设置公共访问权限。若希望外部可访问下载音频文件,可适当放宽权限,但需注意安全风险;若仅用于内部使用,可保持默认的阻止所有公共访问设置。

存储桶策略:如果在创建 Lambda 函数执行角色时未授予对特定存储桶的细粒度权限,可在此处添加存储桶策略,以允许 Lambda 函数对应的角色对该存储桶进行读写操作。例如,添加如下策略(将Role_LambdaAndPolly_FullAccess替换为实际的 Lambda 函数执行角色 ARN):

{
    "Version": "2012 - 10 - 17",
    "Statement": [
        {
            "Sid": "AllowLambdaToAccessS3",
            "Effect": "Allow",
            "Principal": {
                "AWS": "Role_LambdaAndPolly_FullAccess_ARN" #根据实际情况替换
            },
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::text-to-speech-converter-s3/*", #根据实际情况替换
                "arn:aws:s3:::text-to-speech-converter-s3" #根据实际情况替换
            ]
        }
    ]
}

(四)配置测试事件

  1. 回到 Lambda 函数页面,点击页面上方的【Test】按钮,弹出【配置测试事件】弹窗。
  2. 在弹窗中,配置事件名称,例如 “test-tts”。

1741709243705.png

  1. 在事件内容部分,输入测试文本,格式如下:

    {
      "text": "Congratulations! When you hear this sound, it indicates that your experiment has been successful."
    }

    这里的 “text” 字段就是要转换为语音的文本内容,可根据实际需求修改,同时要确保文本语言与代码中设置的VoiceId所支持的语言一致。

  2. 配置完成后,点击【Save】按钮。

(五)测试函数

  1. 创建测试事件完成后,再次点击【Test】按钮,开始测试 Lambda 函数。
    1741709371092.png
  2. 等待测试执行完成,查看测试结果。如果执行成功,在输出结果中可以看到状态码为 200,以及提示文本转语音成功并已上传到 S3 的信息和音频文件在 S3 中的路径;若执行失败,会显示相应的错误信息,可根据错误提示检查代码、权限配置以及文本内容和VoiceId设置等方面是否存在问题。

    Status: Succeeded
    Test Event Name: test-tts
    
    Response:
    {
      "statusCode": 200,
      "body": "文本转语音成功,音频文件已上传到S3",
      "audio_s3_path": "s3://text-to-speech-converter-s3/output_20250311170457.mp3"
    }
    
    Function Logs:
    START RequestId: c35c0e05-04a0-403f-bbeb-41ae395a30b5 Version: $LATEST
    END RequestId: c35c0e05-04a0-403f-bbeb-41ae395a30b5
    REPORT RequestId: c35c0e05-04a0-403f-bbeb-41ae395a30b5    Duration: 3283.48 ms    Billed Duration: 3284 ms    Memory Size: 128 MB    Max Memory Used: 84 MB    Init Duration: 313.26 ms
    
    Request ID: c35c0e05-04a0-403f-bbeb-41ae395a30b5

    1741713757799.png

五、实验结果

若实验成功,在测试结果中会显示文本转语音成功并已上传到 S3 的提示,通过音频文件在 S3 中的路径,可以在 S3 存储桶中找到对应的音频文件。下载该文件到本地,使用音频播放器打开,应能听到与输入文本对应的语音内容。如果没有听到预期的语音内容或出现错误提示,需要仔细检查代码逻辑、权限配置、文本内容、VoiceId设置以及 S3 存储桶的相关设置等方面是否存在问题,逐步排查并解决。

提示:本实验初次编写于2024/11/12,并于2025/3/11对此前内容进行更新,图片、代码均进行了替换,以提升实验效果。
最后修改:2025 年 03 月 12 日
分享是对我最大的赞赏