Plugins de ejemplo¶
Dos plugins publicados, los dos públicos, los dos instalables en Kino y los dos usables como plantilla. Arranca por Internet Archive si quieres la plantilla más simple posible; arranca por Tu servidor, el demo completo de la API, cuando tu fuente sea un servidor de la persona o cuando quieras ver funcionando de punta a punta cada función hasta apiVersion 7.
-
Tu servidor · kinotvapp/kino-plugin-own-server
El demo completo de la API. Un servidor multimedia en la casa (Jellyfin, Emby, un NAS…): la persona escribe su dirección, su usuario y su contraseña. Versión 1.5.0, apiVersion 7:
"hosts": [], todos los tipos de ajuste y el formulario completo, sesión conkino.storage,kino.rank, temporadas,download, copias, firma por petición,channelsen todas sus formas, una sección y mosaicos de Categorías,migrate,meta,subtitles,trackingysegments, más un servidor de referencia (server.mjs) para probarlo sin nada propio. -
Internet Archive · kinotvapp/kino-plugin-archive
Películas de dominio público y televisión clásica de archive.org. La plantilla más simple de la que partir: un manifiesto, un archivo JavaScript, sin paso de compilación, las cinco capacidades más
download, y un ajustelistpara las direcciones de archive.org de la persona (apiVersion 4), con el kitsdk/,GUIDE.md,contract.jsonykino.d.ts.
Para probar cualquiera de los dos en Kino, abre Ajustes > Plugins y escribe
kinotvapp/kino-plugin-archive o kinotvapp/kino-plugin-own-server.
Usa la plantilla, no hagas fork. "Usar como plantilla" crea un repositorio nuevo tuyo con los
mismos archivos. Un fork también funcionaría como plugin, pero la búsqueda de la comunidad de Kino deja
los forks por fuera (Hazte encontrar). Luego cambia id, name, homepage,
hosts y capabilities en kino-plugin.json, reescribe plugin.js y conserva sdk/.
Un ejemplo real: un plugin que usa el navegador oculto
Maratón (firmado, apiVersion 6, "browser": "pages") es un plugin real, de otra persona, que
encuentra su video con kino.browser.capture y ofrece los otros servidores e idiomas
de cada capítulo como copias perezosas con etiqueta. Es un ejemplo solo
de esas dos funciones (Kino solo lista los plugins de la comunidad: cada autor responde por el suyo); "Tu servidor" sigue siendo el plugin de referencia completo.
El plugin de referencia¶
Para lo básico -- search, home, browse, episodes y resolve sobre un sitio público, sin
ajustes ni sesión -- la referencia es kino-plugin.json y plugin.js de
kinotvapp/kino-plugin-archive, el plugin de
Internet Archive, con las cinco capacidades. Se lee más o menos así:
- Declara
archive.orgy*.archive.org: una URL de descarga enarchive.orgredirige a un nodo de almacenamiento comodn720705.ca.archive.org, y el comodín no cubre el dominio pelado. getJsonhace primero elawaity lanza errores después (la regla de la trampa del rechazo).searchlimpia lo que escribió la persona: archive.org responde 200 con un cuerpo de error cuando la consulta tiene un/,-,&o'suelto o unAND/OR/NOTcolgando, así que conserva letras, dígitos y apóstrofes dentro de las palabras, quita las palabras de operador, y les pregunta a las dos colecciones (películas y TV clásica) diga lo que digatype, que usa solo para decidir qué grupo va primero; un ítem que está en las dos se lista una vez.homearma tres filas (películas, TV clásica, animación clásica) y envuelve cada fila en su propiotry/catch, para que una fila que falla no haga perder las otras; lo reporta conkino.log. Cada fila lleva su propio id comoref, ybrowse(ref, cursor)recorre la misma consulta de a 50 con el número de página como cursor ("2","3", …), y lanzakino.error("not_found")para una fila que no conoce.episodeslee la lista de archivos del ítem, conserva los videos originales en orden natural (un comparadornatural()pequeño, porque no se puede confiar enlocaleCompare), los numera a partir de unS01E02en el nombre del archivo o 1, 2, 3, y usa"<item>|<file name>"comorefde cada capítulo.resolveescoge el mejor archivo reproducible (un mp4 derivado del original, o el mp4/webm mismo), convierte los archivos.vtt/.srthermanos ensubtitles, y ponedurationMs.- Cada URL que arma es
httpsen un host declarado; los pósters usanhttps://archive.org/services/img/<id>y no se revisan contra los hosts.
El README.md de ese repositorio dice lo que no hace (una colección se muestra como una sola
película, los capítulos numerados 0 se descartan), así que no copies eso como si fuera lo esperado.
Para todo lo demás, hasta apiVersion 7 (Kino 0.9.51) -- ajustes, sesión, descargas, ítems live,
channels, lo de apiVersion 6, tracking y segments -- la referencia es
kinotvapp/kino-plugin-own-server ("Tu servidor"
1.5.0): su
kino-plugin.json
y su plugin.js usan casi
todo lo que existe, y su
README.md relaciona cada
función con el título de su servidor de prueba que la ejercita:
| Lo que muestra | Dónde en el código | Guía |
|---|---|---|
"hosts": [], el servidor que escribe la persona y sus otras direcciones (una list de campos url) |
kino-plugin.json; base(), addresses(), reach() |
Los servidores propios de la persona |
Todos los tipos de ajuste: url, text, password, toggle, select, list, section (con explicación de 300 caracteres), status, action |
kino-plugin.json: settings |
Formulario de ajustes |
Líneas de estado, botones (confirm, clearSettings) y una revisión antes de guardar |
settingsStatus(), action(), validateSettings() |
Formulario de ajustes |
Login y un token guardado en kino.storage, reintentado una vez ante un 401; kino.sleep con un Retry-After corto |
token(), api() |
kino.storage |
Errores tipados (kino.error) y una frase propia (userMessage) |
api(), resolveCopy() |
Errores que la gente entiende |
Una caché con el ttlMs que escoge la persona, y la última copia si el servidor se cae; telemetry + kino.log.report |
home(), reach() |
kino.storage, Telemetría |
Búsqueda por título sobre un backend que compara cualquier palabra; una Page con next; scopedSearch |
search(), kino.rank.* |
kino.rank, Buscar dentro de un "Ver más" |
Paginación con cursor, filas con genre |
browse(), refFilter(), ROWS |
Paginación |
| Temporadas como títulos separados | episodes() |
Temporadas |
ids.tmdb + ids.imdb, campos del ítem, entradas adult: true |
item(), categories() |
ids.tmdb, Contenido +18 |
Una sección con pestañas y destacado, mosaicos de Categorías, theme |
section(), categories(); kino-plugin.json |
Sección, categorías y colores |
Descargas (download) |
kino-plugin.json; resolve() devuelve un mp4 progresivo |
Descargas |
audioTracks, subtitles, durationMs y skip en el Stream |
resolve() |
Las reglas del Stream |
| Copias con etiqueta y perezosas, el mismo archivo en las otras direcciones | withCopies(), resolveCopy(), withAddresses() |
Copias con etiqueta y perezosas |
Firma de cada petición (signing, signContext, sign, alternateHosts, resolve(ref, { retry })) |
signedStream(), sign(), resolve() |
Firma por petición |
Ítems live (apiVersion 2) |
item(), resolve() |
Canales en vivo (apiVersion 2) |
channels: un ref, un stream en línea, una lista M3U con guía XMLTV, una lista con resolve: true, liveSearch, paginación |
liveCategories(), channel(), liveChannels(), liveSearch(), resolveListEntry() |
Canales en la pestaña En vivo, Tres recetas |
Un User-Agent que los canales exigen: headers en un Stream, streamHeaders en una lista |
agentHeaders() |
Canales en la pestaña En vivo |
| Una guía para canales propios | guide() |
Las funciones de canales |
| Pasar lo guardado con los ids viejos del servidor | migrate(), movedTable() |
Pasar lo guardado |
meta con logo, ratings y cast (Kino 0.9.51) |
meta() |
Describir otros títulos |
subtitles con la pista file (Kino 0.9.51) |
subtitles() |
Subtítulos para cualquier título |
tracking (apiVersion 7): idempotencia con event.id, { skipped: true } |
track() |
Contarle a un servicio de seguimiento |
segments (apiVersion 7) |
segments() |
Dónde están la intro y los créditos |
Su núcleo, línea por línea, está en el recetario: El servidor propio de la persona.
Instálalo y compruébalo¶
kinotvapp/kino-plugin-own-server trae un
servidor de referencia sin dependencias
(node server.mjs [--port 8096] [--user ana] [--password s3cr3t] [--live-agent VLC]) cuyo catálogo ejercita una función
por título, así que puedes instalar el plugin en Kino y ver cada fila de la tabla de arriba
funcionando, sin necesitar un servidor real.
Algunos poderes no están a propósito, porque un servidor en la casa nunca los necesita: DRM
Widevine (receta), un host declarado por http plano
(receta), streams en cualquier servidor
(receta), secretos sellados (kino.secret), la
firma del autor (Plugins firmados), el navegador oculto y kino.html.select
(Navegador oculto) y los pares de llaves (Pares de llaves).