Tính tương tác và tính không thể đoán trước của các nền tảng nội dung do người dùng tạo (UGC) phát trực tiếp là một phần lý do quan trọng khiến chúng trở nên phổ biến. Tuy nhiên, tính không thể đoán trước đó có nghĩa là cộng đồng phải siêng năng theo dõi nội dung của họ để đảm bảo rằng nội dung đó đáp ứng các nguyên tắc cộng đồng hoặc chính sách sử dụng được chấp nhận và phù hợp, an toàn và chào đón tất cả người dùng. Điều này thường dẫn đến một hệ thống kiểm duyệt nơi người dùng báo cáo các hành vi vi phạm có thể xảy ra với nguyên tắc cộng đồng và người kiểm duyệt hoặc quản trị viên sẽ thực hiện hành động khi cần thiết. Đây thường là một quy trình thủ công để lại nhiều điều mong muốn.
Các công cụ Trí tuệ nhân tạo (AI) và Máy học (ML) đã được cải thiện trong những năm gần đây và các nhà phát triển có thể sử dụng các công cụ này để hỗ trợ kiểm duyệt cộng đồng của họ. Trong bài đăng này, chúng ta sẽ xem xét một cách để thực hiện điều đó với Amazon Interactive Video Service (Amazon IVS) và Amazon Rekognition.
Phân tích mọi khung hình của mọi luồng trực tiếp trong một ứng dụng bằng AI/ML sẽ là một nhiệm vụ rất tốn kém và khó khăn. Thay vào đó, nhà phát triển có thể phân tích các mẫu luồng trực tiếp trong ứng dụng của họ theo tần suất cụ thể để hỗ trợ người điều hành bằng cách thông báo cho họ nếu có nội dung cần được người điều hành xem xét thêm. Đây không phải là giải pháp hoàn hảo 100% nhưng là một cách để tự động kiểm duyệt nội dung và giúp công việc của người kiểm duyệt dễ dàng hơn.
Giải pháp này bao gồm các bước sau:
Chúng tôi sẽ sử dụng AWS Serverless Application Model (SAM) để dễ dàng tạo quy tắc và chức năng. Đây là toàn bộ tệp template.yaml
mô tả các quyền cần thiết, quy tắc Amazon EventBridge, lớp AWS Lambda (dành cho phụ thuộc AWS SDK) và định nghĩa hàm. Chúng tôi sẽ phá vỡ điều này dưới đây.
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/"
Có rất nhiều thứ đang diễn ra trong tệp đó, vì vậy hãy chia nhỏ nó ra một chút. Đầu tiên, chúng tôi tạo một lớp để cho phép đưa AWS SDK cho JavaScript (v3) vào chức năng của chúng tôi.
IvsChatLambdaRefLayer: Type: AWS::Serverless::LayerVersion Properties: LayerName: sam-app-dependencies Description: Dependencies for sam app ContentUri: dependencies/ CompatibleRuntimes: - nodejs18.x LicenseInfo: "MIT" RetentionPolicy: Retain
Trong thư mục dependencies/nodejs
, có một tệp package.json
bao gồm các mô-đun mà chức năng của chúng ta cần.
{ "dependencies": { "@aws-sdk/client-ivs": "^3.289.0", "@aws-sdk/client-ivschat": "^3.289.0", "@aws-sdk/client-rekognition": "^3.289.0" } }
Phần tiếp theo, được xác định bởi các khóa IVSAccessPolicy
và APIAccessPolicy
cung cấp cho ứng dụng không có máy chủ của chúng tôi khả năng truy cập các API cần thiết ( s3:GetObject
, s3:GetObjectAcl
, ivschat:SendEvent
, ivs:StopStream
và rekognition:DetectModerationLabels
) và hiển thị phương thức dừng luồng mà chúng tôi sẽ tạo bên dưới thông qua Amazon API Gateway.
Tiếp theo, chúng ta tạo quy tắc Amazon EventBridge. Thuộc tính name
bên dưới bucket
phải khớp với tên của bộ chứa Amazon S3 mà bạn đã định cấu hình trong cấu hình bản ghi của mình. Ghi vào Amazon S3 tạo ra nhiều tệp khác nhau, bao gồm danh sách phát và phương tiện HLS, vì vậy chúng tôi có thể lọc quy tắc này để chỉ kích hoạt cho hình thu nhỏ của mình bằng cách đặt key
bên dưới object
thành 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
Tiếp theo, chúng tôi cấp cho quy tắc các quyền cần thiết để gọi hàm AWS Lambda.
PermissionForEventsToInvokeLambda: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref ModerateImage Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt EventRule.Arn
Bây giờ, chúng ta có thể xác định hàm sẽ được gọi theo quy tắc 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/
Lưu ý: Tôi đang khai báo DEMO_CHAT_ARN
và DEMO_CHANNEL_ARN
là các biến môi trường, nhưng ứng dụng của bạn có thể sẽ lấy các giá trị ARN từ sự kiện được truyền vào hàm vì bạn có thể sẽ sử dụng chức năng này với nhiều hơn một kênh Amazon IVS.
Cuối cùng, chúng ta có thể xác định chức năng sẽ được sử dụng để dừng luồng, nếu cần.
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
Bây giờ chúng ta đã mô tả cơ sở hạ tầng của mình với AWS SAM, hãy tạo các chức năng mà chúng ta đã mô tả. Trong index.mjs
, chúng tôi import
các lớp SDK, truy xuất các giá trị Arn từ các biến môi trường mà chúng tôi đã chuyển vào và tạo các phiên bản của ứng dụng khách cần thiết cho các chức năng của chúng tôi.
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();
Hàm moderateImage
sẽ nhận sự kiện Amazon EventBridge, trích xuất bucket
và key
từ sự kiện, đồng thời gửi DetectModerationLabelsCommand
qua rekognitionClient
để phát hiện mọi nội dung không phù hợp hoặc xúc phạm trong hình ảnh dựa trên các danh mục
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); } };
Nếu cần, hàm moderateImage
gọi sendEvent
để phát hành một sự kiện tùy chỉnh tới mọi máy khách được kết nối giao diện người dùng phía trước với một phòng trò chuyện Amazon IVS nhất định.
const sendEvent = async (eventName, eventDetails) => { const sendEventInput = { roomIdentifier: chatArn, attributes: { streamModerationEvent: JSON.stringify(eventDetails), }, eventName, }; const sendEventRequest = new SendEventCommand(sendEventInput); await ivsChatClient.send(sendEventRequest); };
Giao diện người dùng của bạn có thể quyết định cách xử lý sự kiện này và logic để xuất bản sự kiện này sẽ tùy thuộc vào nhu cầu kinh doanh của bạn. Có thể bạn muốn kích hoạt báo thức tùy chỉnh trong CloudWatch, gửi email hoặc xuất bản thông báo qua Amazon SNS? Nhu cầu của mọi ứng dụng là khác nhau, nhưng dữ liệu kiểm duyệt có sẵn tại thời điểm này để thực hiện những gì bạn cần.
Phương thức stopStream
sử dụng ivsClient
để gửi StopStreamCommand
. Một lần nữa, việc thực hiện điều này là tùy thuộc vào bạn. Bạn thậm chí có thể tự động hóa hoàn toàn lệnh này nếu kết quả Amazon Rekognition khớp với một danh mục nhất định hoặc vượt quá mức độ tin cậy.
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; };
Trong bản trình diễn của mình, tôi đã quyết định lắng nghe các sự kiện tùy chỉnh và hiển thị kết quả trong chế độ xem của người kiểm duyệt hiển thị mục được phát hiện và mức độ tin cậy. Tôi cũng trình bày cho người kiểm duyệt nút 'Dừng phát trực tiếp' để gọi phương thức stopStream
thông qua Cổng API Amazon được hiển thị.
Trong bài đăng này, chúng ta đã học cách sử dụng Amazon Rekognition để hỗ trợ người kiểm duyệt con người kiểm duyệt nội dung trong các ứng dụng mà họ xây dựng bằng Amazon IVS. Nếu bạn muốn tìm hiểu thêm về cách Amazon IVS có thể giúp tạo ra các cộng đồng UGC an toàn hơn, hãy xem các bài đăng blog sau: