diff --git a/modules/turnero/views/configuracion.php b/modules/turnero/views/configuracion.php
index c1e4419..be19c65 100644
--- a/modules/turnero/views/configuracion.php
+++ b/modules/turnero/views/configuracion.php
@@ -13,6 +13,28 @@ require_once __DIR__ . '/../../../config/config.php';
if (!isUserLoggedIn()) { header('Location: ' . BASE_URL . 'login.php'); exit; }
require_once __DIR__ . '/../_acceso.php';
+
+// Límite real de subida para la playlist: el menor entre el tope del código
+// (500 MB) y lo que permita el php.ini de ESTE servidor. Mostrar un número
+// fijo mentiría si el servidor admite menos.
+function _bytesDeIni(string $v): int {
+ $v = trim($v);
+ $n = (float) $v;
+ switch (strtoupper(substr($v, -1))) {
+ case 'G': $n *= 1024; // sigue
+ case 'M': $n *= 1024;
+ case 'K': $n *= 1024;
+ }
+ return (int) $n;
+}
+$_tvLimiteBytes = min(
+ 500 * 1024 * 1024,
+ _bytesDeIni(ini_get('upload_max_filesize') ?: '500M'),
+ _bytesDeIni(ini_get('post_max_size') ?: '500M')
+);
+$_tvLimiteTxt = $_tvLimiteBytes >= 1024 * 1024 * 1024
+ ? round($_tvLimiteBytes / (1024 * 1024 * 1024), 1) . ' GB'
+ : round($_tvLimiteBytes / (1024 * 1024)) . ' MB';
turneroExigirRol(['supervisor']);
$db = Database::getInstance();
@@ -1196,6 +1218,11 @@ $tab = $_GET['tab'] ?? 'lugares';
+
+ Videos MP4 o WebM e imágenes JPG/PNG ·
+ máximo = $_tvLimiteTxt ?> por archivo.
+ Los videos de iPhone (.mov) deben convertirse a MP4 primero.
+
@@ -1647,6 +1674,10 @@ async function cambiarSesion(accion, sesionId) {
// timeout, avisando con un toast que desaparecía en segundos. El cliente veía
// «subí 5» y la playlist mostraba 2. Ahora van de a uno, un fallo no frena a
// los demás, y al final queda un resumen fijo con qué entró y qué no.
+// El mismo límite que muestra la interfaz: calculado en el servidor
+const TV_LIMITE_BYTES = = (int) $_tvLimiteBytes ?>;
+const TV_LIMITE_TXT = '= $_tvLimiteTxt ?>';
+
const escHtml = x => String(x ?? '').replace(/[<>&"]/g, c => ({'<':'<','>':'>','&':'&','"':'"'}[c]));
async function subirTvMediaEnCola(files) {
@@ -1678,8 +1709,9 @@ function subirTvMedia(file) {
if (!allowedMime.includes(file.type)) {
return Promise.resolve({ ok: false, nombre: file.name, motivo: 'formato no admitido (use MP4, WebM, JPG o PNG)' });
}
- if (file.size > 500 * 1024 * 1024) {
- return Promise.resolve({ ok: false, nombre: file.name, motivo: 'supera el límite de 500 MB' });
+ if (file.size > TV_LIMITE_BYTES) {
+ return Promise.resolve({ ok: false, nombre: file.name,
+ motivo: 'pesa ' + Math.round(file.size / 1048576) + ' MB y el límite es ' + TV_LIMITE_TXT });
}
const wrap = document.getElementById('tv-progress-wrap');
diff --git a/scripts/test_tv_playlist.js b/scripts/test_tv_playlist.js
index 75a345b..fa2af71 100644
--- a/scripts/test_tv_playlist.js
+++ b/scripts/test_tv_playlist.js
@@ -74,8 +74,10 @@ ok('el reproductor salta al siguiente si un video falla',
// ── 2. Los pre-chequeos rechazan claro y ANTES de tocar la red ──────
const docTrampa = { getElementById: () => { throw new Error('tocó el DOM'); } };
const subir = new Function('document', 'XMLHttpRequest', 'FormData', 'API',
+ 'TV_LIMITE_BYTES', 'TV_LIMITE_TXT',
subirSrc + '; return subirTvMedia;')(
- docTrampa, function () { throw new Error('tocó la red'); }, function () {}, '');
+ docTrampa, function () { throw new Error('tocó la red'); }, function () {}, '',
+ 500 * 1024 * 1024, '500 MB');
Promise.all([
subir({ name: 'clip.mov', type: 'video/quicktime', size: 1000 }),