Lleva tu contenido a todas las pantallas con un código

TEVIX es una aplicación para Smart TV, celular y computadora que se convierte en la aplicación de tu empresa. No necesitas publicar nada en las tiendas: tu público instala TEVIX, ingresa tu código y el dispositivo pasa a abrirse siempre directamente en tu contenido, con tu nombre, tu color y tu logo.

Sin desarrollar una app

Sirve para portales de noticias, radios, canales de TV locales, iglesias, reproductores de video, cámaras en vivo, cualquier sitio web.

El contenido sigue siendo tuyo

Video, audio, imágenes y páginas se cargan directamente desde tu servidor. TEVIX solo entrega el código a los dispositivos.

Un código, todos los dispositivos

Samsung, LG, Android TV, Fire TV, celular, computadora y navegador. Control remoto, pantalla táctil y teclado.

En 3 pasos

PASO 1

Crea tu código

En la página de registro indica el nombre, el color, la URL de tu contenido y un contacto. El código se genera al instante, con prueba gratis.

PASO 2

Prueba

Abre TEVIX, ingresa el código y revísalo en la TV, en el celular y en la computadora. Ajusta la URL o el aspecto visual en el área del socio cuando quieras.

PASO 3

Difunde

"Instala TEVIX e ingresa ABC-123". El área del socio genera el texto listo para tu público.

Elige el tipo de fuente

La "fuente" es el lugar de donde TEVIX obtiene tu contenido. Existen tres tipos. Empieza por el más simple para tu caso; puedes cambiarlo después sin modificar el código.

