La interactividad y la imprevisibilidad de las plataformas de contenido generado por el usuario (UGC) de transmisión en vivo son una gran parte de por qué son tan populares. Pero esa imprevisibilidad significa que las comunidades deben ser diligentes en el control de su contenido para asegurarse de que cumpla con las pautas de la comunidad o la política de uso aceptable y sea apropiado, seguro y acogedor para todos los usuarios. Esto a menudo da como resultado un sistema de moderación en el que los usuarios informan sobre posibles infracciones a las pautas de la comunidad y los moderadores o administradores toman las medidas necesarias. Este es a menudo un proceso manual que deja mucho que desear.
Las herramientas de inteligencia artificial (IA) y aprendizaje automático (ML) han mejorado en los últimos años, y los desarrolladores pueden usar estas herramientas para ayudar a moderar sus comunidades. En esta publicación, veremos una forma de hacerlo con Amazon Interactive Video Service (Amazon IVS) y Amazon Rekognition.
Analizar cada cuadro de cada transmisión en vivo en una aplicación con AI/ML sería una tarea muy costosa y difícil. En cambio, los desarrolladores pueden analizar muestras de las transmisiones en vivo en sus aplicaciones en una frecuencia específica para ayudar a sus moderadores al alertarlos si hay contenido que necesita una revisión adicional por parte de un moderador humano. No es una solución 100% perfecta, pero es una forma de automatizar la moderación de contenido y ayudar a facilitar el trabajo de los moderadores.
Esta solución implica los siguientes pasos:
Usaremos el modelo de aplicación sin servidor (SAM) de AWS para facilitar la creación de la regla y las funciones. Aquí está el archivo template.yaml
completo que describe los permisos necesarios, la regla de Amazon EventBridge, la capa de AWS Lambda (para la dependencia del SDK de AWS) y las definiciones de funciones. Desglosaremos esto a continuación.
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/"
Están sucediendo muchas cosas en ese archivo, así que analicemos un poco. Primero, creamos una capa para permitir la inclusión de AWS SDK for JavaScript (v3) en nuestra función.
IvsChatLambdaRefLayer: Type: AWS::Serverless::LayerVersion Properties: LayerName: sam-app-dependencies Description: Dependencies for sam app ContentUri: dependencies/ CompatibleRuntimes: - nodejs18.x LicenseInfo: "MIT" RetentionPolicy: Retain
En el directorio dependencies/nodejs
hay un archivo package.json
que incluye los módulos que necesita nuestra función.
{ "dependencies": { "@aws-sdk/client-ivs": "^3.289.0", "@aws-sdk/client-ivschat": "^3.289.0", "@aws-sdk/client-rekognition": "^3.289.0" } }
La siguiente sección, identificada por las claves IVSAccessPolicy
y APIAccessPolicy
, brinda a nuestra aplicación sin servidor la capacidad de acceder a las API necesarias ( s3:GetObject
, s3:GetObjectAcl
, ivschat:SendEvent
, ivs:StopStream
y rekognition:DetectModerationLabels
) y exponer el método de detener flujo que crearemos a continuación a través de Amazon API Gateway.
A continuación, creamos la regla de Amazon EventBridge. La propiedad name
debajo bucket
debe coincidir con el nombre del depósito de Amazon S3 que configuró en su configuración de grabación. La grabación en Amazon S3 crea varios archivos, incluidas listas de reproducción y medios HLS, por lo que podemos filtrar esta regla para activar solo nuestras miniaturas configurando la key
debajo del object
para que tenga 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
A continuación, otorgamos a la regla los permisos necesarios para invocar la función AWS Lambda.
PermissionForEventsToInvokeLambda: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref ModerateImage Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt EventRule.Arn
Ahora podemos definir nuestra función que será invocada por la regla de 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/
Nota: Declaro DEMO_CHAT_ARN
y DEMO_CHANNEL_ARN
como variables de entorno, pero es probable que su aplicación obtenga los valores de ARN del evento pasado a la función, ya que probablemente usaría esta funcionalidad con más de un solo canal de Amazon IVS.
Finalmente, podemos definir la función que se usará para detener una transmisión, si es necesario.
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
Ahora que hemos descrito nuestra infraestructura con AWS SAM, creemos las funciones que describimos. En index.mjs
, import
las clases SDK, recuperamos los valores Arn de las variables de entorno que pasamos y creamos instancias de los clientes necesarios para nuestras funciones.
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();
La función moderateImage
recibirá el evento de Amazon EventBridge, extraerá el bucket
y key
del evento y enviará un DetectModerationLabelsCommand
a través de rekognitionClient
para detectar cualquier contenido inapropiado u ofensivo en las imágenes según las categorías.
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); } };
Si es necesario, la función moderateImage
llama a sendEvent
para publicar un evento personalizado en cualquier cliente conectado a una sala de chat de Amazon IVS determinada.
const sendEvent = async (eventName, eventDetails) => { const sendEventInput = { roomIdentifier: chatArn, attributes: { streamModerationEvent: JSON.stringify(eventDetails), }, eventName, }; const sendEventRequest = new SendEventCommand(sendEventInput); await ivsChatClient.send(sendEventRequest); };
Su front-end puede decidir cómo manejar este evento y la lógica para publicar este evento dependerá de las necesidades de su negocio. ¿Tal vez prefiera activar una alarma personalizada en CloudWatch, enviar un correo electrónico o publicar una notificación a través de Amazon SNS? Las necesidades de cada aplicación difieren, pero los datos de moderación están disponibles en este punto para hacer con ellos lo que necesites.
El método stopStream
usa ivsClient
para enviar un StopStreamCommand
. Nuevamente, la implementación de esto depende de usted. Incluso podría automatizar por completo este comando si el resultado de Amazon Rekognition coincide con una determinada categoría o supera un nivel de confianza.
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; };
En mi demostración, decidí escuchar los eventos personalizados y mostrar los resultados en una vista de moderador que muestra el elemento detectado y el nivel de confianza. También le presento al moderador un botón 'Detener flujo' que invoca el método stopStream
a través de Amazon API Gateway expuesto.
En esta publicación, aprendimos a usar Amazon Rekognition para ayudar a los moderadores humanos a moderar el contenido de las aplicaciones que crean con Amazon IVS. Si desea obtener más información sobre cómo Amazon IVS puede ayudar a crear comunidades UGC más seguras, consulte las siguientes publicaciones de blog: