AWS Transcribe启动转录任务报错:S3私有桶访问与参数验证问题
问题1:TranscriptionJobName格式错误
你当前直接把S3对象键(key)作为转录任务名,你的key里包含/字符(比如示例里的source/2004-DNC.mp3),但Transcribe要求任务名只能包含大小写字母、数字、点.、下划线_、横杠-,不支持斜杠,所以触发了正则校验失败。
修复方案:
对key做字符替换,去掉/或者替换为允许的字符,同时建议加入随机字符串/时间戳避免任务名重复(同区域下转录任务名不能重复),示例修改逻辑如下:
# 引入os和uuid模块用于处理文件名和生成唯一标识 import os, uuid # 生成符合规范的任务名 base_name = os.path.splitext(os.path.basename(key))[0] job_name = f"{base_name}_{uuid.uuid4().hex[:8]}".replace('/', '_')
后续将TranscriptionJobName参数的值替换为生成的job_name即可。
问题2:S3 URI无法访问
你生成的s3://{桶名}/{对象键}格式的MediaFileUri完全符合要求,无需调整。私有桶本身不会造成访问问题,Block Public Access配置仅拦截公共访问请求,不会影响AWS服务内部的合法授权访问。
本次报错的核心原因是:你给Lambda配置的S3读权限仅能让Lambda自身访问S3,但启动转录任务后是Transcribe服务独立访问S3对象读取音频,该操作不经过Lambda执行,所以Transcribe服务没有获得S3的读取授权。
修复方案二选一即可:
方案1:给S3桶添加桶策略,允许Transcribe服务读取对象
在你的源S3桶的桶策略中添加如下配置:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "transcribe.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::abcdefghijk-transcribe-source/*" } ] }
方案2:为转录任务指定执行角色
先创建一个IAM角色,信任Transcribe服务,且附加S3读权限,然后在调用start_transcription_job时添加参数JobExecutionSettings={'AllowDeferredExecution': True, 'DataAccessRoleArn': '你创建的角色ARN'}即可。
修改后的完整Lambda代码示例
import boto3 import os import uuid s3 = boto3.client('s3') transcribe = boto3.client('transcribe') def lambda_handler(event, context): for record in event['Records']: source_bucket = record['s3']['bucket']['name'] key = record['s3']['object']['key'] object_url = f"s3://{source_bucket}/{key}" # 生成符合要求的唯一任务名 base_name = os.path.splitext(os.path.basename(key))[0] job_name = f"{base_name}_{uuid.uuid4().hex[:8]}".replace('/', '_') response = transcribe.start_transcription_job( TranscriptionJobName=job_name, Media={'MediaFileUri': object_url}, MediaFormat='mp3', LanguageCode='en-US', # 如果选择方案2指定执行角色,取消下面这行的注释并替换为实际角色ARN # JobExecutionSettings={'AllowDeferredExecution': True, 'DataAccessRoleArn': 'arn:aws:iam::你的账号ID:role/你的Transcribe执行角色名'} ) print(response)
内容的提问来源于stack exchange,提问作者Ray

