---
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
