亚马逊Amazon S3+Amazon Lambda实时转录与翻译教程

无服务器架构是一种新的云计算方法,允许开发人员在不考虑服务器的维护的情况下构建和部署应用程序。亚马逊云科技就为用户提供一系列免费的无服务器产品服务,如Amazon S3、Amazon Lambda等。本文为大家介绍的是利用亚马逊Amazon S3+Amazon Lambda实时转录与翻译教程,有需要的朋友可以参考一下!

本文需要用到的亚马逊AWS免费套餐:Amazon S3+Amazon Lambda+Amazon Translate+Amazon Transcribe。

1、Amazon S3

Amazon S3是一种对象存储服务,可以存储静态网站内容、用户上传的文件等。Amazon S3免费套餐提供5GB的免费云存储空间、99.999999999%的持久性、20000个Get请求、2000个Put请求,使用时长达12个月。

2、Amazon Lambda

Amazon Lambda(AWS Lambda)是一种无服务器计算服务,允许用户运行代码而无需管理服务器。用户可以根据事件触发函数,如HTTP请求、数据库更改等。AWS Lambda免费套餐提供每月100万次免费调用请求,灵活可扩展,永久免费使用。

3、Amazon Translate

Amazon Translate支持70多种语言之间的翻译,助力产品销往全球,每月200万个字符免费用量,免费使用时长达12个月。

4、Amazon Transcribe

Amazon Transcribe为各类海外应用添加语音转文字功能,每月60分钟免费时长,免费使用时长达12个月。

新用户注册亚马逊云科技账户,即可在控制台中试用亚马逊AWS免费套餐产品。

点击领取:亚马逊AWS免费套餐

一、启动亚马逊Amazon Translate和Amazon Transcribe

1、当音频文件以/audio前缀上传至Amazon Simple Storage Service(S3)存储桶时,会触发一个AWS Lambda函数,它将运用Amazon Transcribe从音频文件中提取文本。该函数会将转录文本以/transcriptions前缀写入同一个存储桶。

2、当在/transcriptions目录下创建一个文件时,另一个AWS Lambda函数会被触发以执行翻译任务。为简化说明,我们假设录音为英语,希望将其翻译为意大利语。这个AWS Lambda函数会将翻译结果写入/translations目录。

亚马逊转录和翻译的架构和编排

编排非常适用于创建小型原型和概念验证。在这个例子中,我们也将Amazon S3用作消息总线。

注意:在使用Amazon S3、Amazon S3前缀和AWS Lambda实现编排时,务必要非常小心,不要导致AWS Lambda函数出现递归调用,否则会产生不必要的费用。请留意函数写入Amazon S3的路径。

二、创建亚马逊AWS CDK堆栈

1、安装AWS CDK CLI

如果还没有安装AWS CDK,请使用npm进行安装:

npm install -g aws-cdk

2、新建AWS CDK项目

为用户的AWS CDK项目新建一个目录,并使用下列命令对其初始化

mkdir transcribe-translate
cd transcribe-translate
cdk init app --language typescript

3、添加所需的AWS CDK依赖项

npm install @aws-cdk/aws-s3 @aws-cdk/aws-lambda @aws-cdk/aws-iam @aws-cdk/aws-s3-notifications @aws-cdk/aws-lambda-nodejs

三、创建亚马逊无服务器基础架构

编辑lib/transcribe-translate-stack.ts文件以定义资源:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3n from 'aws-cdk-lib/aws-s3-notifications';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as path from 'path';

export class TranscribeTranslateStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create the S3 bucket
    const bucket = new s3.Bucket(this, 'UploadBucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY, // this is OK only for dev
      autoDeleteObjects: true, // this is OK only for dev
    });

    // Create the Transcribe Lambda function
    const transcribeFunction = new NodejsFunction(this, 'TranscribeFunction', {
      runtime: lambda.Runtime.NODEJS_18_X,
      entry: path.join(__dirname, '../lambda/transcribe.mjs'),
      handler: 'handler',
      environment: {
        BUCKET_NAME: bucket.bucketName,
      },
      timeout: cdk.Duration.seconds(900),
    });

    // Grant read/write permissions on S3 objects for the transcribe function
    bucket.grantReadWrite(transcribeFunction, 'transcriptions/*');

    // Additional permissions for Transcribe
    transcribeFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['transcribe:StartTranscriptionJob', 'transcribe:GetTranscriptionJob'],
      resources: ['*'],
    }));

    // Add S3 event notification to trigger Transcribe function
    bucket.addEventNotification(s3.EventType.OBJECT_CREATED, new s3n.LambdaDestination(transcribeFunction), {
      prefix: 'audio/',
    });

    // Create the Translate Lambda function
    const translateFunction = new NodejsFunction(this, 'TranslateFunction', {
      runtime: lambda.Runtime.NODEJS_18_X,
      entry: path.join(__dirname, '../lambda/translate.mjs'),
      handler: 'handler',
      environment: {
        BUCKET_NAME: bucket.bucketName,
      },
      timeout: cdk.Duration.seconds(900),
    });

    // Grant read/write permissions on specific S3 objects for the translate function
    bucket.grantRead(translateFunction, 'transcriptions/*');
    bucket.grantReadWrite(translateFunction,'translations/*');

    // Additional permissions for Translate
    translateFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['translate:TranslateText'],
      resources: ['*'],
    }));

    // Add S3 event notification to trigger Translate function
    bucket.addEventNotification(s3.EventType.OBJECT_CREATED, new s3n.LambdaDestination(translateFunction), {
      prefix: 'transcriptions/',
    });
  }
}

