--- id: "US-EDU-004" title: "Ver Video de Leccion" type: "User Story" status: "Done" priority: "Alta" epic: "OQI-002" story_points: 3 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-EDU-004: Ver Video de Lección ## Metadata | Campo | Valor | |-------|-------| | **ID** | US-EDU-004 | | **Épica** | OQI-002 - Módulo Educativo | | **Módulo** | education | | **Prioridad** | P0 | | **Story Points** | 3 | | **Sprint** | Sprint 3 | | **Estado** | Pendiente | | **Asignado a** | Por asignar | --- ## Historia de Usuario **Como** usuario inscrito viendo una lección de video, **quiero** reproducir el video con controles completos y funcionalidades avanzadas, **para** consumir el contenido educativo de manera cómoda y eficiente. ## Descripción Detallada El usuario debe poder reproducir videos educativos con un reproductor profesional que incluya controles estándar (play/pause, volumen, pantalla completa), funcionalidades avanzadas (velocidad de reproducción, subtítulos, picture-in-picture), navegación temporal, y auto-guardado de progreso. El sistema debe recordar la posición de reproducción y permitir saltos rápidos. ## Mockups/Wireframes ``` ┌─────────────────────────────────────────────────────────────────┐ │ Lección 2.1: Niveles principales de Fibonacci │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ [VIDEO REPRODUCIÉNDOSE] │ │ │ │ │ │ │ │ Carlos explicando │ │ │ │ niveles de Fibonacci │ │ │ │ │ │ │ │ │ │ │ │ ━━━━━━━━━━●━━━━━━━━━━━━━━━━━━━━━━━━━━ 05:30 / 12:15 │ │ │ │ ⏮ ⏸ ⏭ 🔊──────● ⚙ 1.25x [CC] [PIP] ⛶ │ │ │ │ │ │ │ │ Capítulos: │ │ │ │ • 0:00 - Introducción │ │ │ │ • 2:15 - Nivel 38.2% │ │ │ │ • 5:30 - Nivel 50% ← Actual │ │ │ │ • 8:45 - Nivel 61.8% │ │ │ │ • 11:00 - Conclusión │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ CONTROLES: │ │ • Espacio: Play/Pause │ │ • →: Adelantar 10s │ │ • ←: Retroceder 10s │ │ • F: Pantalla completa │ │ • M: Silenciar │ │ • 0-9: Saltar a ese % del video │ │ │ └─────────────────────────────────────────────────────────────────┘ [MENÚ DE VELOCIDAD] ┌──────────────┐ │ Velocidad │ │ ○ 0.5x │ │ ○ 0.75x │ │ ● 1x │ ← Seleccionado │ ○ 1.25x │ │ ○ 1.5x │ │ ○ 2x │ └──────────────┘ [MENÚ DE CALIDAD] ┌──────────────┐ │ Calidad │ │ ● Auto │ ← Adaptativa │ ○ 1080p │ │ ○ 720p │ │ ○ 480p │ │ ○ 360p │ └──────────────┘ [SUBTÍTULOS] ┌──────────────┐ │ Subtítulos │ │ ● Desactivado│ │ ○ Español │ │ ○ English │ └──────────────┘ ``` --- ## Criterios de Aceptación **Escenario 1: Reproducir video** ```gherkin DADO que el usuario accedió a una lección de video CUANDO el reproductor carga ENTONCES se muestra el video con controles Y el video está pausado inicialmente Y se muestra duración total Y se carga en la última posición guardada (si existe) Y se muestra toast "Continuando desde X:XX" ``` **Escenario 2: Controles básicos funcionan** ```gherkin DADO que el video está cargado CUANDO el usuario hace click en Play ENTONCES el video se reproduce Y el botón cambia a Pause ⏸ Y la barra de progreso avanza Y el tiempo actual se actualiza cada segundo ``` **Escenario 3: Cambiar velocidad de reproducción** ```gherkin DADO que el video se está reproduciendo a 1x CUANDO el usuario selecciona velocidad 1.5x ENTONCES el video se reproduce 50% más rápido Y el audio se ajusta automáticamente (sin distorsión) Y se muestra indicador "1.5x" en el reproductor Y la configuración se guarda para próximos videos ``` **Escenario 4: Activar subtítulos** ```gherkin DADO que el video tiene subtítulos en español CUANDO el usuario activa subtítulos ENTONCES aparecen subtítulos sincronizados con el audio Y se pueden personalizar tamaño y posición Y la preferencia se guarda para próximos videos ``` **Escenario 5: Saltar a posición específica** ```gherkin DADO que el video se está reproduciendo CUANDO el usuario hace click en la barra de progreso ENTONCES el video salta a esa posición Y se muestra preview al hacer hover sobre la barra Y la nueva posición se guarda automáticamente ``` **Escenario 6: Auto-guardado de progreso** ```gherkin DADO que el usuario está viendo un video Y el video alcanza la posición 7:30 CUANDO pasan 10 segundos ENTONCES se guarda la posición en backend Y si el usuario cierra la página y vuelve ENTONCES el video se carga en 7:30 ``` **Escenario 7: Atajos de teclado** ```gherkin DADO que el usuario está viendo un video CUANDO presiona la tecla → ENTONCES el video avanza 10 segundos Y se muestra indicador "+10s" CUANDO presiona la tecla ← ENTONCES el video retrocede 10 segundos Y se muestra indicador "-10s" CUANDO presiona Espacio ENTONCES el video pausa/reanuda CUANDO presiona F ENTONCES entra/sale de pantalla completa ``` **Escenario 8: Picture-in-Picture** ```gherkin DADO que el video se está reproduciendo CUANDO el usuario hace click en botón PIP ENTONCES el video se minimiza en una ventana flotante Y puede navegar a otras páginas mientras ve el video Y los controles básicos están disponibles en PIP Y al cerrar PIP, vuelve al reproductor normal ``` **Escenario 9: Capítulos del video** ```gherkin DADO que el video tiene capítulos definidos CUANDO el usuario hace click en un capítulo ENTONCES el video salta a ese timestamp Y se muestra marcador de capítulo en la barra de progreso Y al hacer hover en la barra, muestra nombre del capítulo ``` **Escenario 10: Completar video automáticamente** ```gherkin DADO que el usuario está viendo un video CUANDO el video alcanza el 90% de reproducción ENTONCES la lección se marca automáticamente como completada Y se muestra toast "Lección completada +10 XP" Y se actualiza el progreso del curso Y se desbloquea siguiente lección (si es secuencial) ``` ## Criterios Adicionales - [ ] Calidad adaptativa según ancho de banda - [ ] Buffer progresivo para evitar cortes - [ ] Indicador de buffering cuando carga - [ ] Manejo de errores (video no disponible, error de red) - [ ] Analytics: pausas, rewinds, abandonos - [ ] Thumbnail preview al hover sobre barra de progreso - [ ] Continuar reproduciendo al cambiar de pestaña (background play) --- ## Tareas Técnicas **Database:** - [ ] DB-EDU-010: Tabla video_chapters (video_id, time, title) - [ ] DB-EDU-011: Actualizar user_lesson_progress.last_position cada 10s **Backend:** - [ ] BE-EDU-022: Endpoint POST /education/lessons/:id/progress - [ ] BE-EDU-023: Endpoint GET /education/videos/:id/chapters - [ ] BE-EDU-024: Generar signed URLs para Vimeo/S3 - [ ] BE-EDU-025: Implementar validación de acceso a video - [ ] BE-EDU-026: Webhook de Vimeo para confirmar encoding completado - [ ] BE-EDU-027: Rate limiting en auto-save (máx cada 5s) **Frontend:** - [ ] FE-EDU-026: Implementar VideoPlayer.tsx con React Player - [ ] FE-EDU-027: Custom controls overlay - [ ] FE-EDU-028: Speed control menu - [ ] FE-EDU-029: Subtitles toggle y customización - [ ] FE-EDU-030: Keyboard shortcuts (arrow keys, space, f, m) - [ ] FE-EDU-031: Picture-in-Picture implementation - [ ] FE-EDU-032: Progress bar con preview thumbnail - [ ] FE-EDU-033: Chapters navigation - [ ] FE-EDU-034: Auto-save de posición cada 10s - [ ] FE-EDU-035: Restore position on load - [ ] FE-EDU-036: Analytics tracking (play, pause, seek, complete) - [ ] FE-EDU-037: Loading spinner y error states **Tests:** - [ ] TEST-EDU-011: Test auto-save de progreso - [ ] TEST-EDU-012: Test restaurar posición guardada - [ ] TEST-EDU-013: Test marcar completado al 90% - [ ] TEST-EDU-014: Test E2E reproducir video completo --- ## Dependencias **Depende de:** - [ ] US-EDU-003: Iniciar lección - Estado: Pendiente - [ ] Video CDN: Vimeo Pro o AWS S3 + CloudFront **Bloquea:** - [ ] US-EDU-005: Completar lección - [ ] US-EDU-007: Ver progreso --- ## Notas Técnicas **CDN de Videos:** - Opción 1: Vimeo Pro (recomendado para MVP) - API robusta - Encoding automático - Streaming adaptativo HLS - Subtítulos integrados - Analytics incluido - Opción 2: AWS S3 + CloudFront + MediaConvert - Más control - Más setup inicial - Costos variables **Librerías recomendadas:** - React Player: Wrapper para múltiples providers - Video.js: Player HTML5 completo y customizable - Plyr: Alternativa moderna y ligera **Auto-save strategy:** ```javascript // Guardar posición cada 10s mientras reproduce useEffect(() => { const interval = setInterval(() => { if (isPlaying) { saveProgress(currentTime); } }, 10000); return () => clearInterval(interval); }, [isPlaying, currentTime]); // Guardar al pausar const handlePause = () => { saveProgress(currentTime); }; // Guardar antes de salir useEffect(() => { return () => { saveProgress(currentTime); }; }, []); ``` **Analytics events:** - `video_started`: Primera reproducción - `video_played`: Cada vez que presiona play - `video_paused`: Cada pausa - `video_seeked`: Salto manual - `video_completed`: Alcanza 90% - `video_speed_changed`: Cambia velocidad - `video_quality_changed`: Cambia calidad **Entidades/Tablas:** - `education.lessons` (campo videoUrl) - `education.video_chapters` - `education.user_lesson_progress` (campo last_position) --- ## Definition of Ready (DoR) - [x] Historia claramente escrita - [x] Criterios de aceptación definidos - [x] Story points estimados - [x] Dependencias identificadas - [x] Sin bloqueadores - [x] Diseño/mockup disponible - [x] API spec disponible ## Definition of Done (DoD) - [ ] Código implementado según criterios - [ ] Tests unitarios escritos y pasando - [ ] Tests de integración pasando - [ ] Code review aprobado - [ ] Documentación actualizada - [ ] QA aprobado - [ ] Desplegado en ambiente de pruebas --- ## Historial de Cambios | Fecha | Cambio | Autor | |-------|--------|-------| | 2025-12-05 | Creación | Requirements-Analyst | --- **Creada por:** Requirements-Analyst **Fecha:** 2025-12-05 **Última actualización:** 2025-12-05