Novedades para quienes escriben plugins¶
Lo que cambió en Kino y que importa cuando escribes un plugin, por versión de la app. Cada número está en el contrato y en los archivos de referencia.
Kino 0.9.53: kino.meta y kino.tmdb¶
Sin apiVersion nuevo: sigue siendo 7, y nada de esta lista te obliga a cambiar tu plugin. Las dos
llamadas nuevas existen solo desde Kino 0.9.53, así que compruébalas antes de usarlas
(typeof kino.meta === "function", typeof kino.tmdb === "function"); node sdk/validate.mjs avisa si tu código llama
alguna sin esa comprobación.
kino.meta(query): pregúntale a Kino qué sabe de un título ({ type, ids: { imdb, tmdb, tvdb, kitsu, mal, anilist }, lang }) y recibe sinopsis, año, póster, fondo, logo, géneros, duración, capítulos con sus ids, la equivalencia de todos los ids, notas y reparto, onull. Kino responde con su propia consulta de TMDB, AniList para el anime y los demás pluginsmetade la persona, combinados igual que en la ficha; tu plugin nunca toca una llave de TMDB, y nunca se le pregunta a sí mismo. 30 llamadas por minuto, máximo 8 s, en caché 30 minutos. La APIkino.kino.tmdb(path, params): la API v3 de TMDB, solo lectura, sin una llave en tu plugin. Primero va la llave propia de Kino, detrás de la caché de TMDB de Kino (en disco, la misma de sus pantallas, con una copia de hasta 7 días cuando TMDB no responde) y de límites propios (20 llamadas cada 10 s por plugin, 60 cada 10 s entre todos los plugins), para que los plugins no gasten la cuota de Kino. Solo cuando la llave de Kino falla (TMDB le responde 401/403/429, o se agota uno de esos límites) la misma petición sale otra vez con la llave de la persona: la que escribe en Ajustes ("Tu llave de TMDB", opcional, sincronizada entre sus aparatos) o, si no hay, la que configuró en un addon de Stremio instalado, si acepta usarla. Una llave que tu plugin guarda en sus propios ajustes nunca se usa. Kino pone la llave; tu código nunca ve ninguna, y TMDB no necesita una entrada en tushosts.no_tmdb_key(con la frase de Kino para la persona ene.userMessage: "Agrega tu llave de TMDB en Ajustes, o instala un addon de TMDB de Stremio configurado con tu llave.") queda para una versión de Kino sin llave propia y una persona sin llave. Solo rutas de lectura permitidas, 40 llamadas cada 10 s por plugin conteste la llave que conteste, en caché 10 minutos. Un catálogo hecho con TMDB ya no necesita su propio ajuste de llave (déjalo solo como respaldo para versiones anteriores). La APIkino, un ejemplo completo.- El kit de Node corre las dos:
KINO_META_FIXTURE,KINO_TMDB_KEY(o"tmdbKey"ensdk/config.json) yKINO_TMDB_FIXTURE. Probar en local.
Kino 0.9.51: apiVersion 7¶
apiVersion 7 = Kino 0.9.51. El contrato (contract.json) dice ahora maxApiVersion 7 y
kino.apiVersion reporta 7. Un manifiesto con "apiVersion": 7 se rechaza en Kino 0.9.50 y anteriores
("Este plugin necesita una versión más nueva de Kino"), así que declara 7 solo si usas tracking o
segments. Nada más de esta lista te obliga a cambiar tu plugin.
tracking(apiVersion 7): tu plugin exportatrack(event)y Kino le cuenta qué película o capítulo suena en ese aparato, de cualquier fuente:start,progress,stopywatched, con los ids propios del capítulo y los de la serie aparte. Se aprueba en rojo ("Le contará a … qué ves y cuándo lo terminas"), trae el interruptor "Enviar lo que veo" en tu pestaña de Ajustes, y los eventos esperan en una cola que sobrevive sin conexión y con la app cerrada (reintentos ordenados, 200 por plugin, 7 días). Devuelve{ skipped: true }para un evento que a tu servicio no le sirve. Contarle a un servicio de seguimiento qué ve la persona.segments(apiVersion 7): tu plugin exportasegments(query)y le dice a Kino dónde están la intro y los créditos de cualquier película o capítulo; los botones "Saltar intro" y "Saltar outro" y el salto automático los usan en celular y TV. Sin aprobación en rojo. Dónde están la intro y los créditos.- Subtítulos por archivo:
subtitles()recibefile: { hash?, size?, name? }, lo que Kino sabe del archivo que suena (el hash de OpenSubtitles, su tamaño, su nombre, o uno al estilo de un release armado con el título), para poner primero la versión exacta. Un addon de Stremio lo recibe como los extrasvideoHash,videoSizeyfilename. SinapiVersionnuevo. Subtítulos para cualquier título, Addons de Stremio. metacon logo, notas y reparto: la respuesta demetapuede traerlogo(se muestra en lugar del nombre en la ficha),ratings(hasta 6, de IMDb, Rotten Tomatoes, Letterboxd…) ycast(hasta 20); un addon de Stremio al estilo de AIOMetadata los da con sulogo,imdbRatingyapp_extras.cast. SinapiVersionnuevo: las versiones anteriores los ignoran. Describir otros títulos.- Los enlaces
stremio:///detail/…abren el título en Kino (el "Open in Stremio" de Seenr y similares), en vez de ignorarse. Addons de Stremio. -
"Tu servidor" 1.5.0, el plugin de referencia, ahora muestra todo lo que un servidor propio puede usar hasta apiVersion 7:
tracking,segments,subtitlesconfile,metacon logo, notas y reparto, y lo de apiVersion 6 (sección, categorías, firma por petición, copias, el formulario de ajustes completo, una lista conresolve: true,liveSearchy paginación de canales). Plugins de ejemplo. -
Compatibilidad de Nuvio v2: Kino convierte muchos más scrapers de Nuvio. Scrapers de varios archivos (los hermanos se leen del mismo repositorio, máximo 16 archivos y 1 MiB), un subconjunto de Node (
path,url,util,events,querystring,timers,bufferyhttp/https/undicisobrekino.fetch;setInterval,queueMicrotask), elonSettingsde cada scraper como formulario de ajustes que se sincroniza entre aparatos, y cada copia reproducible ofrecida como alternativa con etiqueta en el menú Servidor (las páginas de embed de últimas). Una dirección al estilo Kodiurl|User-Agent=…se vuelve encabezados. Los scrapers P2P y de debrid se rechazan ("No compatible"). Nada de esto es para tu propio plugin: es lo que puede dar por hecho un scraper de Nuvio. Scrapers de Nuvio. - Formulario de ajustes: el
hintde unasectionpuede tener hasta 300 caracteres y se parte en varias líneas (sectionHintMaxCharsencontract.json). Las versiones anteriores a 0.9.51 rechazan uno de más de 80, así que mantenlo corto si tu plugin tiene que instalarse en ellas. Formulario de ajustes. - Un
%en el texto de un error ya no tumba la app. Hasta 0.9.50, un error de tu plugin cuyo texto llevaba un%(una URL codificada como?q=Inception%20sen un "fetch failed") podía cerrar Kino de golpe. Ahora el texto de un error puede ser cualquiera; si tu plugin tiene que correr en 0.9.50 y anteriores, no metas direcciones codificadas en sus mensajes de error. Errores que tu código puede atrapar. - Recomendados suma addons de Stremio de utilidad (subtítulos como OpenSubtitles v3 y Subtis, catálogos como Cinemeta, TMDB e IMDb) y canales gratis y legales (Pluto TV, Radios). La lista ya no se publica en npm: Kino la lee de este repositorio en GitHub, luego de archive.org y luego de la copia de jsDelivr del mismo archivo de GitHub. Un addon que reproduce video sigue sin recomendarse. Addons de Stremio.
- La tarjeta de tu plugin ya no lleva la insignia "Kino" (parecía hecho por Kino); los addons de Stremio y los scrapers de Nuvio conservan la suya.
- Un addon de Stremio cuya descripción niega los torrents ya no se oculta ("no incluye streams, torrents ni contenido P2P"); el id y el nombre siguen estrictos. Lo que Kino rechaza.
Kino 0.9.50: apiVersion 6¶
apiVersion 6 = Kino 0.9.50. El contrato (contract.json) dice ahora maxApiVersion 6 y
kino.apiVersion reporta 6. Un manifiesto con "apiVersion": 6 se rechaza en Kino 0.9.49 y anteriores
("Este plugin necesita una versión más nueva de Kino"), así que declara 6 solo si usas algo de esta
lista. Todo lo que un plugin ahora puede cambiar de cómo lo muestra Kino está reunido en
Personaliza tu plugin.
- Secretos sellados más grandes y con tipo: hasta 8.192 bytes, y llaves de cifrado con tipo
(
use: "cipher-key") que sirven también parades-ede3. Manifiesto. migrate: pasar a tu plugin lo que la persona tenía guardado y Kino ya no puede abrir. Pasar lo guardado.- Streams firmados por petición:
signing: "request",signContext, el exportsign,resolve(ref, { retry })yalternateHosts. Firma por petición. - El formulario de ajustes: tipos
section,statusyaction(hasta 16, además de los 12 con valor),settingsStatus,actionconclearSettings,validateSettings, la pestaña propia en Ajustes y la sincronización entre aparatos. Formulario de ajustes. debugytelemetry(trueo"verbose"),kino.log.report, la página Registro, las etiquetas de logcatKinoPlugin/<id>yKinoPlay, y las métricas de reproducción. Registro y telemetría.- Modo debug en todo plugin: todo plugin instalado (el tuyo, un addon de Stremio convertido, un
scraper de Nuvio) tiene un interruptor "Modo debug" en su pestaña de Ajustes, sin que hagas nada:
encendido, sus fallas se ven en pantalla y su Registro se puede copiar o compartir, así que una persona
te puede mandar una captura o su Registro.
"debug": trueahora solo lo deja encendido de entrada; sin él arranca apagado. La decisión de la persona se conserva en las actualizaciones y se sincroniza con sus otros aparatos. Modo debug. - Los rechazos tempranos se atajan: un
throwen una funciónasyncantes de su primerawaitlo ataja eltry/catchde quien la llama (o un.catch(), unPromise.all), como en Node; solo un rechazo que nadie maneja nunca sigue haciendo fallar la llamada. Sigue haciendo elawaitprimero si tu plugin tiene que correr en 0.9.49 y anteriores. La trampa del rechazo. section,categoriesytheme: una sección propia, un grupo en Categorías y tus colores. Sección, categorías y colores.scopedSearch: responder tú la búsqueda dentro de un "Ver más". Contrato.kino.error(code, message, { userMessage }): tu propia frase para la persona, con reglas de seguridad y atribuida a tu plugin. Contrato.- Entradas
adult: truedetrás del código +18 de la persona (antes se descartaban). Contenido +18. - Canales en tus filas de Inicio (
kind: "live"enhome; antes se quitaban). Canales en vivo. - Pares de llaves en
kino.crypto:generateKeyPair,sign,verify,importKey,deriveSharedSecret. API kino. - El navegador oculto:
"browser": true(aprobado en rojo, "Puede abrir páginas web ocultas para encontrar el video") ykino.browser.capture, que abre un embed en una WebView oculta dentro de la app, en unresolveque empezó la persona, y devuelve las peticiones de video que hizo, retenidas para que sus tokens sigan frescos, con los encabezados y cookies para reproducirlas. Todo su tráfico pasa por un proxy con una credencial por captura e IP revisadas y fijas; la red de la casa nunca; una página a la vez; cookies y almacenamiento borrados. Una página que pide una persona termina conblocked: Kino nunca resuelve un captcha. Elresolvede un plugin aprobado tiene 75 s. También, con"browser": "pages"(su propia línea roja),kino.browser.page, que lee el HTML de una página a través del mismo navegador oculto cuando la revisión automática del sitio pasa sola (nunca desdecategories; el documento principal tiene que quedarse en tus hosts, revisando cada salto de redirección, o la lectura termina enblocked). Navegador oculto. Stream.labely copias perezosas con etiqueta: nombra cada copia ("Latino · Servidor 1") para el nuevo menú Servidor del reproductor, y lista copias como{ label, ref }que Kino resuelve conresolve(ref)solo cuando la persona escoge una, el cambio automático llega a ella (máximo 20 s cada una) o la elección de copia de una descarga la prueba. Si la escogida falla, se vuelve a la copia que se estaba viendo. Copias con etiqueta y perezosas.meta: describir títulos que listaron otras fuentes (sinopsis, imágenes, capítulos) cuando TMDB y AniList no tienen nada. Describir otros títulos.
Sin apiVersion nuevo (sirve para cualquier plugin):
alternativesen unStream: hasta 8 copias del mismo video; Kino pasa a la siguiente cuando una no se puede reproducir en el aparato. Contrato.- Reproducir en el TV desde el celular, capítulos nuevos de las series seguidas y "Para ti" funcionan para títulos de cualquier plugin. Lo que ve la persona.
- Actualizaciones: revisión al abrir la app (máximo cada 12 h), insignia de pendientes, y una llamada fallida con una actualización pendiente lo dice. Publicar.
- Un plugin firmado en dos repositorios cuenta como el mismo con el mismo
idy la misma llave. Plugins firmados. - Export
subtitles: responder la "Buscar subtítulos en línea" del reproductor para cualquier título que Kino conozca por id de IMDb o TMDB, junto a tus videos o como proveedor de subtítulos ("capabilities": ["subtitles"]sola). Subtítulos para cualquier título. Stream.skip: dónde están la entrada y el cierre de este archivo, para "Saltar intro" / "Saltar outro"; los tuyos le ganan a AniSkip, una corrección a mano le gana a los tuyos. Contrato.- El campo
categoriesdel manifiesto (movies,series,anime,live,radio,subtitles,utilities,adult): los chips de categoría de la tienda de plugins. Manifiesto. - Formulario de ajustes:
settingsStatus()se vuelve a pedir después de cada acción, así querefresh: trueya no hace falta. Formulario de ajustes. - Registros: solo un plugin que declara
telemetryenvía líneas dekino.logcon una falla, recomendado o no; por ahora no hay interruptor para apagarlo. Registro y telemetría. - "De la comunidad" es su propia pestaña de la pantalla Plugins. Publicar.
- Addons de subtítulos de Stremio (OpenSubtitles v3, traductores como GTSubs) se instalan como proveedores de subtítulos; las traducciones automáticas salen como "Español (traducido)". No tienes nada que escribir. Addons de Stremio.
- Ids reservados:
live,local,unknown,plugin,own,subtitle-keys,subtitle-prefs(la lista cambió: las versiones anteriores reservan algunos más, así que si una dice "El id … está reservado por Kino", escoge otro). - Reclamos y retiro de plugins de la comunidad:
community-blocklist.json. - Enviar a la TV: todo HLS pasa por el celular; un archivo sin
headersva directo y, si la TV no puede, por el celular. Enviar a la TV. genreen una fila de Inicio, una categoría en vivo o una lista (peliculas,series,anime,infantil,documentales,deportes,noticias,musica,entretenimiento,otros): Categorías agrupa por él las filas navegables de todos los plugins, y En vivo filtra por él entre proveedores. Opcional; sin él, Kino lo adivina por el título. Contrato.streamHeadersen una lista: elUser-Agento elRefererque el reproductor manda para cada canal de la lista, aparte de losheadersde descarga de la propia lista. Canales en vivo.- Una llamada
kino.*síncrona que falla se puede atajar (unkino.storagelleno, un error dekino.crypto): tutry/catchrecibe unErrornormal; Kino 0.9.49 terminaba ahí la llamada entera. Errores que tu código puede atrapar. - Después de actualizar Kino, las actualizaciones de plugins que esperan aprobación se instalan una vez, desde la dirección del propio plugin, con un aviso único "Se actualizaron tus plugins" que dice lo que cada uno puede hacer ahora. Publicar.
- El formulario de ajustes, documentado entero: cada tipo de campo, atributo y valor por defecto, con un ejemplo completo. Formulario de ajustes.
(Las versiones de Kino anteriores a genre y streamHeaders los ignoran; no se revisó la versión exacta
en que salió cada uno.)
También en esta versión (ya documentado antes en esta página como "próxima versión"):
- Instalar desde la URL del manifiesto. La gente puede pegar la URL
httpsde unkino-plugin.jsonen cualquier servidor público, no solo unowner/repode GitHub. Una instalaciónurl:así leeentryeiconal lado del manifiesto, no puede usarsecretssellados, siempre cuenta como no firmada y nunca sale en "De la comunidad" (el descubrimiento sigue usando el topic de GitHub). Una URL dekino-plugin.jsonen GitHub, raw.githubusercontent.com o jsDelivr (cdn.jsdelivr.net/gh/owner/repo@<ref exacta>/…;@latestes la rama por defecto, un rango de versiones se rechaza) se vuelveowner/repocomo antes. Instalar desde la URL del manifiesto, Publicar. liveSearch, un export opcional nuevo para canales en vivo (sinapiVersionnuevo: sigue siendo 3 conchannels). Kino lo pide desde la búsqueda de En vivo mientras algunos de tus canales nunca se han listado; devuelve canales como una página deliveChannels, máximo 100 conservados, desde 2 caracteres escritos, 15 s. Canales en vivo.- Los catálogos en vivo grandes siguen paginando.
liveChannelsrecibe 10 páginas al comienzo, y 5 más cada vez que la persona se acerca al final, hasta 10.000 canales (200 páginas) por categoría. Las versiones anteriores se quedan en 10 páginas. Pruébalo connode sdk/run.mjs . live search <consulta>. - Listas M3U en UTF-8, Latin-1 o UTF-16; los atributos de
#EXTINFpueden ir con comillas simples o sin comillas; una lista de más de 20 MB o una guía de más de 50 MB se corta en su última línea completa en vez de rechazarse. Canales en vivo. - Addons de Stremio: la gente los puede instalar desde el mismo campo (Kino genera el plugin; no
tienes nada que escribir). Su
resolve, como el de un scraper de Nuvio convertido, tiene 75 s. Qué se admite, qué se rechaza (torrents y P2P siempre) y cómo hacer que un addon funcione bien: Addons de Stremio. dituya no es unidde plugin reservado (las versiones anteriores lo siguen rechazando, así que evítalo).
Kino 0.9.46 a 0.9.49¶
- Se acepta un
./al principio deentryeicon. Kino lo quita e instala el plugin. Kino 0.9.45 y anteriores lo siguen rechazando (El campo "entry" debe ser una ruta relativa a un archivo .js), así que sigue escribiendo"plugin.js"e"icon.png". Elvalidate.mjsdel kit rechaza"./plugin.js"por eso. Detalles. - Tus logs ayudan cuando falla un plugin recomendado. En un plugin del catálogo recomendado de
Kino, las últimas 30 líneas de
kino.logde una llamada fallida (depuradas, 2 KB) van con el reporte del error comoplugin_log. Registra pasos y estados, nunca lo que la persona escribió ni un secreto.kino.log. - Un canal en vivo nunca muestra el botón de descarga, aunque el plugin declare
download.
Sobre la versión de cada punto
Estos puntos están en las versiones publicadas como 0.9.46 a 0.9.49; no se comprobó la versión exacta en la que apareció cada uno.
Kino 0.9.45¶
Contrato (contract.json, maxApiVersion 5):
- Plugins firmados,
apiVersion5. Firma opcional del autor enkino-plugin.json(node sdk/seal.mjs --keygen,--sign;validate.mjsla comprueba), clave fijada en la primera instalación, "Firmado por su autor" en la hoja de consentimiento, insignia "Firmado", la clave del autor en los detalles. Necesita Kino 0.9.45+; las apps más viejas rechazan un manifiesto conapiVersion5. Borradores anteriores de estos documentos decían 0.9.46: salió en 0.9.45. Plugins firmados. - Sin máximo de
hosts. El límite de 20 desapareció (solo lo acota el manifiesto de 16 KB). Kino 0.9.44 y anteriores siguen rechazando más de 20, y el kit avisa. Manifiesto. kino.apiVersionreporta 5.
Comportamiento que puedes notar (sin cambio de manifiesto):
- Enviar a la TV (Chromecast y DLNA) funciona para títulos de plugins. Directo para mp4/webm y HLS
sin
headers; por el celular cuando ponesheaders; nunca para DRM, DASH, MPEG-TS progresivo o un formato que nada identifica. Enviar a la TV. - Los plugins acompañan a la persona entre sus aparatos (celular y TV): instalaciones, encendidos, aprobaciones, ajustes y contraseñas (cifradas) se sincronizan, y el otro aparato instala tu plugin desde la misma dirección. Plugins en otros aparatos.
- Direcciones de instalación: también sirve una URL
raw.githubusercontent.com/.../kino-plugin.json(omanifest.json, para Nuvio) o unagithub.com/.../blob/...; una ref que solo viene de una URL pegada no es un pin. Inicio, Scrapers de Nuvio. - Descargas HLS:
EXT-X-DISCONTINUITYse deja tal cual salvo que el formato cambie en él; una llave mala o un segmento vacío terminan como "Este video no se puede descargar"; un reintento solo retoma con el mismo contenido. Las descargas siguen siendo declarativas:"download"encapabilities, nada que exportar. Descargas. - Headers de canales M3U: se leen
#EXTHTTP,url|User-Agent=...y los headers de#KODIPROP; solo se conservanUser-Agent,Referer,OriginyCookie. Canales en vivo. kino.fetch: los saltos de redirección rechazados cuentan para las 60 peticiones, máximo 6 fetch en vuelo, máximo 3 preguntas de host por llamada, se rechazan las formas IPv6 de direcciones privadas, sin proxy del dispositivo. Un plugin convertido desde un scraper de Nuvio tiene 250 peticiones y 75 s deresolve. Límites.
Sobre la versión de cada punto
El archivo del contrato fija la versión solo para los plugins firmados y el límite de hosts (0.9.45). Los demás puntos están en la compilación que se publicó como 0.9.45; no se verificó en qué versión exacta apareció cada uno.
Ya estaba antes de 0.9.45¶
streamHosts: "any" (apiVersion 4), liveStreamHosts: "any" (apiVersion 3 más la capacidad
channels), fetchHosts: "any" (lo escribe Kino solo en scrapers de Nuvio convertidos, nunca para tu
plugin), y la pregunta que Kino le hace a la persona la primera vez que un stream usa un host que no
declaraste. Están documentados en el manifiesto,
canales en vivo y el contrato.