亚马逊AWS官方博客

在 AWS 上实现无服务器视频字幕自动翻译架构

简介

随着媒体行业的全球化发展,越来越多的用户(包括企业和个人)都会有视频字幕的自动化翻译的需求。本文使用Amazon S3作为视频和字幕文件的存储,使用 Amazon Translate 实现了字幕的机器翻译,并且使用Amazon Lambda来调用 Amazon Translate 构建了一套无服务器的视频字幕翻译架构。利用本文实现的方案,您只需要将视频和字幕文件上传至Amazon S3,就可以自动获得翻译后的视频和字幕文件。

基础介绍

Amazon Simple Storage Service (Amazon S3) 是一种对象存储服务,提供行业领先的可扩展性、数据可用性、安全性和性能。这意味着各种规模和行业的客户都可以使用它来存储和保护各种用例(如网站、移动应用程序、备份和还原、存档、企业应用程序、IoT 设备和大数据分析)的任意数量的数据。

Amazon Translate 是一项神经网络机器翻译服务,可提供快速、高质量且经济实惠的语言翻译。神经网络机器翻译是一种语言翻译自动化形式,采用深度学习模型,可以提供比基于规则的传统统计式翻译算法更准确、更自然的翻译。利用 Amazon Translate,可以对面向国际用户的网站和应用程序等内容进行本地化,并轻松高效地翻译大量文字。

AWS Lambda 是一项计算服务,无需预配置或管理服务器即可运行代码。借助 AWS Lambda,几乎可以为任何类型的应用程序或后端服务运行代码,并且不必进行任何管理。AWS Lambda 在可用性高的计算基础设施上运行代码,执行计算资源的所有管理工作,其中包括服务器和操作系统维护、容量预置和自动扩展、代码监控和记录。

srt格式字幕:srt的全称是SubRip Text,是最为流行的文本字幕格式,因为其制作规范简单,一句时间代码+一句字幕,使得制作修改就相当简单。配合上.style文件还能让srt自带一些字体上的特效等。下图是srt格式字幕的一个简单例子。

整体架构

本方案的整体架构图如下所示:

1. 用户上传视频和原语言的SRT格式的字幕文件到 S3 存储桶;
2. 监测到 S3 存储桶的事件变化(put object操作),自动触发执行 Lambda 函数;
3. Lambda 函数调用 Translate 服务对字幕文件的内容进行翻译;
4. Lambda 函数集成翻译结果形成一个目标语言的 SRT 字幕文件;
5. Lambda 函数将新的字幕文件上传到S3存储桶;
6. 用户可以利用原来的视频文件和目标语言的 SRT 字幕文件

构建步骤

1.创建S3存储桶

进入AWS控制台进入S3服务,创建一个存储桶,并且创建两个文件夹,“input”用于存放视频和源语言字幕文件,“output”用于存放翻译后的目标语言字幕文件。

在“input”文件夹中再创建两个文件夹,“videos”用于存放视频文件,“subtitles”用于存放源字幕文件。

2.创建 IAM 角色

每个Lambda函数都有一个与之关联的IAM角色。此角色定义允许该功能与其进行交互的其他AWS服务。

在AWS控制台中进入IAM服务,选择创建角色,并选择“Lambda”作为角色类型,在“Permission”中赋予该函数需要交互的两个服务的权限:“TranslateFullAccess” 和 “AmazonS3FullAccess”,最后点击创建角色。

3.创建Lambda函数

在AWS控制台中进入Lambda服务,点击“create Function”按钮。选择“从头开始创作”,填写函数名,并且在“Runtime”运行环境中选择“Python3.7”环境,在“执行角色”中选择“使用现有角色”,选择刚刚创建的角色名称,最后点击创建函数。

4.配置Lambda触发条件

在Lambda的函数配置页面,点击“Add Trigger”按钮添加触发条件。

在触发条件配置页面,在“Bucket”下拉列表中选择刚刚创建的存储桶名称,在“Event”下拉列表中选择“Put”,在“Prefix”中输入“input/subtitles”,在“Suffix”中输入“.srt”,然后点击“add”按钮,完成触发条件的添加。该触发条件设置监视刚刚创建存储桶的input/subtitles目录中扩展名为.srt的文件,如果是put操作,将触发该lambda函数。

5. Lambda内存和超时配置

在刚创建的Lambda函数中,需要配置内存的大小和执行超时。在本方案中Lambda会下载SRT格式的字幕文件到内部中,调用Translate翻译后会上传到S3,然后将内存中的源字幕文件删除。内存分配为默认的128MB,超时时间设置为10分钟。

