尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Plataforma de streaming libre y de código abierto para el cine independiente: cortometrajes, películas y series de creadores que suben, publican y comparten su obra.
Qué es · Funciones · Arquitectura · Empezar · Contribuir · Hoja de ruta
GMA Filmo nace de la comunidad Generación Maldita con una idea sencilla: que el cine hecho fuera de los grandes estudios tenga una casa propia, cuidada y abierta.
Es una plataforma de streaming completa (catálogo, reproductor, perfiles, valoraciones, comunidad) en la que los propios creadores suben y publican su obra desde un estudio integrado. Y es open source: cualquiera puede leer el código, ejecutarlo, mejorarlo o usarlo como base para su propia plataforma.
🍿 Para el público Un catálogo navegable como el de cualquier gran plataforma, con perfiles, lista personal, «seguir viendo», valoraciones y comentarios.
🎥 Para quien crea Un perfil público de creador, enlaces sociales, opción de recibir apoyo y Mi Estudio para subir películas, tráileres, subtítulos y extras.
🛠️ Para quien programa Un proyecto real en Next.js + Supabase con un motor multimedia propio, neutral respecto al proveedor de vídeo y cubierto por pruebas.
| Función | Qué hace | |
|---|---|---|
| 🏠 | Inicio | Cabecera ambiental con tráiler, carruseles por colección, Top 10 y recomendaciones por perfil |
| 🎞️ | Catálogo | Cortos, películas y series, con colecciones y filtros por género |
| 🔎 | Buscador | Búsqueda por título y por autor en todo el catálogo |
| 📄 | Ficha del título | Sinopsis, créditos, extras, títulos relacionados, valoraciones y comentarios |
| ▶️ | Reproductor | Pantalla completa con HLS (nativo o hls.js), subtítulos y progreso guardado por perfil; también reproduce el contenido histórico en MP4 y YouTube |
| Función | Qué hace | |
|---|---|---|
| 👥 | Perfiles | Varios perfiles por cuenta, con avatar propio, modo infantil y bloqueo por PIN |
| 📌 | Mi Espacio | Lista personal, historial y «seguir viendo» |
| ⭐ | Valoraciones | Puntuación por estrellas y nota media pública por título |
| 💬 | Comentarios | Respuestas, «me gusta», orden, comentarios en un momento concreto del vídeo y reporte de contenido |
| ✍️ | Propuestas de sinopsis | La comunidad puede sugerir mejoras a las fichas |
| 🔐 | Acceso | Email y contraseña o Google (Supabase Auth), y navegación como invitado |
| Función | Qué hace | |
|---|---|---|
| 🧑🎨 | Perfil de creador | Página pública con filmografía, biografía y redes sociales |
| 💛 | Apoyar al creador | Página de apoyo directo a cada creador |
| 🎛️ | Mi Estudio | Asistente de subida con ficha completa: película, tráiler, póster, subtítulos y extras |
| ⏯️ | Subidas reanudables | Si se corta la conexión, la subida continúa donde se quedó; cada archivo se verifica por tamaño y huella SHA-256 |
GMA Filmo separa con claridad quién decide (la aplicación y la base de datos) de quién mueve los bytes (el proveedor de vídeo y una pasarela propia). Así, las películas nunca pasan por el servidor web y el proveedor de vídeo se puede cambiar sin tocar la interfaz.
flowchart LR
subgraph Navegador
UI["🖥️ Web GMA Filmo<br/>catálogo · Mi Estudio · reproductor"]
end
subgraph Aplicación["Aplicación (Next.js)"]
API["API GMA<br/>autorización · ficha · cuotas"]
MS["Motor multimedia<br/>MediaService + proveedores"]
end
subgraph Datos
DB[("Supabase<br/>Auth + PostgreSQL con RLS")]
end
subgraph Vídeo["Servidor de vídeo"]
GW["Pasarela GMA<br/>subidas + HLS autorizado"]
PT["PeerTube<br/>transcodificación · HLS privado"]
end
UI -->|JSON| API
API --> DB
API --> MS
MS -->|REST, credenciales solo en servidor| PT
UI -->|bytes + capacidad firmada| GW
GW --> PT
PT -->|HLS privado| GW
GW -->|HLS autorizado| UI
Principios del diseño
lib/media/ define un contrato MediaProvider con varias implementaciones: peertube (producción), mock (desarrollo local, sin dependencias externas), y r2 / stream para compatibilidad con contenido anterior.UPLOAD_ENGINE_V2, NEXT_PUBLIC_UPLOAD_ENGINE_V2, UPLOADS_PAUSED…).sequenceDiagram
autonumber
actor C as Creador
participant S as Mi Estudio
participant A as API GMA
participant G as Pasarela
participant P as PeerTube
C->>S: Elige el archivo y rellena la ficha
S->>S: Calcula la huella SHA-256 (Web Worker)
S->>A: Pide una sesión de subida
A-->>S: Capacidad firmada de corta duración
S->>G: Envía los bytes por partes (reanudable)
G->>P: Retransmite al proveedor
P-->>A: Vídeo procesado en HLS
A->>A: Verifica tamaño, huella y duración
C->>S: Publica el título
Note over A: Desde aquí aparece en el catálogo
S->>G: El espectador pide el HLS con su capacidad
G-->>S: Segmentos autorizados
| Capa | Tecnología |
|---|---|
| Framework | Next.js 14 (App Router) · React 18 · TypeScript |
| Interfaz | Tailwind CSS 4 · shadcn/ui · Radix · Motion · Iconoir |
| Estado y validación | Zustand · Zod |
| Cuentas y datos | Supabase: Auth + PostgreSQL con Row Level Security |
| Vídeo | PeerTube (privado, HLS) · hls.js · pasarela propia en Node |
| Subidas | Hash SHA-256 en Web Worker (hash-wasm) · transportes uploadx, tus y multipart |
| Imágenes y auxiliares | sharp · Cloudflare R2 |
| Pruebas | Playwright (e2e, responsive, estudio) · node:test con tsx · PGlite |
| Despliegue | Vercel (web) · servidor propio con PeerTube y la pasarela |
# 1. Clona el repositorio
git clone https://github.com/gfromtheD/gma-filmo.git
cd gma-filmo
# 2. Instala las dependencias
npm install
# 3. Crea tu archivo de entorno a partir de la plantilla
cp .env.uploads.example .env.local
# y rellena al menos NEXT_PUBLIC_SUPABASE_URL y NEXT_PUBLIC_SUPABASE_ANON_KEY
# 4. Arranca el servidor de desarrollo
npm run dev
Abre http://localhost:3000 y listo. Con el motor apagado (valor por defecto) tendrás el catálogo, el reproductor y toda la parte social funcionando.
El esquema completo vive en supabase/migrations/. Ejecuta cada archivo en el editor SQL de Supabase en orden de fecha (el prefijo del nombre), empezando por comments_system.sql y dm_system.sql, que no llevan fecha. Las migraciones son aditivas e idempotentes: ninguna borra datos y se pueden repetir sin riesgo.
El motor incluye un proveedor Mock que transfiere bytes reales por HTTP, verifica la huella y entrega un HLS de prueba. No necesitas PeerTube ni cuentas en la nube.
npm run media:local-keys # genera las claves Ed25519 locales
npm run media:fixtures # crea los vídeos de prueba
npm run media:local:prepare # prepara Supabase local aislado (Docker)
npm run media:local:start # levanta web, pasarela y base de datos
La plantilla .env.media.example contiene la configuración local segura. Más detalle en infrastructure/media-local/README.md.
| Variable | Para qué sirve |
|---|---|
NEXT_PUBLIC_SUPABASE_URL · NEXT_PUBLIC_SUPABASE_ANON_KEY | Conexión pública a Supabase (protegida por RLS) |
SUPABASE_URL · SUPABASE_SERVICE_ROLE_KEY · SUPABASE_DB_URL | Acceso de servidor. Nunca con prefijo NEXT_PUBLIC_ |
UPLOAD_ENGINE_V2 · NEXT_PUBLIC_UPLOAD_ENGINE_V2 | Enciende el motor multimedia nuevo |
UPLOADS_PAUSED | Pausa las subidas nuevas sin afectar a la reproducción |
MEDIA_VIDEO_PROVIDER · MEDIA_AUXILIARY_PROVIDER | Proveedor de vídeo y de archivos auxiliares (mock, peertube, r2) |
MEDIA_GATEWAY_URL | Dirección de la pasarela de medios |
MEDIA_CAPABILITY_* | Claves Ed25519 para firmar las autorizaciones |
PEERTUBE_* | Conexión a la instancia de PeerTube (solo servidor) |
Las plantillas completas están en .env.uploads.example, .env.media.example e infrastructure/peertube/env.example. Ninguna contiene secretos reales: no subas nunca los tuyos.
npm run lint # análisis estático
npm run test:e2e # recorrido de la web con Playwright
npm run test:responsive # matriz de móviles, tabletas y escritorio
npm run test:media:unit # contratos, estados, cuotas e idempotencia del motor
npm run test:media:integration # ciclo de vida, recuperación y publicación
npm run test:media:studio # lógica de Mi Estudio
npm run test:uploads # motor de subidas
[!TIP] Los comandos
media:*ytest:media:*delpackage.jsoncubren el resto: contrato con PeerTube, concurrencia en PostgreSQL, pruebas en vivo del entorno local y operaciones.
gma-filmo/
├── app/ Rutas de Next.js (App Router)
│ ├── (platform)/ inicio, cortos, películas, series, buscador, creadores
│ │ └── (protected)/ mi-espacio, mi-estudio, mi-perfil, configuración
│ ├── ver/[id]/ reproductor
│ └── api/ API: títulos, subidas, medios, comentarios, valoraciones…
├── components/
│ ├── features/ componentes por función (studio, player, comments…)
│ └── ui/ componentes base (shadcn/ui)
├── lib/
│ ├── media/ motor multimedia: servicio, proveedores, pasarela, transportes
│ ├── studio-media/ adaptador entre Mi Estudio y el motor
│ ├── uploads/ motor de subidas y compatibilidad con R2
│ └── supabase/ clientes y consultas
├── supabase/migrations/ esquema de la base de datos
├── infrastructure/ plantillas de PeerTube, entorno local y worker de vídeo
├── scripts/ utilidades operativas del motor y las subidas
├── tests/ · e2e/ pruebas unitarias, de integración y end-to-end
└── docs/ decisiones de arquitectura, planes y runbooks
next.config.mjs.¿Has encontrado una vulnerabilidad? Por favor, no abras un issue público: escribe de forma privada a quien mantiene el proyecto desde GitHub.
GMA Filmo es de todos los que quieran construirlo. Toda ayuda suma: código, diseño, pruebas, traducciones, documentación o simplemente reportar un fallo.
flowchart LR
A["🍴 Haz un fork"] --> B["🌿 Crea una rama"]
B --> C["💻 Programa y prueba"]
C --> D["📬 Abre un pull request"]
D --> E["👀 Revisión"]
E --> F["🎉 ¡Dentro!"]
main con un nombre claro (feat/subtitulos-srt, fix/reproductor-safari).feat:, fix:, docs:, test:…).npm run lint y las pruebas de la parte que hayas tocado.Lee la guía completa en CONTRIBUTING.md.
¿Echas algo en falta? Propónlo en un issue.
| Documento | Contenido |
|---|---|
| Plan maestro del motor multimedia | Decisiones, contratos y máquina de estados del motor |
| Runbook del motor | Operación diaria, incidentes y marcha atrás |
| PeerTube | Cómo se integra PeerTube y qué queda en el servidor |
| Entorno local | Stack multimedia aislado para desarrollar |
| Decisiones de arquitectura | ADR del proyecto |
Publicado bajo la licencia MIT. Puedes usar, copiar, modificar y distribuir el código libremente, también con fines comerciales, siempre que conserves el aviso de copyright.
[!NOTE] La licencia cubre el código. Las películas, imágenes y textos de los creadores pertenecen a sus autores y no se distribuyen con este repositorio.
Hecho con ❤️ por la comunidad de Generación Maldita