TipoCuándo usarloQué necesitasCómo se ve
SitioYa tienes un sitio web, un reproductor web o un panel que funciona bien en TV.Solo la URL (ej.: https://player.suaradio.com.br).Pantalla completa, sin el menú de TEVIX. Igual que abrir el sitio en el navegador de la TV.
CompatibleYa tienes un start.json de otra aplicación de TV.La URL de tu start.json.TEVIX lee tu menú y tus páginas y los dibuja con el aspecto visual de TEVIX. No hay nada que rehacer.
TEVIXQuieres una app con menú, destacados, cuadrículas de noticias, videos y radio fija.Archivos JSON en el formato que se describe abajo, alojados en tu servidor.Menú lateral, tarjetas, lector de artículos, reproductor de radio.

Sitio o reproductor web

Indica la URL completa. El dispositivo abre esa página en pantalla completa dentro de TEVIX. Funciona con cualquier sitio, pero para que se vea bien en la TV el sitio debe aceptar la navegación con flechas y OK (foco visible en los botones). Si ya funciona en el navegador de la TV, funcionará aquí.

¿Reproductor o sitio en http:// (sin HTTPS)? Funciona igual. TEVIX detecta que el contenido es http y pasa a ejecutarse en su propia dirección http para abrir tu reproductor embebido, con el botón Volver. No necesitas cambiar nada en tu servidor.
Mientras TEVIX esté en http://, los sitios http:// y https:// funcionan. Cuando TEVIX pase a https://, un sitio http:// seguirá abriéndose, pero por navegación directa en lugar de incrustado. Prefiere siempre HTTPS en tu sitio.

Formato compatible (start.json)

Si ya tienes un start.json publicado para otra aplicación de TV, registra su URL (por ejemplo https://seusite.com/app/start.json). TEVIX entiende:

Aún no compatible en este formato: plugins (video:plugin:, audio:plugin:), panel:, request:interaction: y propiedades extendidas. Esos ítems muestran un aviso en lugar de fallar.

Formato TEVIX

Es el formato más completo y, a la vez, simple: un archivo principal (tevix.json) con la identidad y el menú, y un archivo por página. Lo vemos a continuación.

tevix.json: identidad y menú

{
  "tevix": "1.0",
  "app": {
    "name": "Portal Ciudad",
    "tagline": "Noticias y Radio 98,7",
    "short": "PC",
    "color": "#E8452C",
    "logo": "logo.png"
  },
  "menu": [
    { "id": "inicio",   "label": "Inicio",   "icon": "home",  "content": "inicio.json" },
    { "id": "aovivo",   "label": "En vivo",  "icon": "live",  "content": "aovivo.json" },
    { "id": "noticias", "label": "Noticias", "icon": "news",  "content": "noticias.json" },
    { "id": "radio",    "label": "Radio",    "icon": "radio", "content": "radio.json" }
  ],
  "player": {
    "type": "audio",
    "title": "Radio Ciudad 98,7 FM",
    "subtitle": "En vivo",
    "url": "https://stream.suaradio.com.br/live.mp3"
  }
}
CampoObligatorioDescripción
app.namesíNombre que aparece en el menú y en el título. Hasta 40 caracteres.
app.taglinenoLínea debajo del nombre.
app.shortnoSigla de 2 letras que se usa cuando no hay logo.
app.colornoColor de la marca en hexadecimal. Da color al foco, a los botones y al reproductor.
app.logonoImagen cuadrada (mín. 128×128). URL absoluta o relativa al tevix.json.
menu[]síDe 1 a 8 ítems. Cada uno con label, icon y content (URL de la página o la página incrustada como objeto).
playernoRadio fija en la parte inferior de la pantalla. url del stream (mp3/aac). autoplay solo funciona donde el dispositivo lo permita.
Lo que esté completado en el panel del socio (nombre, color, logo) tiene prioridad sobre el app del tevix.json. Así puedes cambiar el color sin tocar los archivos.

Páginas y bloques

Cada ítem del menú apunta a un archivo de página. La página tiene un título y una lista de bloques, de arriba hacia abajo.

{
  "title": "Inicio",
  "meta": "Actualizado hace 4 min",
  "blocks": [
    { "type": "hero", "items": [ "1 destacado grande + hasta 2 laterales" ] },
    { "type": "row",  "title": "Últimos videos", "items": [ "carrusel horizontal" ] },
    { "type": "grid", "title": "Noticias",       "items": [ "cuadrícula de tarjetas" ] },
    { "type": "list", "title": "Más leídas",     "items": [ "lista numerada solo con texto" ] }
  ]
}
BloquePara quéÍtems
heroDestacado superior (titular, en vivo).El 1.º se muestra grande; el 2.º y el 3.º quedan al lado. Usa imágenes 2:1 en el primero.
rowCarrusel horizontal (videos recientes, programas).Cualquier cantidad; se desplaza hacia el lado.
gridCuadrícula de tarjetas con imagen (noticias, canales).Cualquier cantidad; se acomoda en filas.
listLista compacta solo con título (ranking, programación).Hasta ~30 por bloque para que se vea bien en la TV.

Ítems

{
  "k": "Deportes",
  "title": "Ciudad FC gana y asume el liderato",
  "desc": "Un gol a los 43 del segundo tiempo aseguró la victoria.",
  "time": "hace 1 h",
  "image": "https://seusite.com/img/futebol.jpg",
  "action": "text:materia/1235.json"
}
CampoDescripción
titleTítulo de la tarjeta (obligatorio). Hasta 2 líneas en la TV: prefiere menos de 70 caracteres.
kEtiqueta corta en la esquina de la imagen (sección, "En vivo", "Podcast").
descResumen de hasta 2 líneas.
timeTexto pequeño (horario, duración, "hace 22 min").
imageImagen 16:9 (ideal 640×360 o 960×540, JPG). Sin imagen, la tarjeta usa un fondo neutro.
actionLo que ocurre al seleccionar. Ver abajo.

Acciones

AcciónQué haceObservaciones
video:URLAbre el reproductor de video en pantalla completa.MP4 (H.264) o HLS (.m3u8). HLS es lo ideal para transmisiones en vivo.
audio:URLReproduce en el reproductor fijo de radio, sin salir de la página.MP3/AAC, stream o archivo. Play/pausa con OK.
text:URLAbre un artículo en pantalla de lectura.URL de un JSON en el formato de artículo.
content:URLAbre otra página (JSON de página) con botón Volver.Para programación completa, subcategorías, etc.
link:URLAbre un sitio web en pantalla completa dentro de la app.Volver lo cierra y regresa a TEVIX.
link:window:URLAbre el sitio en una ventana nueva (fuera de la app).Solo tiene sentido en computadora.
info:textoMuestra un aviso rápido.Ej.: "Llama al 0800 123 987".
content:plugin:ID, video:plugin:ID, panel:…, player:…Contenido y reproductor controlados por un plugin tuyo.Ver Plugins.

Las URL pueden ser relativas al archivo en el que están (materia/1235.json, ../videos/x.mp4). Un ítem sin action es solo informativo.

Plugins: contenido dinámico desde tu servidor

Los JSON estáticos resuelven la mayoría de las apps. Cuando el contenido necesita lógica en tiempo real (programación que cambia, reproductor con inicio de sesión, progreso en vivo, catálogo por usuario), usa un plugin TEVIX: una página HTML tuya que corre oculta dentro de la app y conversa con ella. La app le pide el contenido al plugin, el plugin responde con el mismo JSON de página que ya conoces y, cuando quieras, actualiza ítems en pantalla, abre un video, muestra un panel o reacciona a lo que hace el usuario.

Mismo formato

El plugin devuelve páginas, ítems y acciones iguales a las de los archivos JSON. No hay nada nuevo que aprender en la parte visual.

Tiempo real

Reloj, marcador, "al aire ahora", progreso del programa: el plugin cambia solo los ítems que variaron, sin recargar.

Tu lógica, tu servidor

La página del plugin se aloja contigo. Puede llamar a tu API, guardar datos en el dispositivo e identificarlo.

1. La página del plugin

Crea un HTML (ej.: https://seusite.com/tevix/plugin.html) que cargue la biblioteca y registre un handler. La página no tiene interfaz: solo responde a la app.

<!DOCTYPE html>
<html><head><meta charset="utf-8">
<script src="https://tevix.app/js/tevix-plugin.js"></script>
</head><body><script>
TevixPlugin.setupHandler({
  init: function (info) {
    // info.app {name,color,logo}, info.code, info.lang ("pt"|"en"|"es"), info.device.id, info.tevix
  },
  ready: function () {
    // conexión lista: aquí puedes iniciar timers (ej.: actualizar ítems cada segundo)
  },
  handleRequest: function (id, data, reply) {
    // la app pide un contenido. "init" es la solicitud predeterminada cuando se abre la página del plugin.
    if (id === "init") reply({
      headline: "Al aire",
      pages: [{ items: [
        { id: "agora", layout: "0,0,8,2", titleHeader: "Ahora", title: "Noticiero de la Mañana", progress: 0.4, action: "video:plugin:aovivo" },
        { layout: "8,0,4,2", type: "button", icon: "list", label: "Programación", action: "content:plugin:grade" }
      ]}]
    });
    else if (id === "aovivo") reply({ url: "https://cdn.seusite.com/live.m3u8", title: "En vivo" });
    else if (id === "grade") reply({ headline: "Programación", pages: [ /* ... */ ] });
    else reply({ error: "solicitud desconocida: " + id });
  },
  handleData: function (data) {
    // viene de una acción "plugin:commit:ALGUNA-COSA" (string)
  },
  handleEvent: function (name, data) {
    // "player:play", "player:time" {position,duration}, "player:ended", "player:closed", "content:shown", "focus" {id}, "back", "visibility"
  }
});
</script></body></html>

reply() acepta un JSON de página (pages/template+items o blocks), un objeto { "action": "video:..." } para solo ejecutar una acción, o { "error": "mensaje" }. También puede devolver una Promise. Si el plugin no responde en 20 segundos, la app muestra un error con un botón Reintentar.

2. Conectando el plugin a la app

En el tevix.json, un ítem del menú puede apuntar al plugin en lugar de a un archivo de página:

{
  "app": { "name": "TV Cidade", "color": "#E8452C" },
  "menu": [
    { "label": "En vivo", "icon": "live", "plugin": "https://seusite.com/tevix/plugin.html" },
    { "label": "Noticias", "icon": "news", "content": "noticias.json" }
  ]
}

Si toda la app es el plugin, usa "plugin": "URL" directamente en la raíz del tevix.json (sin menu): la app se abre sin barra lateral. Por defecto la app pide el contenido init; cámbialo con "request": "otro-id". Dentro de cualquier página, estática o proveniente del plugin, usa las acciones de la tabla de abajo. El plugin permanece cargado mientras la app esté abierta, incluso al cambiar de página; cargar un plugin de otra URL descarga el anterior.

AcciónQué hace
content:plugin:ID@URLCarga el plugin de la URL (si aún no está cargado) y abre el contenido ID como página, con Volver.
content:plugin:IDLo mismo, en el plugin ya cargado. El ID no puede contener /, . ni :.
plugin:URLCarga el plugin y abre el contenido init. Igual a content:plugin:init@URL.
plugin:commit:TEXTOEntrega TEXTO al handleData del plugin. Úsalo para botones ("favorito", "entrar", "siguiente").
video:plugin:ID · audio:plugin:IDLe pide ID al plugin y reproduce lo que llegue: { "url", "title", "position" } o { "action" }. Ideal para URL firmadas o que expiran.
panel:plugin:ID · panel:URLMuestra un panel (ventana sobre el contenido) con un JSON de página pedido al plugin o cargado desde la URL. panel:close lo cierra.
player:pause · resume · toggle · stop · seek:+30 · position:120 · label:TEXTOControla el reproductor de video/audio en uso y el texto que muestra.
focus:IDMueve el foco al ítem con ese id.
plugin:reload · plugin:unloadPide de nuevo el contenido actual · descarga el plugin.
[acción1|acción2]Varias acciones en secuencia. Ej.: [panel:close|video:plugin:aovivo].

3. Qué puede hacer el plugin en la app

Todo mediante la biblioteca TevixPlugin:

MétodoEfecto
updateItems([{ id, ...props }])Cambia propiedades de ítems en pantalla por el id (título, imagen, progress, action...), sin recargar la página. Es el corazón del tiempo real.
updateContent(json)Reemplaza la página actual por otro JSON de página.
showContent(json)Abre un JSON de página encima de la actual, con Volver.
reloadContent()Hace que la app pida de nuevo el contenido actual (llama a handleRequest).
showPanel(json) · closePanel()Muestra o cierra un panel.
play("video"|"audio", url, { title, position })Reproduce, opcionalmente continuando desde una posición.
setPlayerLabel(texto)Texto en el reproductor mientras reproduce ("Noticiero de la Mañana · 12:04").
executeAction("...", datos)Cualquier acción de la tabla anterior (ej.: "player:pause", "back:", "content:plugin:grade").
updateMenu([...])Cambia el menú de la app (mismo formato del menu del tevix.json).
requestData(id, cb)Pide datos a la app: "device:id", "info", "lang", "player:state", "content:current", "focus:current".
requestDeviceId(cb)Identificador estable de este dispositivo (para inicio de sesión por dispositivo, límites, favoritos).
storage.set(clave, valor) · storage.get(clave, cb) · storage.remove(clave)Guarda datos en el dispositivo, separados por plugin.
busy(true, "Cargando…") · busy(false)Indicador de "espera" sobre la app.
toast(texto) · log() · warn() · error()Aviso rápido en pantalla · mensajes en la consola de la app, para depurar.

4. Eventos que envía la app

Llegan en handleEvent(nombre, datos):

EventoCuándoDatos
player:play · player:pause · player:ended · player:error · player:loadedCambios del reproductor de video o audio.{ url, position, duration, paused, ended }
player:timeCada segundo durante la reproducción de video.ídem
player:closedEl usuario cerró el video (Volver). Guarda la posición para "seguir viendo".ídem
content:shownUna página terminó de dibujarse.{ id, title, depth }
focusEl foco llegó a un ítem con id.{ id, panel }
panel:shown · panel:closedUn panel se abrió o se cerró.{ id }
backEl usuario presionó Volver.{ depth, panel, overlay }
visibilityLa app pasó a segundo plano o volvió.{ hidden }

5. Propiedades extra de páginas e ítems

DóndePropiedadPara qué
ítemidIdentifica el ítem para updateItems, focus:ID y el evento focus.
ítemprogressBarra de progreso de 0 a 1 en la base del ítem (programa en vivo, "seguir viendo").
ítemalignment"left" (predeterminado), "center" o "right" para los textos.
ítemimageFiller"cover" (predeterminado), "contain" o "fill" para la imagen.
ítemenabled: falseÍtem atenuado y sin foco.
ítemcolor · backgroundColores del ítem (CSS).
páginareadyAcción que se ejecuta apenas aparece la página (ej.: "plugin:commit:abriu").
páginalive{ "interval": 30, "action": "plugin:reload" }: repite la acción mientras la página esté en pantalla. Para actualizaciones más finas, prefiere updateItems.
Direcciones. La app corre en https://, así que la página del plugin también debe estar en https:// (un certificado gratuito con Let's Encrypt lo resuelve). Los videos y audios que devuelve el plugin siguen la misma regla de los JSON. La biblioteca tevix-plugin.js es pequeña, sin dependencias y funciona en los navegadores antiguos de las TV.
Para probar, crea tu app gratis en el área del socio apuntando a tu tevix.json con el plugin y abre el código en la app. Abre la consola del navegador en la computadora: los mensajes de TevixPlugin.log() aparecen con el prefijo [plugin].

Artículos (texto)

{
  "k": "Ciudad",
  "title": "La alcaldía anuncia una nueva línea de autobuses",
  "subtitle": "La operación comienza el lunes con 12 vehículos.",
  "date": "2 de noviembre de 2026",
  "author": "Redacción",
  "image": "https://seusite.com/img/onibus.jpg",
  "body": [
    "Primer párrafo.",
    "Segundo párrafo."
  ]
}

Cada elemento de body se convierte en un párrafo. Texto plano, sin HTML. La lectura usa letra grande, cómoda a 3 metros de la TV.

Radio fija

Con el campo player en el tevix.json, la app muestra una barra de radio siempre visible. El oyente navega por las noticias mientras escucha. Cualquier ítem con audio: también se reproduce en esa barra. Usa un stream directo (.mp3 o .aac), no una página de reproductor.

Íconos del menú

home live news video radio play movie tv music settings info link web star search list. Los nombres de íconos de Material Design (play-circle-outline, live-tv, ondemand-video…) se convierten automáticamente; los nombres desconocidos se muestran como un punto.

Ejemplo completo para copiar

La app de demostración "Portal Cidade" está publicada y puede servir de modelo. Descarga los archivos, cambia textos, imágenes y URL y publícalos en tu servidor:

Para verlo en la app: abre TEVIX e ingresa 8CR-EEC.

Alojamiento y CORS

Los archivos JSON se quedan en tu servidor, en cualquier alojamiento que sirva archivos estáticos. El dispositivo los obtiene directamente desde ahí, así que hay dos requisitos obligatorios:

  1. Habilitar CORS: el servidor debe responder con el encabezado Access-Control-Allow-Origin: * en los JSON (y en las imágenes, si quieres).
  2. HTTPS siempre que sea posible. Los certificados gratuitos (Let's Encrypt) lo resuelven.
Nginx
location ~* \.json$ {
    add_header Access-Control-Allow-Origin * always;
    add_header Cache-Control "public, max-age=300";
}
Apache (.htaccess)
<FilesMatch "\.json$">
    Header set Access-Control-Allow-Origin "*"
    Header set Cache-Control "public, max-age=300"
</FilesMatch>
Cloudflare Pages, Netlify, Vercel, GitHub Pages

GitHub Pages ya envía CORS habilitado. En Netlify crea un archivo _headers con /*.json y Access-Control-Allow-Origin: *. En Cloudflare Pages y Vercel, usa el archivo de headers de la plataforma con la misma regla.

WordPress

Coloca los JSON en una carpeta del sitio (ej.: /tevix/) y aplica la regla de Apache de arriba en el .htaccess de esa carpeta. O genera los JSON mediante un plugin o la REST API (ver abajo).

Caché: la app guarda el último JSON válido de cada página. Si tu servidor se cae, el público sigue viendo la última versión. Los cambios aparecen en hasta 5 minutos (o al instante, con "Limpiar caché" en la configuración de la app).

Generar los archivos automáticamente

No necesitas escribir JSON a mano. Cualquier cosa que genere un archivo de texto sirve:

Probar tu app

  1. Abre TEVIX en el navegador (o en la TV) e ingresa tu código. En el área del socio está el botón Probar mi app ahora, que ya entra con el código.
  2. Navega con las flechas del teclado (o del control remoto) y OK/Enter. Volver: Backspace o Esc.
  3. ¿Cambiaste un JSON? Ve a Configuración → Limpiar caché y recargar dentro de la app.
  4. El error "No se pudo cargar esta página" muestra la URL y el motivo (404, CORS, JSON inválido). Valida el JSON en un validador en línea antes de publicar.
  5. En Configuración → Verificar código ahora la app consulta el servidor de TEVIX al instante (útil justo después de renovar el plan).

Consejos para que se vea bien en la TV

Planes, prueba y vencimiento

Prueba gratis

Al crear el código obtienes días de prueba (el plazo aparece en el área del socio). Todo funciona igual que en el plan pago; la app muestra una etiqueta "Prueba".

Plan mensual

Un valor fijo por mes por código, sin límite de dispositivos. Al renovar, la etiqueta desaparece y el plazo avanza 30 días.

Vencimiento

Sin renovación, el código se suspende. Los dispositivos muestran "Código suspendido. Contacta a la empresa" en la siguiente verificación (hasta 6 h). Al renovar, vuelve a funcionar por sí solo.

Para contratar o renovar, usa el contacto que aparece en el área del socio. El código es siempre el mismo: tu público no necesita ingresar nada de nuevo.

Área del socio

En /parceiro ingresas con el código y la contraseña elegida en el registro. Ahí puedes:

Preguntas frecuentes

¿Necesito publicar algo en las tiendas de Samsung, LG o Google?

No. TEVIX ya está (o estará) en las tiendas. Tu público instala TEVIX e ingresa tu código.

¿Cuántos dispositivos pueden usar el mismo código?

Ilimitados. El código identifica a tu empresa, no a un dispositivo.

¿Puedo cambiar el contenido después?

Sí, en cualquier momento, cambiando tus archivos JSON o la URL en el área del socio. El código sigue siendo el mismo.

¿TEVIX aloja mis videos o mi radio?

No. Todo se queda en tu servidor o CDN. Eso mantiene el servicio económico y tu contenido bajo tu control.

Ya tengo un start.json de otra aplicación. ¿Tengo que rehacerlo?

No. Registra la URL de tu start.json como fuente "Formato compatible". Los plugins de ese formato aún no son compatibles.

¿En qué idiomas está la app?

Portugués, inglés y español. TEVIX detecta el idioma del dispositivo y permite cambiarlo en Configuración. Tu contenido aparece en el idioma en que lo escribas.

¿Cómo sale el usuario de mi app para ingresar otro código?

En la app, Configuración → Cambiar código. En fuentes del tipo Sitio, presiona Volver fuera del sitio para abrir la configuración.

¿Y si olvido la contraseña del área del socio?

Contacta al soporte mediante el contacto del área del socio e indica tu código; la contraseña se restablece.

¿Listo para empezar?
Crea tu código ahora y pruébalo en todos los dispositivos.
Crear mi app gratisYa tengo código