Subir Videos
Section titled “Subir Videos”TalentBricksAI usa AWS S3 para almacenar videos y CloudFront para streaming optimizado.
Arquitectura
Section titled “Arquitectura”┌────────────────┐ ┌────────────────┐ ┌────────────────┐│ Usuario │────▶│ CloudFront │────▶│ S3 Bucket ││ (Video Player)│ │ (CDN) │ │ (Storage) │└────────────────┘ └────────────────┘ └────────────────┘ │ ▼ URLs Firmadas (Acceso Temporizado)Configuracion de AWS
Section titled “Configuracion de AWS”1. Crear Bucket S3
Section titled “1. Crear Bucket S3”# Crear bucketaws s3 mb s3://talentbricksai-videos --region us-east-1
# Configurar como privado (por defecto)aws s3api put-public-access-block \ --bucket talentbricksai-videos \ --public-access-block-configuration \ "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"2. Estructura de Carpetas
Section titled “2. Estructura de Carpetas”talentbricksai-videos/├── courses/│ ├── fundamentos-data-engineering/│ │ ├── 01-introduccion.mp4│ │ ├── 02-conceptos.mp4│ │ └── thumbnail.jpg│ └── ml-basico/│ ├── 01-intro.mp4│ └── thumbnail.jpg└── assets/ └── common/3. Politica IAM
Section titled “3. Politica IAM”Crear un usuario IAM con permisos minimos:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::talentbricksai-videos/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::talentbricksai-videos" } ]}Subir Videos
Section titled “Subir Videos”Opcion 1: AWS CLI
Section titled “Opcion 1: AWS CLI”# Subir un videoaws s3 cp ./video.mp4 s3://talentbricksai-videos/courses/mi-curso/01-intro.mp4
# Subir carpeta completaaws s3 sync ./videos/ s3://talentbricksai-videos/courses/mi-curso/Opcion 2: Consola AWS
Section titled “Opcion 2: Consola AWS”- Ir a S3 en la consola de AWS
- Seleccionar el bucket
- Click en “Upload”
- Arrastrar archivos
Opcion 3: Desde la Aplicacion (Admin)
Section titled “Opcion 3: Desde la Aplicacion (Admin)”La aplicacion incluye funcionalidad de upload usando presigned URLs:
// El admin panel genera URLs de subidaconst { uploadUrl, fileUrl } = await generateUploadUrl({ fileName: 'video.mp4', contentType: 'video/mp4'});
// Subir directamente a S3await fetch(uploadUrl, { method: 'PUT', body: videoFile, headers: { 'Content-Type': 'video/mp4' }});Configuracion de CloudFront
Section titled “Configuracion de CloudFront”1. Crear Distribucion
Section titled “1. Crear Distribucion”En la consola de AWS CloudFront:
- Click “Create Distribution”
- Origin Domain:
talentbricksai-videos.s3.us-east-1.amazonaws.com - Origin Access: “Origin access control settings (recommended)”
- Crear nuevo OAC (Origin Access Control)
2. Configurar Comportamientos
Section titled “2. Configurar Comportamientos”| Setting | Valor |
|---|---|
| Viewer Protocol Policy | Redirect HTTP to HTTPS |
| Allowed HTTP Methods | GET, HEAD |
| Cache Policy | CachingOptimized |
| Compress Objects | Yes |
3. URLs Firmadas (Signed URLs)
Section titled “3. URLs Firmadas (Signed URLs)”Para contenido privado, usar URLs firmadas:
import { getSignedUrl } from '@aws-sdk/cloudfront-signer';
export function generateVideoUrl(videoPath: string): string { const url = `https://d123abc.cloudfront.net/${videoPath}`;
return getSignedUrl({ url, keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID!, privateKey: process.env.CLOUDFRONT_PRIVATE_KEY!, dateLessThan: new Date(Date.now() + 3600 * 1000).toISOString(), // 1 hora });}4. Actualizar Politica del Bucket
Section titled “4. Actualizar Politica del Bucket”Permitir acceso desde CloudFront:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::talentbricksai-videos/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DISTRIBUTION_ID" } } } ]}Formatos de Video Recomendados
Section titled “Formatos de Video Recomendados”| Setting | Valor Recomendado |
|---|---|
| Formato | MP4 (H.264) |
| Resolucion | 1080p (1920x1080) |
| Bitrate | 5-8 Mbps |
| Audio | AAC, 128-192 kbps |
| Frame Rate | 30 fps |
Compresion con FFmpeg
Section titled “Compresion con FFmpeg”# Comprimir video para webffmpeg -i input.mov \ -c:v libx264 -preset slow -crf 22 \ -c:a aac -b:a 128k \ -movflags +faststart \ output.mp4Costos Estimados
Section titled “Costos Estimados”| Servicio | Costo |
|---|---|
| S3 Storage | ~$0.023/GB/mes |
| S3 Requests | ~$0.0004/1000 GET |
| CloudFront Transfer | ~$0.085/GB (primeros 10TB) |
| CloudFront Requests | ~$0.0075/10000 |
Ejemplo: 100GB de videos, 1000 visualizaciones/mes
Section titled “Ejemplo: 100GB de videos, 1000 visualizaciones/mes”- Storage: 100GB × $0.023 = $2.30/mes
- Transfer: ~50GB × $0.085 = $4.25/mes
- Total: ~$6.55/mes
Variables de Entorno
Section titled “Variables de Entorno”Agregar a .env.server:
# AWS S3AWS_ACCESS_KEY_ID=AKIA...AWS_SECRET_ACCESS_KEY=...AWS_S3_BUCKET=talentbricksai-videosAWS_S3_REGION=us-east-1
# CloudFront (para URLs firmadas)CLOUDFRONT_DOMAIN=d123abc.cloudfront.netCLOUDFRONT_KEY_PAIR_ID=K123...CLOUDFRONT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n..."Integracion con el Video Player
Section titled “Integracion con el Video Player”El componente VideoPlayer usa las URLs firmadas:
export function VideoPlayer({ lesson }: { lesson: Lesson }) { const { data: videoUrl } = useQuery(getSignedVideoUrl, { lessonId: lesson.id });
return ( <video src={videoUrl} controls onTimeUpdate={handleProgress} /> );}Siguiente Paso
Section titled “Siguiente Paso”- Configurar Pagos - Habilitar compras de cursos