四、亚马逊无服务器架构触发转录任务

在以下示例中,将会触发转录任务,但不会监控其是否成功完成。

在本地代码仓库创建一个lambda/transcribe.mjs文件

import { TranscribeClient, StartTranscriptionJobCommand } from '@aws-sdk/client-transcribe';

const transcribeClient = new TranscribeClient();

export const handler = async (event) => {
    const bucket = process.env.BUCKET_NAME;
    const key = event.Records[0].s3.object.key;

    const transcribeParams = {
        TranscriptionJobName: `TranscribeJob-${Date.now()}`,
        LanguageCode: 'en-US',
        Media: {
            MediaFileUri: `s3://${bucket}/${key}`
        },
        OutputBucketName: bucket,
        OutputKey: `transcriptions/${key.split("/").pop()}.json`
    };

    try {
        await transcribeClient.send(new StartTranscriptionJobCommand(transcribeParams));
        console.log('Transcription job started');
    } catch (err) {
        console.error('Error starting transcription job', err);
        return;
    }

};

任务完成后会在/transcriptions下新建一个对象。这将触发编排的下一阶段。

五、亚马逊无服务器架构触发翻译任务

创建一个lambda/translate.mjs文件

import { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
import { TranslateClient, TranslateTextCommand } from '@aws-sdk/client-translate';

const s3Client = new S3Client();
const translateClient = new TranslateClient();

export const handler = async (event) => {
    const bucket = process.env.BUCKET_NAME;
    const key = event.Records[0].s3.object.key;

    // Get the transcription text from S3
    let transcriptionData;
    
    try {
        transcriptionData = await s3Client.send(new GetObjectCommand({
            Bucket: bucket,
            Key: key
        }));
    } catch (err) {
        console.error('Error getting transcription from S3', err);
        return;
    }

    const { results } = JSON.parse(await streamToString(transcriptionData.Body));

    const transcriptionText = results.transcripts.reduce(
        (acc, curr) => acc + curr.transcript, ''
    );
    console.log('Transcription text:', transcriptionText);

    // Translate the transcription
    const translateParams = {
        SourceLanguageCode: 'en',
        TargetLanguageCode: 'it',
        Text: transcriptionText
    };

    console.log(translateParams);

    let translation; 
    
    try{
        translation = await translateClient.send(new TranslateTextCommand(translateParams));
        console.log('Translation:', translation.TranslatedText);
    }catch(err){
        console.error('Error translating text', err);
        return;
    }

    // Save the translation result to S3
    const translationResult = {
        originalText: transcriptionText,
        translatedText: translation.TranslatedText
    };

    try{
        await s3Client.send(new PutObjectCommand({
            Bucket: bucket,
            Key: `translations/${key.split("/").pop()}.it.txt`,
            Body: translationResult.translatedText,
            ContentType: 'text/plain'
        }));
    }catch(err){
        console.error('Error saving translation to S3', err);
        return;
    }

    console.log('Translation saved');
};

// Helper function to convert a stream to a string
const streamToString = (stream) => {
    return new Promise((resolve, reject) => {
        const chunks = [];
        stream.on('data', (chunk) => chunks.push(chunk));
        stream.on('error', reject);
        stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
    });
};

六、亚马逊无服务器架构部署

cdk bootstrap # if you haven't bootstrapped in this region before
cdk deploy

完成部署后,用户应该能看到一个输出列表。在这里可以找到用户的Amazon S3存储桶名称。

亚马逊无服务器架构部署

七、测试亚马逊无服务器架构

要进行测试,只需将mp3文件上传到audio/输出所得的Amazon S3存储桶中。用户可以使用下列Amazon CLI。

aws s3 cp ./path/to/your/audio/file s3://your-bucket-here/audio/file.mp3

或者转到亚马逊云科技控制台,向audio/上传mp3文件。稍后便可得到transcriptions/和translations/,在这两个文件夹中可以找到每个类别的编排结果。

测试亚马逊无服务器架构

八、清理亚马逊无服务器架构

任务完成后,用下列命令拆解基础架构。

cdk destroy

相关推荐:《如何注册亚马逊AWS海外账号?

使用教程

腾讯云服务器迁移最简单方法

2024-10-28 16:11:22

使用教程

Immich安装教程

2024-11-11 10:34:03

相关推荐