6.导入Lambda函数

上传附件中的代码文件或者直接copy文件中的代码到Lambda函数中。

Lambda函数的实现主要分为以下几个步骤:

6.1 参数获取

从event对象中和系统变量中获取相关参数信息。
region = os.environ['AWS_DEFAULT_REGION']
bucket_name = event['Records'][0]['s3']['bucket']['name']
sourceS3Key = event['Records'][0]['s3']['object']['key']

6.2 从S3下载字幕文件并读取内容

# 下载S3的字幕文件到本地
input_file_name = sourceS3Key.split("/")[-1]
local_input_file = "/tmp/" + input_file_name
s3_client.download_file(bucket_name, sourceS3Key, local_input_file)

# 读取字幕文件的内容
id_list, time_list, subtitles_list = read_srt(local_input_file)

# 读取srt格式的字幕文件
def read_srt(filename):
id_list = []
time_list = []
subtitles_list = []
with open(filename, encoding='utf-8') as srt_file:
content = srt_file.read()
content_split = content.split("\n\n")
# print(content_split)
for one_content in content_split:
if one_content != '':
id_list.append(one_content.split("\n")[0])
time_list.append(one_content.split("\n")[1])
subtitles_list.append(one_content.split("\n")[2])
return id_list, time_list, subtitles_list

6.3 调用 Amazon Translate 对字幕内容进行翻译

# 调用Amazan Translate进行翻译
def translate_text(text, sourceLanguageCode, targetLanguageCode):
response1 = translate_client.translate_text(
Text = text,
SourceLanguageCode = sourceLanguageCode,
TargetLanguageCode = targetLanguageCode
)
translation_text = response1['TranslatedText']
return translation_text

# 翻译字幕列表
def translate_subtitles(subtitles_list, sourceLanguageCode, targetLanguageCode):
translate_subtitles_list = []
for subtitle in subtitles_list:
translated_subtitle = translate_text(subtitle,sourceLanguageCode, targetLanguageCode)
translate_subtitles_list.append(translated_subtitle)

return translate_subtitles_list

# 对字幕进行翻译
translate_subtitles_list = translate_subtitles(subtitles_list, sourceLanguageCode, targetLanguageCode)

6.4 将翻译后的目标语言和原来的id以及时间线集成为一个新的SRT格式字幕文件

# 生成srt字幕文件
def get_translated_srt_content(id_list, time_list, translate_subtitles_list):
result = ""
for i in range(len(id_list)):
result = result + id_list[i] + "\n" + time_list[i] + "\n" + translate_subtitles_list[i] + "\n\n"
return result

# 把翻译的结果集成到srt字幕文件里
result = get_translated_srt_content(id_list, time_list, translate_subtitles_list)

6.5 上传新的字幕文件到S3

# 上传文件到S3
output_filename = "translated_" + input_file_name
outputS3Key = "output/translated-subtitles/" + output_filename
s3_client.put_object(Body=result, Bucket=bucket_name, Key=outputS3Key)
# s3_client.upload_file(local_file, bucket_name, outputS3Key)

6.6 删除Lambda下载到内存中的源字幕文件

# 删除下载的临时文件
os.remove(local_input_file)

7.测试

在AWS管理控制台点击“S3”服务,打开刚创建的存储桶,进入“input/videos”文件夹,点击“Upload”“Add files”从本地电脑里选择一个视频文件;进入“input/subtitles”文件夹,上传一个srt格式的字幕文件。

此时就会触发我们刚刚创建的Lambda函数。Lambda函数执行完成后,进入到S3存储桶的“output/translated-subtitles”文件夹,可以看到翻译后的目标语言字幕文件。

很多播放软件都支持自动加载字幕,需要把字幕文件和原始的视频文件放在同一目录。本文使用 ffmpeg 把字幕合成到视频中,以查看字幕翻译效果。

清理资源

最后点击删除函数清理资源。

总结

本方案使用了Amazon Translate实现字幕的机器翻译,并且使用Amazon Lambda实现了无服务器的架构,用户可以非常方便得集成到各种场景。无服务器架构使用户无需购买和管理无服务器资源。

源代码

本文Lambda源代码查看:https://github.com/nwcd-samples/ServerlessSubtitleTranslation

参考

 

本篇作者

张贝贝

AWS解决方案架构师,负责基于AWS的云计算方案架构咨询和设计,擅长软件开发,机器学习等领域,具有丰富的解决客户实际问题的经验。