SATPLAYTV WEBPLAYER - IPTV MULTI-DNS CON PANEL DE ADMINISTRACION Fecha: 2026-10-04 (hora Europa/Roma). Las claves estan SOLO en Webplayer-claves.txt. Creado por SatPlayTV - © 2026 SatPlayTV. Todos los derechos reservados. ===================================================================== 1. QUE ES ===================================================================== Un reproductor web IPTV (en vivo, peliculas y series) con panel de administracion. Tu gestionas varios DNS/servidores IPTV (Xtream Codes o listas M3U) y das a tus clientes un usuario y clave PROPIOS del WebPlayer. El cliente entra en la web, ve canales/categorias, busca, guarda favoritos y reproduce. NUNCA ve el DNS real ni las credenciales IPTV: el servidor hace de proxy de la API Xtream y de los streams (reescribe los m3u8, soporta Range, evita contenido mixto http/https y CORS) con tokens cifrados. Si un DNS falla, el reproductor prueba otro formato (TS/HLS) y despues salta solo al siguiente DNS que tenga el mismo canal (por nombre / id EPG). Todo en espanol, responsive (movil, tablet, PC, TV con teclado/mando). La MISMA aplicacion tiene dos versiones, ambas con su panel de administracion completo (DNS, clientes, actividad, ajustes): FASE 1 Servidor Ubuntu (Docker + tunel Cloudflare) -> FUNCIONANDO FASE 2 Hosting compartido (PHP + SQLite/MySQL) -> Webplayer-hosting.zip (NO subido a ningun sitio) ===================================================================== 2. DIRECCIONES (URLs) ===================================================================== SERVIDOR UBUNTU (Fase 1) Reproductor de clientes ...... https://webplayer.cojedor.top/ Panel de administracion ...... https://webplayer.cojedor.top/admin/ API del reproductor .......... https://webplayer.cojedor.top/api.php (la usa el propio reproductor; POST + CSRF) Proxy de streams ............. https://webplayer.cojedor.top/p.php (solo con token; sin token = 403) Acceso en la LAN ............. http://192.168.178.47:8150/ y http://192.168.178.47:8150/admin/ HOSTING (Fase 2, cuando lo subas; ejemplo con subdominio) Reproductor ............ https://webplayer.satplaytv.com/ Panel de administracion https://webplayer.satplaytv.com/admin/ API ..................... https://webplayer.satplaytv.com/api.php (el dominio/subdominio exacto lo eliges tu; ver LEEME-HOSTING.txt dentro del zip) Donde ver las direcciones: en el panel, Ajustes > "Direcciones" muestra reproductor, panel, API y proxy con el dominio con el que has entrado. No hay otro fichero o panel externo con estas direcciones. Usuario y clave del admin: Webplayer-claves.txt. ===================================================================== 3. COMO ANADIR UN DNS (servidor IPTV) ===================================================================== Panel > "DNS / Servidores" > "+ Anadir DNS" - Nombre: lo ven los clientes en el selector de servidor (p. ej. "Servidor 1"). No pongas ahi el dominio real. - Tipo "Xtream Codes": URL base (http://servidor:puerto) + usuario y clave IPTV por defecto. Tambien vale pegar una URL .../get.php?username=U&password=P&type=m3u_plus : se detecta y se convierte sola. - Tipo "Lista M3U": URL de la lista (http/https). Se admiten listas grandes; se cachean 15 min. - Formato de directo: Automatico (TS y luego HLS), TS primero o HLS primero. - User-Agent (opcional) por DNS; Orden; Activo/Inactivo. - Boton "Probar": comprueba conexion y credenciales (estado, caducidad, numero de categorias). - "Vaciar cache de catalogos" si cambias algo en el proveedor y quieres verlo ya. Los DNS inactivos desaparecen de golpe para los clientes. Los DNS no tienen limite en numero. ===================================================================== 4. COMO ANADIR CLIENTES ===================================================================== Panel > "Clientes" > "+ Nuevo cliente" - Usuario y clave del WebPlayer (si dejas la clave vacia se genera una aleatoria segura y se muestra UNA vez: copiala; solo se guarda el hash. Con "Nueva clave" generas otra cuando quieras). - Caducidad (fecha; vacio = sin caducidad). Botones rapidos "+30 d" en la lista. - Maximo de conexiones simultaneas (cada pestana/dispositivo reproduciendo cuenta como una). - DNS permitidos: marca los que puede usar (ninguno marcado = todos los activos). Para cada DNS Xtream puedes poner usuario/clave IPTV PROPIOS de ese cliente (si los dejas vacios se usan los del DNS). - Notas, activar/desactivar, eliminar. Pasa al cliente: https://webplayer.cojedor.top/ + su usuario + su clave. Panel > "Actividad": quien esta en linea, que canal ve, desde que IP, boton "Expulsar", y registro de eventos (accesos, fallos de login, reproducciones, limites de conexiones) de los ultimos 60 dias. Panel > "Ajustes": titulo, intro, texto de ayuda en el login, User-Agent, vida del token, cache, limite de intentos y bloqueo, zona horaria, modo mantenimiento, cambio de clave de admin, direcciones. ===================================================================== 5. LO QUE VE EL CLIENTE ===================================================================== Pantalla de intro con el logo SatPlayTV (una vez por sesion; se puede quitar en Ajustes), login, y el reproductor: pestanas En vivo / Peliculas / Series / Favoritos, categorias, buscador, selector de servidor, EPG corta (ahora/despues) si el DNS es Xtream, favoritos, canal anterior/siguiente, boton "Cambiar DNS", pantalla completa, boton "Compatibilidad" (transcodificacion, ver seccion 11). Teclado/mando: flechas para moverse, Enter reproducir, F pantalla completa, M silenciar, RePag/AvPag cambiar de canal. Motor: hls.js 1.7.3 y mpegts.js 1.8.2 incluidos EN LOCAL (sin CDN). Pie: "Creado por SatPlayTV · © 2026 SatPlayTV. Todos los derechos reservados." ===================================================================== 6. DONDE ESTA TODO EN EL SERVIDOR UBUNTU (192.168.178.47) ===================================================================== Carpeta ............ /opt/webplayer Codigo ............. /opt/webplayer/src (montado SOLO LECTURA en el contenedor) Datos .............. /opt/webplayer/data (config.php con la clave de cifrado, BD SQLite, cache, sesiones; FUERA del web root; permisos de www-data) Copias ............. /opt/webplayer/backups Docker ............. /opt/webplayer/Dockerfile (instala ffmpeg), docker-compose.yml, wp.ini (PHP endurecido), wp.conf (Apache), wp-entry.sh (arranque: lanza la limpieza de transcodificaciones cada 15 s y luego Apache) Contenedor ......... webplayer-web (imagen webplayer-web:2, php:8.2-apache + ffmpeg 7.1) Puerto ............. 8150 (solo 127.0.0.1 y 192.168.178.47; ufw lo abre solo a la LAN 192.168.178.0/24) Tunel Cloudflare ... cloudflared-webplayer (servicio systemd; config en /etc/cloudflared-webplayer/config.yml; webplayer.cojedor.top -> http://127.0.0.1:8150; DNS CNAME ya creado en Cloudflare) No se ha tocado ningun otro tunel (micine-jellyfin, nube-ubuntu, etc.) ni ningun panel existente. Operacion (desde SSH en el servidor): Ver logs ........... cd /opt/webplayer && docker compose logs -f Reiniciar .......... cd /opt/webplayer && docker compose restart Reconstruir imagen . cd /opt/webplayer && docker compose up -d --build Tunel .............. sudo systemctl status|restart cloudflared-webplayer Copia de datos ..... sudo tar czf /opt/webplayer/backups/datos-$(date +%F).tgz -C /opt/webplayer data Olvido de clave admin: docker exec -u www-data webplayer-web php /var/www/html/tools/reset_admin.php --creds=/var/wp-data/admin-credentials.txt y lee la clave nueva con: sudo cat /opt/webplayer/data/admin-credentials.txt (despues borra ese fichero). ACTUALIZAR el codigo: 1) Copia de seguridad: tar czf /opt/webplayer/backups/src-$(date +%F).tgz -C /opt/webplayer src 2) Copia los ficheros nuevos DENTRO de /opt/webplayer/src (sin tocar /opt/webplayer/data). Si en lugar de copiar dentro sustituyes la carpeta src entera, reinicia el contenedor (docker compose restart) para que vuelva a montarla. 3) No hace falta reconstruir la imagen salvo que cambies Dockerfile/wp.ini/wp-entry.sh (PHP lee los ficheros). Cache de catalogos: Ajustes > Vaciar cache. ===================================================================== 7. VERSION PARA HOSTING COMPARTIDO (satplaytv.com) - Webplayer-hosting.zip ===================================================================== Contenido del zip: LEEME-HOSTING.txt (instrucciones completas paso a paso) + carpeta webplayer/ (el codigo). Misma aplicacion, MISMO panel de administracion completo (DNS, clientes, actividad, ajustes). PHP 7.4+ con SQLite o MySQL/MariaDB; sin Docker, sin root; ffmpeg OPCIONAL (si no hay, la opcion de compatibilidad se oculta sola). NO se ha subido ni tocado el hosting real. Resumen de subida: 1) Crea el subdominio (p. ej. webplayer.satplaytv.com) con HTTPS. 2) Sube el CONTENIDO de la carpeta webplayer/ a la raiz del subdominio (incluidos ficheros ocultos .htaccess). 3) Abre https://webplayer.satplaytv.com/install.php : elige SQLite (o MySQL con los datos de cPanel), usuario admin y deja la clave vacia para que se genere una; guardala (se muestra una sola vez). 4) BORRA install.php. Entra en https://webplayer.satplaytv.com/admin/ y anade DNS y clientes igual que arriba. 5) Comprueba que /includes/db.php y /data/ dan 403/404. Limite del hosting compartido: el video pasa por PHP (un proceso por espectador) -> util para pocos clientes simultaneos; para mas, usa la version del servidor Ubuntu. Detalles en LEEME-HOSTING.txt. ===================================================================== 8. SEGURIDAD APLICADA ===================================================================== - Claves de admin y de clientes con hash (password_hash), claves aleatorias fuertes generadas en la instalacion (nada por defecto). CSRF en todos los formularios y llamadas, consultas preparadas (PDO), limite de intentos de login (por IP y por usuario, 5 fallos = 15 min, configurable), sesiones con cookie HttpOnly + SameSite + Secure, regeneracion de sesion al entrar, caducidad por inactividad. - Cabeceras: Content-Security-Policy estricta (solo scripts propios), HSTS, X-Frame-Options DENY, nosniff, Referrer-Policy, Permissions-Policy. - Los streams y las imagenes pasan por tokens cifrados (AES-256-GCM) con caducidad; el cliente nunca recibe la URL del DNS ni usuario/clave IPTV. El proxy comprueba en cada peticion que el cliente sigue activo y no caducado, y bloquea destinos locales (127.x, 169.254.x; opcionalmente redes privadas) para evitar SSRF. - PHP endurecido en Docker (open_basedir, disable_functions, display_errors off), codigo en solo lectura, datos fuera del web root, Apache deniega includes/, tools/, config.php y ficheros .sqlite/.log/etc. ===================================================================== 9. PRUEBAS REALIZADAS ===================================================================== Servidor (https://webplayer.cojedor.top, desde fuera de la LAN): login admin, alta de DNS de prueba (M3U publico de iptv-org, 327 canales de Espana) con "Probar", alta de cliente, login de cliente, categorias (43), busqueda, reproduccion real en navegador (Chrome) con HLS a traves del proxy (playlist reescrita, sub-playlist y segmentos con Range), sin violaciones de CSP, y el DNS real no aparece en ninguna respuesta. Despues se BORRARON el cliente y el DNS de prueba (el panel esta vacio, listo para tus datos). Pruebas locales adicionales (servidor simulado Xtream): categorias/canales/VOD/series/EPG, directo TS con mpegts.js, HLS, VOD con Range (206), conmutacion automatica al siguiente DNS cuando el primero falla (403 geo-bloqueado -> salta al otro DNS con el mismo canal), limite de conexiones (429), expulsion desde el panel, bloqueo por fuerza bruta (429), CSRF sin token (403), token de proxy invalido (403). Transcodificacion (seccion 11): probada en el servidor desde fuera (https://webplayer.cojedor.top) con ficheros generados con ffmpeg (MKV HEVC+AC3, AVI MPEG-4+MP2, TS HEVC+AC3, TS MPEG-2+MP2, MP4 H.264 como control) servidos como lista M3U de prueba, y con un canal HLS real del M3U publico de iptv-org (3Cat). Reproduccion real en Chrome, limite de simultaneas (429), limite de conexiones del cliente, token invalido (403), limpieza de temporales y de procesos ffmpeg al parar/cambiar de canal/inactividad (ver abajo). Los ficheros y el DNS/cliente de prueba se BORRARON. Zip de hosting: probado desde cero en un PHP local (PHP 8.4) con instalador web: SQLite, MySQL/MariaDB y instalacion en subcarpeta; panel completo, DNS Xtream/M3U, cliente y proxy funcionando. ===================================================================== 10. LIMITACIONES / A TENER EN CUENTA ===================================================================== - Cloudflare: el video pasa por el tunel/proxy de Cloudflare. Con muchos espectadores o mucho trafico de video su plan gratuito puede limitarlo (condiciones sobre contenido no-HTML). Para uso moderado funciona; si lo usas a gran escala, valora acceso directo por IP/puerto o un plan adecuado. - Cloudflare inserta un script de "Web Analytics" (beacon) que la CSP bloquea: es inofensivo; puedes desactivarlo en Cloudflare > Web Analytics si molesta el aviso en consola. - Formatos no soportados por el navegador (MKV/AVI, HEVC, MPEG-2, audio AC3/MP2/DTS, TS en iPhone): se resuelven con la transcodificacion ffmpeg (seccion 11), que usa CPU del servidor. Con la transcodificacion desactivada o sin ffmpeg (hosting) se vuelve a la reproduccion directa de antes (en iPhone solo HLS/m3u8 del proveedor). - EPG: solo con DNS Xtream (get_short_epg). Las listas M3U no tienen guia. - La conmutacion entre DNS empareja canales por nombre normalizado / id EPG; si un proveedor nombra distinto el canal, no lo encontrara como alternativo. - Las claves de clientes no se pueden ver despues (solo hash): usa "Nueva clave". - Pendiente (no pedido): importar clientes en bloque, multiples administradores, EPG XMLTV para M3U. ===================================================================== 11. TRANSCODIFICACION / MODO COMPATIBILIDAD (ffmpeg) ===================================================================== QUE HACE: cuando el navegador no puede reproducir un contenido (HEVC/H.265, MPEG-2, MKV, AVI, WMV, FLV, MPG, audio AC3/E-AC3/MP2/DTS, TS directo en iPhone/iPad sin MSE...) el servidor lo convierte al vuelo con ffmpeg a HLS (video H.264 + audio AAC estereo) y lo entrega por tc.php con token cifrado (mismas reglas que el proxy: cuenta activa y no caducada, reproduccion no expulsada, DNS/credenciales IPTV nunca visibles). Cada reproduccion tiene su propia sesion; al parar, cambiar de canal, cerrar sesion, ser expulsado o quedar inactiva (>90 s sin peticiones) el proceso ffmpeg se mata y se borran los temporales (/opt/webplayer/data/tc//). Un limpiador revisa cada 15 s (wp-entry.sh -> tools/tc_reaper.php) y tambien se limpia al vuelo; tope de 4 GB de temporales y 6 h (directo) / 12 h (VOD) por sesion. CUANDO SE USA: - Automatico: formato incompatible conocido (mkv, avi, wmv, flv, mpg, ts en iPhone...) -> directamente transcodificado; si el navegador "reproduce" pero sin imagen o sin audio (HEVC, AC3...) a los ~6 s cambia solo. Si todos los formatos directos fallan, transcodifica como ultimo recurso antes de cambiar de DNS. - Manual: boton "Compatibilidad" junto a "Cambiar DNS" (solo aparece si la transcodificacion esta activa). - Respeta el limite de conexiones del cliente (la transcodificacion cuelga de su misma reproduccion: no cuenta como conexion extra) y el limite global de transcodificaciones: si esta lleno muestra "Servidor ocupado". AJUSTES (Panel > Ajustes > "Transcodificacion / Compatibilidad (ffmpeg)"): - Activar/desactivar (ahora ACTIVADA, maximo 2). - Maximo de transcodificaciones simultaneas (defecto 2). - Calidad: Automatica (si el video ya es H.264 yuv420p lo COPIA sin recodificar = casi 0 % CPU; si no, recodifica hasta 1080p) o tope fijo 1080/720/480/360 (siempre recodifica, mas ligero cuanto menor). - Velocidad del codificador (preset x264: ultrafast ... medium; defecto veryfast). - Panel > Resumen muestra "Transcodificaciones activas n / max" y Actividad lista las sesiones con boton Detener. LIMITES (CPU del servidor: Ryzen 5 PRO 2400G, 4 nucleos / 8 hilos, sin GPU): - Recodificar un video 1080p H.264 con preset veryfast consume ~2-3 nucleos; 720p ~1-1.5; 480p/360p menos. Por eso el maximo por defecto es 2. Con HEVC 4K de origen la decodificacion tambien pesa: baja la calidad o el maximo. Si el servidor lleva otras cargas (Jellyfin, etc.) deja el maximo en 1-2 y usa calidad 720. - Arranque 3-10 s hasta que hay los primeros segmentos de 4 s. Retardo en directo ~12-20 s. - VOD transcodificado (peliculas/series): ffmpeg genera a ~3x velocidad real; se puede ir hacia atras y hasta lo ya generado, pero no saltar muy adelante hasta que se genere. Una sesion = una pelicula. - El proveedor IPTV ve UNA conexion por sesion transcodificada (la conexion la hace el servidor). - Subtitulos incrustados no se incluyen. COMANDOS UTILES (SSH): docker exec webplayer-web ffmpeg -version docker exec webplayer-web ls /var/wp-data/tc (sesiones activas; vacio si no hay nadie) docker exec webplayer-web ps -eo pid,args | grep ffmpeg (procesos en curso) Reconstruir tras cambiar Dockerfile: cd /opt/webplayer && docker compose up -d --build HOSTING: la app detecta sola ffmpeg (y proc_open). Sin ffmpeg la seccion de Ajustes y el boton NO se muestran. Ver LEEME-HOSTING.txt apartado 5b.