直播用户生成内容 (UGC) 平台的交互性和不可预测性是它们如此受欢迎的重要原因。但是,这种不可预测性意味着社区必须勤勉地监控他们的内容,以确保它符合他们的社区准则或可接受的使用政策,并且对所有用户来说都是适当、安全和受欢迎的。这通常会导致一个审核系统,用户向社区指南报告潜在的违规行为,主持人或管理员在必要时采取行动。这通常是一个手动过程,有很多不足之处。
近年来,人工智能(AI) 和机器学习 (ML) 工具得到了改进,开发人员可以使用这些工具来协助管理他们的社区。在这篇文章中,我们将探讨一种使用 Amazon Interactive Video Service (Amazon IVS) 和 Amazon Rekognition 实现这一目标的方法。
使用AI/ML分析应用程序中每个实时流的每一帧将是一项非常昂贵且困难的任务。相反,开发人员可以按指定频率分析其应用程序中的实时流样本,以在有内容需要人工审核员进一步审查时提醒审核员,从而协助审核员。它不是 100% 完美的解决方案,但它是一种自动化内容审核并帮助简化审核员工作的方法。
该解决方案包括以下步骤:
我们将使用 AWS 无服务器应用程序模型 (SAM) 来简化规则和函数的创建。这是描述必要权限、Amazon EventBridge 规则、AWS Lambda 层(用于 AWS SDK 依赖项)和函数定义的整个template.yaml
文件。我们将在下面对此进行分解。
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: Amazon IVS Moderation Functions Globals: Function: Runtime: nodejs18.x Timeout: 30 MemorySize: 128 Api: EndpointConfiguration: Type: REGIONAL Cors: AllowMethods: "'GET, POST, OPTIONS'" AllowHeaders: "'Content-Type'" AllowOrigin: "'*'" MaxAge: "'600'" Resources: IvsChatLambdaRefLayer: Type: AWS::Serverless::LayerVersion Properties: LayerName: sam-app-dependencies Description: Dependencies for sam app ContentUri: dependencies/ CompatibleRuntimes: - nodejs18.x LicenseInfo: "MIT" RetentionPolicy: Retain IVSAccessPolicy: Type: AWS::IAM::Policy Properties: PolicyName: IVSModerationAccessPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - 's3:GetObject' - 's3:GetObjectAcl' - 'ivschat:SendEvent' - 'ivs:StopStream' - 'rekognition:DetectModerationLabels' Resource: '*' Roles: - Ref: ModerateImageRole - Ref: StopStreamRole ApiAccessPolicy: Type: AWS::IAM::Policy Properties: PolicyName: ApiAccessPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - 'sts:AssumeRole' Resource: '*' Roles: - Ref: ModerateImageRole - Ref: StopStreamRole EventRule: Type: AWS::Events::Rule Properties: Description: EventRule State: ENABLED EventPattern: source: - aws.s3 detail-type: - "Object Created" detail: bucket: name: - ivs-demo-channel-stream-archive object: key: - suffix: .jpg Targets: - Arn: !GetAtt ModerateImage.Arn Id: MyLambdaFunctionTarget PermissionForEventsToInvokeLambda: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref ModerateImage Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt EventRule.Arn ModerateImage: Type: 'AWS::Serverless::Function' Properties: Environment: Variables: DEMO_CHAT_ARN: 'arn:aws:ivschat:us-east-1:[redacted]:room/[redacted]' DEMO_CHANNEL_ARN: 'arn:aws:ivs:us-east-1:[redacted]:channel/[redacted]' Handler: index.moderateImage Layers: - !Ref IvsChatLambdaRefLayer CodeUri: lambda/ StopStream: Type: 'AWS::Serverless::Function' Properties: Environment: Variables: DEMO_CHAT_ARN: 'arn:aws:ivschat:us-east-1:[redacted]:room/[redacted]' DEMO_CHANNEL_ARN: 'arn:aws:ivs:us-east-1:[redacted]:channel/[redacted]' Handler: index.stopStream Layers: - !Ref IvsChatLambdaRefLayer CodeUri: lambda/ Events: Api1: Type: Api Properties: Path: /stop-stream Method: POST Outputs: ApiURL: Description: "API endpoint URL for Prod environment" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
该文件中发生了很多事情,所以让我们对其进行分解。首先,我们创建一个层以在我们的函数中包含适用于 JavaScript (v3) 的 AWS 开发工具包。
IvsChatLambdaRefLayer: Type: AWS::Serverless::LayerVersion Properties: LayerName: sam-app-dependencies Description: Dependencies for sam app ContentUri: dependencies/ CompatibleRuntimes: - nodejs18.x LicenseInfo: "MIT" RetentionPolicy: Retain
在dependencies/nodejs
目录中,有一个package.json
文件,其中包含我们的函数所需的模块。
{ "dependencies": { "@aws-sdk/client-ivs": "^3.289.0", "@aws-sdk/client-ivschat": "^3.289.0", "@aws-sdk/client-rekognition": "^3.289.0" } }
下一部分由键IVSAccessPolicy
和APIAccessPolicy
标识,使我们的无服务器应用程序能够访问必要的 API( s3:GetObject
、 s3:GetObjectAcl
、 ivschat:SendEvent
、 ivs:StopStream
和rekognition:DetectModerationLabels
)并公开停止流方法我们将在下面通过 Amazon API Gateway 创建。
接下来,我们创建 Amazon EventBridge 规则。 bucket
下的name
属性应与您在录制配置中配置的 Amazon S3 存储桶的名称相匹配。录制到 Amazon S3 会创建各种文件,包括播放列表和 HLS 媒体,因此我们可以通过将object
下的key
设置为suffix: jpg
来过滤此规则以仅触发我们的缩略图。
EventRule: Type: AWS::Events::Rule Properties: Description: EventRule State: ENABLED EventPattern: source: - aws.s3 detail-type: - "Object Created" detail: bucket: name: - ivs-demo-channel-stream-archive object: key: - suffix: .jpg Targets: - Arn: !GetAtt ModerateImage.Arn Id: MyLambdaFunctionTarget
接下来,我们为规则提供调用 AWS Lambda 函数所需的权限。
PermissionForEventsToInvokeLambda: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref ModerateImage Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt EventRule.Arn
现在我们可以定义将由 Amazon EventBridge 规则调用的函数。
ModerateImage: Type: 'AWS::Serverless::Function' Properties: Environment: Variables: DEMO_CHAT_ARN: 'arn:aws:ivschat:us-east-1:[redacted]:room/[redacted]' DEMO_CHANNEL_ARN: 'arn:aws:ivs:us-east-1:[redacted]:channel/[redacted]' Handler: index.moderateImage Layers: - !Ref IvsChatLambdaRefLayer CodeUri: lambda/
注意:我将DEMO_CHAT_ARN
和DEMO_CHANNEL_ARN
声明为环境变量,但您的应用程序可能会从传递到函数中的事件中获取 ARN 值,因为您可能会将此功能与多个 Amazon IVS 通道一起使用。
最后,如有必要,我们可以定义将用于停止流的函数。
StopStream: Type: 'AWS::Serverless::Function' Properties: Environment: Variables: DEMO_CHAT_ARN: 'arn:aws:ivschat:us-east-1:[redacted]:room/[redacted]' DEMO_CHANNEL_ARN: 'arn:aws:ivs:us-east-1:[redacted]:channel/[redacted]' Handler: index.stopStream Layers: - !Ref IvsChatLambdaRefLayer CodeUri: lambda/ Events: Api1: Type: Api Properties: Path: /stop-stream Method: POST
现在我们已经使用 AWS SAM 描述了我们的基础设施,让我们创建我们描述的函数。在index.mjs
中,我们import
SDK 类,从传入的环境变量中检索Arn值,并创建函数所需的客户端实例。
import { IvsClient, StopStreamCommand } from "@aws-sdk/client-ivs"; import { IvschatClient, SendEventCommand } from "@aws-sdk/client-ivschat"; import { RekognitionClient, DetectModerationLabelsCommand } from "@aws-sdk/client-rekognition"; const chatArn = process.env.DEMO_CHAT_ARN; const channelArn = process.env.DEMO_CHANNEL_ARN; const ivsClient = new IvsClient(); const ivsChatClient = new IvschatClient(); const rekognitionClient = new RekognitionClient();
moderateImage
函数将接收 Amazon EventBridge 事件,从事件中提取bucket
和key
,并通过rekognitionClient
发送DetectModerationLabelsCommand
以根据类别检测图像中的任何不当或冒犯性内容
export const moderateImage = async (event) => { console.log('moderateImage:', JSON.stringify(event, null, 2)); const bucket = event.detail.bucket.name; const key = event.detail.object.key; const detectLabelsCommandInput = { Image: { S3Object: { Bucket: bucket, Name: key, } }, }; const detectLabelsRequest = new DetectModerationLabelsCommand(detectLabelsCommandInput); const detectLabelsResponse = await rekognitionClient.send(detectLabelsRequest); if (detectLabelsResponse.ModerationLabels) { sendEvent('STREAM_MODERATION', detectLabelsResponse.ModerationLabels); } };
如有必要, moderateImage
函数调用sendEvent
将自定义事件发布到任何前端连接的客户端到给定的 Amazon IVS 聊天室。
const sendEvent = async (eventName, eventDetails) => { const sendEventInput = { roomIdentifier: chatArn, attributes: { streamModerationEvent: JSON.stringify(eventDetails), }, eventName, }; const sendEventRequest = new SendEventCommand(sendEventInput); await ivsChatClient.send(sendEventRequest); };
您的前端可以决定如何处理此事件,发布此事件的逻辑将取决于您的业务需求。也许您更愿意在 CloudWatch 中触发自定义警报、发送电子邮件或通过 Amazon SNS 发布通知?每个应用程序的需求都不同,但此时可以使用审核数据来根据需要进行处理。
stopStream
方法使用ivsClient
发送StopStreamCommand
。同样,这取决于您的实施。如果 Amazon Rekognition 结果匹配特定类别或超过置信水平,您甚至可以完全自动化此命令。
export const stopStream = async (event) => { console.log('stopStream:', JSON.stringify(event, null, 2)); try { const stopStreamRequest = new StopStreamCommand({ channelArn }); const stopStreamResponse = await ivsClient.send(stopStreamRequest); responseObject.body = JSON.stringify(stopStreamResponse); } catch (err) { responseObject.statusCode = err?.name === 'ChannelNotBroadcasting' ? 404 : 500; responseObject.body = JSON.stringify(err); } return responseObject; };
在我的演示中,我决定侦听自定义事件并在显示检测到的项目和置信度的主持人视图中显示结果。我还向主持人展示了一个“停止流”按钮,该按钮通过公开的 Amazon API 网关调用stopStream
方法。
在这篇博文中,我们学习了如何使用 Amazon Rekognition 来帮助人工审核员审核他们使用 Amazon IVS 构建的应用程序中的内容。如果您想详细了解 Amazon IVS 如何帮助创建更安全的 UGC 社区,请查看以下博客文章: