Regarder sa construction
Film / Créer une application kiosque avec le SDK
3:07

Claude Code crée un kiosque d’enregistrement dans le hall contre window.screenrig : waitUntilActive(), ready(), kv.get() et emitConfirmed(). Le tapotement d’un visiteur atteint l’agent, qui répond sur le mur d’accueil. Chapitres et transcription →
Le runtime est déjà dans l’application
app pack et app upload prennent un répertoire statique déjà construit avec une racine index.html. Le packer injecte _screenrig/runtime.js et ajoute sa balise script à ce document. L’application en cours reçoit window.screenrig sans étape de construction ni dépendance npm : rien à installer, importer ou configurer.
Chaque version d’application immuable s’exécute sur sa propre origine isolée sous apps.screenrig.ai. L’identifiant de l’application subsiste après la version, donc les données clé/valeur écrites par une version demeurent accessibles à la suivante.
La surface window.screenrig
Trois propriétés en lecture seule, dix méthodes, un espace de noms kv de cinq autres, et un espace de noms device pour l’écran, la présence, les touches matérielles, le capteur de lumière, l’état du réseau et le retour haptique. Lisez readyState d’abord et vérifiez capabilities avant d’appeler une méthode qu’une activation donnée pourrait ne pas avoir.
Chaque méthode répond à une question différente, alors commencez par ce que vous souhaitez accomplir :
| Pour faire cela | Appeler |
|---|---|
| Attendre que le lecteur active cette page | screenrig.waitUntilActive() |
| Indique que l’application est active et à l’écran | screenrig.ready() |
| Terminer le tour de cette application sur une page d’avancement d’application | screenrig.nextPage() |
| Indiquer au Player que cette page n’a rien à afficher pour le moment | screenrig.skip(reason) |
| Informez l’agent qu’un événement s’est produit | screenrig.emit(code) |
| Savoir que le backend a enregistré cet événement | screenrig.emitConfirmed(code) |
| Laissez un diagnostic pour que le Player et le runtime le collectent | screenrig.log(...) |
| Lire l’état d’une application en direct | screenrig.kv.get(), screenrig.kv.list() |
| Écrivez l’état d’application en direct | screenrig.kv.set(), screenrig.kv.delete() |
| Mettre à jour au moment où l’état de l’application en direct change | screenrig.kv.onChange() |
| Réagir à un changement de taille ou de capacité | screenrig.onResize(), screenrig.onCapabilities() |
| Atténuer, assombrir ou réveiller l’écran | screenrig.device.display.set() |
| Savoir que quelqu’un s’est approché de l’écran | screenrig.device.onPresence() |
| Prendre le contrôle des touches de volume matérielles | screenrig.device.onKey() |
| Connaître le niveau de lumière ambiante | screenrig.device.onLight() |
| Savoir que l’appareil est passé en ligne ou hors ligne | screenrig.device.onNetwork() |
| Jouer un tic haptique | screenrig.device.vibrate() |
| Démonter les écouteurs lorsque l’application a terminé avec le runtime | screenrig.destroy() |
screenrig.readyState#
Si le runtime injecté est attaché. Chaque document commence inert et devient active lorsque la poignée de main et le contexte du Player arrivent ; une page qui n’est pas encore affichée reste inert. Attendez active avec screenrig.waitUntilActive() ; ne considérez pas inert au chargement comme « hors screenRIG ». Sur failed, ou lorsque window.screenrig est absent, affichez votre propre contenu et sautez la surface ci-dessous, ainsi la même version fonctionne aussi hors screenRIG. Pendant inert, ready(), log(), emit(), emitConfirmed(), nextPage(), skip() et la lecture/écriture kv lèvent ou rejettent avec le code inert ; kv.onChange peut être enregistré à tout moment.
screenrig.context#
Où ce document s’exécute.
| Champ | Type | Notes |
|---|---|---|
application_id | string | L’identifiant app_ de app upload. Le magasin clé/valeur lui appartient. |
release_id | string | La version immuable servant cette origine. |
primitive_id | string | Le primitif que ce document remplit sur la page actuelle. |
viewport | { width, height } | La surface dans laquelle le lecteur s’affiche. |
primitive | { width, height } | Le rectangle que ce document occupe à l’intérieur de cette fenêtre d’affichage. |
capabilities | object | Les mêmes booléens que screenrig.capabilities. |
screen_id | chaîne, optionnelle | Présent quand l’exécution sait quel écran joue. |
context est une description, pas un matériel de demande. Rien dedans n’est destiné à être signé, transféré ou renvoyé à screenRIG ; les méthodes ci-dessous transportent ce dont le runtime a besoin.
Les params de lancement ne font pas partie de context : une liste de lecture peut donner à une application params (voir Jetons d’écran dans les adresses d’iframe et les params d’application), et le Player ajoute chacun à l’adresse de la page comme paramètre de requête après ticket. Lisez-les depuis location.search, par exemple new URLSearchParams(location.search).get("kiosk"). Ce sont des indications, pas des identifiants, et quiconque peut ouvrir la page peut envoyer n’importe quelle valeur, donc traitez-les comme une entrée non fiable ; context.screen_id reste le moyen de savoir quel écran est en lecture. Les Players Qt, Android, Apple et Windows chargent une application depuis leur paquet local, qui n’a pas d’adresse de lancement, et ne lui passent aucun param.
screenrig.capabilities#
Dix booléens qui indiquent quelles méthodes protégées feront quelque chose pour cette activation. Les clés sont pointées, donc lisez-les avec la notation entre crochets.
| Signaler | Portails |
|---|---|
page.advance | screenrig.nextPage() |
page.skip | screenrig.skip() |
kv.read | screenrig.kv.get(), screenrig.kv.list() et screenrig.kv.onChange() |
kv.write | screenrig.kv.set() et screenrig.kv.delete() |
device.display | screenrig.device.display.get(), .set() et screenrig.device.onDisplay() |
device.presence | screenrig.device.onPresence() |
device.keys | screenrig.device.onKey() |
device.light | screenrig.device.onLight() |
device.network | screenrig.device.onNetwork() |
device.haptics | screenrig.device.vibrate() |
if (window.screenrig.capabilities["kv.write"]) {
saveButton.hidden = false;
}Abonnez-vous avec onCapabilities au lieu de lire les indicateurs une fois au démarrage.
screenrig.waitUntilActive(timeoutMs)#
Appelez-le d’abord, avant toute autre méthode, et affichez votre interface pendant qu’il attend. Il se résout lorsque le Player a activé cette page, ou immédiatement si le runtime est déjà active, et il ne déclare pas l’application rendue. Il rejette avec activation_timeout après timeoutMs (par défaut 10000, au maximum 300000) ; une page en attente peut simplement attendre à nouveau. Démarrez le son après sa résolution, car le Player charge une application avant l’affichage de sa page : un écran dont le navigateur autorise la lecture automatique le démarre aussitôt, et sur un écran dont le navigateur la refuse, play() est rejeté avec NotAllowedError ; interceptez l’erreur et lisez en sourdine.
const sr = window.screenrig;
async function start() {
render(); // the UI works with or without screenRIG
if (!sr) return;
for (;;) {
try { await sr.waitUntilActive(60000); break; }
catch (err) { if (err.code !== "activation_timeout") return; }
}
await sr.ready();
// From here: emit, emitConfirmed, log, kv, nextPage.
}
start();Vérifiez readyState === "active" avant un appel SDK depuis un gestionnaire d’événements, un minuteur ou catch, et mettez en file d’attente les entrées arrivant plus tôt. Un log() d’un gestionnaire qui s’exécute pendant inert lance aussi une exception, ce qui peut interrompre le démarrage avant qu’un événement ne soit envoyé.
screenrig.ready()#
Appelez-le après la résolution de waitUntilActive() et avant de dépendre de context, kv ou nextPage, une fois que l’application a ce qu’il faut pour être à l’écran. Appelé pendant inert, il lance une exception.
await window.screenrig.waitUntilActive();
await window.screenrig.ready();screenrig.nextPage()#
Appelez-le uniquement sur une page d’avancement d’application où cette primitive est le contrôleur, lorsque l’application a terminé son tour. C’est un coup unique : une activation obtient un avancement.
window.screenrig.nextPage();La méthode est pour une page dont le advance.mode est application, où ce primitif est le contrôleur :
{
"advance": { "mode": "application", "max_ms": 60000 },
"primitives": [
{
"id": "app",
"primitive": "application",
"release_id": "rel_01EXAMPLERELEASE000000000",
"rect": { "x": 0, "y": 0, "width": 1920, "height": 1080 },
"layer": 0,
"content_fit": "fill",
"controller": true
}
]
}Exactement un primitif sur cette page porte controller: true, et il doit s’agir d’un primitif d’application. max_ms sur l’objet page advance borne le tour.
screenrig.skip(reason)#
Appelez-la à la place de ready() lorsque l’application n’a rien à afficher pour le moment. L’écran passe aussitôt à la suite avec la transition normale de la page, et cette apparition ne compte aucune lecture. C’est une décision prise au démarrage : appelez-la dans les dix secondes suivant l’activation et avant ready().
await window.screenrig.waitUntilActive();
const events = await loadToday();
if (events.length === 0) {
await window.screenrig.skip("no events today");
} else {
render(events);
await window.screenrig.ready();
}Le contrôleur de la page, ou l’application seule sur sa page, détient la capacité, sur une page sans image ni vidéo. La méthode rejette avec capability_denied sans elle, avec skip_after_ready une fois que ready() a été appelée, et avec not_supported sur un Player qui ne la prend pas en charge. Elle rejette avec forbidden lorsque le Player garde la page : l’opérateur la retient, l’écran est éteint, aucune autre page ne peut jouer, ou toutes les autres pages ont aussi été sautées. Affichez alors votre contenu de repli et appelez ready(). Une liste de lecture de tuiles qui sautent toutes affiche la dernière pendant toute sa durée au lieu de tourner en boucle. Le reason facultatif (64 caractères au plus) apparaît dans le journal du Player du projet sous player.application_skipped. skip() est fourni par le runtime que app pack et app upload injectent : réemballez une version pour lui donner la méthode.
screenrig.emit(code)#
Utilisez-le quand l’agent doit voir qu’un événement s’est produit : une page a terminé une étape, un formulaire kiosque a été soumis, l’application a prouvé qu’elle a tourné. C’est un événement nommé de l’application, qui arrive dans le journal des événements du projet où l’agent le surveille avec la CLI fournie events list ou events follow. Un code, pas de corps de message.
log n’est pas un substitut. Un diagnostic n’est pas un événement d’application, et un agent lisant le journal des événements ne le verra pas.
window.screenrig.emit("menu.rendered");Les méthodes emit() et emitConfirmed() du SDK ajoutent des enregistrements application.event dont la ressource est l’écran. Lisez-les avec --type application.event et, au besoin, --screen-id. Les champs details.primitive_id et details.code renvoyés identifient la primitive émettrice et l’action nommée. --app-id sélectionne les événements de la ressource d’application, de ses versions et de ses entrées clé/valeur, et exclut donc ces événements d’écran.
screenrig events list --type application.event --screen-id scr_SCREEN| Paramètre | Type | Notes |
|---|---|---|
code | string | Assaini à [A-Za-z0-9._-], au maximum 64 caractères. |
screenrig.emitConfirmed(code)#
Utilisez-le quand l’application doit savoir que l’événement est arrivé : une commande kiosque a été passée, un formulaire envoyé, une visite terminée. Il envoie le même événement nommé que emit, et sa promesse se résout uniquement une fois que le Player confirme que le backend a accepté l’événement.
Il rejette avec le problème du backend lorsque l'événement est refusé, et avec ack_timeout après 10 secondes sans réponse. Ne pas réessayer automatiquement après un délai : le backend peut déjà avoir accepté l'événement. Un reçu prouve que l'événement est dans le journal d'événements du projet, pas que quelque chose l'a encore traité.
Les reçus fonctionnent sur chaque Player qui exécute des applications.
await window.screenrig.emitConfirmed("order.placed");| Paramètre | Type | Notes |
|---|---|---|
code | string | Assaini à [A-Za-z0-9._-], au maximum 64 caractères. |
screenrig.log({ level, code, message })#
Utilisez-le pour le diagnostic : le debug, info, warn et error sont les textes que le Player et le runtime collectent pendant que l’application est affichée. Le runtime injecté journalise lui-même par cette méthode. La journalisation est limitée : 32 lignes par client, et au maximum 2048 octets par message. Journalisez ce que vous voudriez voir en débogage, pas une ligne par image.
Ne pas utiliser log quand vous voulez dire emit. Les agents ne traitent pas les lignes de journal comme des événements d’application, donc tout ce dont l’agent doit agir appartient dans un code emit.
window.screenrig.log({
level: "warn",
code: "menu.stale",
message: "Falling back to the cached menu."
});| Champ | Type | Notes |
|---|---|---|
level | string | debug, info, warn ou error. |
code | string | Assaini à [A-Za-z0-9._-], au maximum 64 caractères. |
message | string | Au maximum 2048 octets. |
screenrig.onResize(handler)#
S’abonner lorsque la disposition peut changer sous vos yeux au lieu de lire context une fois. Le gestionnaire reçoit { viewport, primitive }, les mêmes deux objets que context transporte, et l’appel retourne la fonction qui termine l’abonnement.
const stopResize = window.screenrig.onResize(function (size) {
render(size.viewport, size.primitive);
});
stopResize();screenrig.onCapabilities(handler)#
S’abonner lorsque les capacités accordées peuvent changer au lieu de décider une fois au démarrage. Lisez screenrig.capabilities dans le gestionnaire pour les booléens actuels et activez ou masquez les contrôles affectés ; l’appel retourne la fonction qui termine l’abonnement.
const stopCapabilities = window.screenrig.onCapabilities(function () {
saveButton.hidden = !window.screenrig.capabilities["kv.write"];
});screenrig.destroy()#
Démonter les écouteurs lorsque l’application a fini avec le runtime. Une application qui s’exécute pour tout son tour et laisse le Player remplacer le document n’a pas besoin de l’appeler.
screenrig.kv#
Le magasin clé/valeur de l’application, pour l’état d’application en direct qui survit à une activation. Cinq méthodes propres : get, list, set, delete, et onChange. Voir le magasin clé/valeur ci-dessous.
Le magasin de clés/valeurs
Utilisez le magasin pour l’état d’application en direct : le menu rendu par l’application, le texte modifié ce matin par un opérateur, un compteur laissé par la dernière activation. Lisez-le avec kv.get et kv.list, écrivez-le avec kv.set et kv.delete, et soyez informé de chaque changement avec kv.onChange.
Le magasin appartient à l’identifiant d’application dans context.application_id, pas à une version, donc une entrée survit au prochain app upload. Les valeurs sont des octets, donc texte, JSON et petits binaires font tous un aller-retour. Les lectures nécessitent kv.read et les écritures kv.write ; vérifiez le drapeau avant d’appeler.
Le magasin et sa poussée de changement s’exécutent sur chaque lecteur qui exécute des applications : l’application Web du lecteur (PWA), Android, Amazon Signage Stick, macOS, Windows, Linux, Raspberry Pi, LG webOS Signage, BrightSign et Samsung Smart Signage (Tizen). Apple TV, iPhone et iPad n’exécutent pas d’applications ; voir prise en charge des primitives par plateforme.
screenrig.kv.get(key)#
Lire l’état en direct de l’application. Attendre la promesse.
const entry = await window.screenrig.kv.get("menu");screenrig.kv.list()#
Lire l’état en direct de l’application lorsque vous ne connaissez pas encore les clés : cela liste les clés que l’application a stockées. Attendre la promesse.
const keys = await window.screenrig.kv.list();screenrig.kv.set(key, value, options)#
Écrire l’état de l’application en direct. value est une chaîne ou un Uint8Array ; options est optionnel.
await window.screenrig.kv.set("menu", JSON.stringify(menu), {
contentType: "application/json"
});
await window.screenrig.kv.set("badge.png", pngBytes, {
contentType: "image/png"
});| Paramètre | Type | Requis | Notes |
|---|---|---|---|
key | string | oui | Voir clés. |
value | chaîne ou Uint8Array | oui | Les octets à stocker. |
options.contentType | string | non | Par défaut à text/plain pour une chaîne et application/octet-stream pour un Uint8Array. |
options.expectedRevision | entier non négatif | non | Écrivez seulement si l’entrée est toujours à cette révision. |
options.idempotencyKey | string | non | Réessayer la même écriture sans l’appliquer deux fois. |
screenrig.kv.delete(key, expectedRevision, options)#
Écrire l’état de l’application en direct en supprimant une entrée. expectedRevision est optionnel : omettez-le pour supprimer l’entrée actuelle, ou fournissez-le pour rejeter les modifications concurrentes.
await window.screenrig.kv.delete("menu");| Paramètre | Type | Requis | Notes |
|---|---|---|---|
key | string | oui | Voir clés. |
expectedRevision | entier non négatif | non | La révision à laquelle l’entrée était lors de votre lecture. |
options.idempotencyKey | string | non | Réessayer la même suppression sans l’appliquer deux fois. |
screenrig.kv.onChange(handler)#
Mettre à jour l’état de l’application en direct dès qu’il change au lieu de le sonder. Le gestionnaire s’exécute chaque fois qu’une clé de cette application change, quel que soit l’auteur : l’agent avec kv set, un système externe via un webhook clé/valeur, ou cette application sur n’importe quel écran. Il reçoit la clé modifiée, pas la valeur, donc lisez la nouvelle valeur avec kv.get. L’appel retourne la fonction qui termine l’abonnement.
const sr = window.screenrig;
async function showMenu() {
render(await sr.kv.get("menu"));
}
const stopChanges = sr.kv.onChange(function (change) {
if (change.key === "menu" && !change.deleted) showMenu();
});
await sr.waitUntilActive();
await sr.ready();
await showMenu();Abonnez-vous avant la première lecture, ainsi un changement survenant pendant votre lecture ne sera pas manqué ; un gestionnaire enregistré avant l’activation démarre dès que la page est active. Appelez stopChanges() pour terminer l’abonnement.
Un changement atteint chaque écran dont la liste de lecture place cette application en quelques secondes. Plusieurs écritures rapides sur une clé peuvent arriver comme un seul changement portant la révision la plus récente, donc traitez un changement comme « relire cette clé », pas comme un compte d’écritures. Un changement est un signal, pas un historique : lisez ce dont vous avez besoin au démarrage de l’application, puis suivez les changements.
| Champ | Type | Notes |
|---|---|---|
key | string | La clé qui a changé. |
revision | entier, optionnel | La nouvelle révision de l’entrée. Absente lorsque deleted est true. |
deleted | boolean | true lorsque la clé a été supprimée. |
Clés
Une clé fait de 1 à 256 octets UTF-8. La limite est en octets, pas en caractères, donc une clé avec des caractères multi-octets l’atteint plus vite que sa longueur ne le suggère. Une clé ne doit pas commencer par _screenrig/ ; ce préfixe appartient au runtime injecté.
Révisions et idempotence
Chaque entrée porte une révision. Vous pouvez optionnellement passer expectedRevision à screenrig.kv.set ou screenrig.kv.delete pour écrire uniquement si l'entrée est toujours à la révision que vous avez lue. Une révision obsolète signifie que quelqu’un d’autre a écrit avant vous : relisez l’entrée, réappliquez votre modification, puis réessayez.
idempotencyKey couvre l’autre moitié. Une écriture qui peut être réessayée après une réponse perdue peut porter la même clé à chaque tentative, et le magasin l’applique une fois.
Le même magasin depuis le CLI
L’agent peut accéder à ces entrées depuis l’extérieur du navigateur avec les kv commandes du CLI intégré contre l’identifiant app_ de app upload. C’est la vue opérateur de la boutique. Ce n’est pas un substitut aux cinq méthodes ci-dessus : une application modifie ses propres données via screenrig.kv dans le navigateur, pendant qu’elle est à l’écran. Un changement écrit par l’agent atteint l’application en cours via kv.onChange.
Pousser des données depuis un autre système
Un webhook clé/valeur est une URL qui écrit une clé de cette application. Donnez-la à tout ce qui peut envoyer un POST HTTP, comme un point de vente, un script de feuille de calcul, un cron ou curl, et chaque POST remplace la valeur de cette clé. Chaque écran exécutant l’application en est informé via kv.onChange en quelques secondes, sans nouvelle version ni agent en boucle.
L’agent en crée un pour une clé avec le CLI intégré et vous remet son URL et son secret :
screenrig kv webhook create menu --app-id app_01EXAMPLEAPP00000000000 --description "Point of sale menu feed"La réponse porte le url du webhook et son secret (srkw_…). Le secret est montré uniquement à la création du webhook et lors de la rotation de son secret, donc saisissez-le immédiatement dans le système d’envoi. L’URL n’est pas secrète ; le secret l’est.
L’expéditeur publie la nouvelle valeur comme corps brut de la requête, avec le secret dans l’en-tête Authorization :
curl https://api.screenrig.ai/api/applications/app_01EXAMPLEAPP00000000000/kv-webhooks/kvw_01EXAMPLEWEBHOOK00000/write \
-H "Authorization: Bearer $KV_WEBHOOK_SECRET" \
-H "Content-Type: application/json" \
--data '{"soup":"lentil","price":"6.50"}'Un expéditeur qui ne parle que l’authentification HTTP Basic utilise l’identifiant du webhook comme nom d’utilisateur et le secret comme mot de passe :
curl https://api.screenrig.ai/api/applications/app_01EXAMPLEAPP00000000000/kv-webhooks/kvw_01EXAMPLEWEBHOOK00000/write \
--user "kvw_01EXAMPLEWEBHOOK00000:$KV_WEBHOOK_SECRET" \
-H "Content-Type: application/json" \
--data '{"soup":"lentil","price":"6.50"}'- Le corps, au maximum 1 Mio, devient la valeur, et
Content-Typeson type de contenu (application/octet-streamquand l’en-tête est absent). La valeur atteint l’application du navigateur, ne postez donc jamais un identifiant comme tel. - Chaque publication est une écriture clé/valeur comme
kv set: elle remplace la valeur, augmente la révision et est comptabilisée dans le stockage comme toute autre écriture. - La réponse est les nouvelles métadonnées de la clé (
key,revision,bytes,sha256,content_typeetupdated_at), jamais sa valeur. - Ajouter un en-tête
Idempotency-Key(8 à 200 caractères) pour réessayer un post en toute sécurité : dans les 24 heures, la même clé s’applique une fois, et la même clé avec un autre corps ou type de contenu est refusée avecidempotency_mismatch. Sans cela, chaque post est une nouvelle écriture. - Un webhook accepte jusqu’à 120 publications par minute ; au-delà, la réponse est
429avecRetry-After. - Un secret manquant ou erroné, ou un webhook inconnu, répond
401. Un secret dans l’URL ou la chaîne de requête n’est jamais accepté. - Une application a jusqu’à 20 webhooks.
kv webhook rotate-secretémet un nouveau secret et l’ancien s’arrête immédiatement ;kv webhook deletearrête l’URL immédiatement et laisse la valeur de la clé en place.
Une carte accepte aussi des webhooks : un envoi construit son document de données, tel quel ou par un mappage (Webhooks de carte).
L’appareil
Une application qui anime un panneau mural ou un kiosque peut piloter l’écran sur lequel elle s’exécute. Les indicateurs device sont remis au frame qui contrôle sa page (le contrôleur de la page, ou son unique application), sur un Player capable de le faire sur cet appareil : le Player Android accorde device.display, device.keys et device.network, accorde device.presence lorsque l’appareil a une caméra et que la personne qui a configuré l’appareil a autorisé le Player à l’utiliser (Paramètres Android, Applications, screenRIG Player, Autorisations, Caméra), device.light lorsqu’il a un capteur de lumière, et device.haptics lorsqu’il a un vibreur. Les Players qui ne peuvent pas piloter un appareil laissent chaque indicateur device à false. display.get(), display.set() et vibrate() rejettent avec not_supported sur un Player qui ne les offre pas, et avec capability_denied sans l’indicateur. onDisplay, onPresence, onKey, onLight et onNetwork peuvent être enregistrés à tout moment et, comme kv.onChange, ne s’exécutent simplement jamais sans l’indicateur.
screenrig.device.display.set(state)#
Atténuer, assombrir ou réveiller l’écran. brightness va de 0 à 1 (0 est le niveau le plus bas du rétroéclairage, pas l’extinction) ; on: false assombrit l’écran et on: true le rallume. Omettez un membre pour le laisser tel quel. Les touchers atteignent toujours l’application tant que l’écran est sombre : un toucher peut donc le réveiller. Une programmation d’affichage qui garde l’écran sombre l’emporte sur l’application, et le Player rétablit l’affichage lorsque la page quitte l’écran.
await window.screenrig.device.display.set({ brightness: 0.3 });
await window.screenrig.device.display.set({ on: false });screenrig.device.display.get()#
L’état actuel de l’écran, sous la forme { on, brightness }.
screenrig.device.onDisplay(handler)#
Appelé avec { on, brightness } chaque fois que l’écran change, que ce soit par cette application, par une programmation d’affichage ou par un opérateur.
screenrig.device.onPresence(handler)#
Appelé lorsque l’appareil voit quelqu’un bouger devant l’écran, au plus une fois par seconde. Le Player lit la caméra de l’appareil et ne garde aucune image : aucune image n’est stockée, journalisée ni envoyée. La caméra ne fonctionne que tant qu’un gestionnaire est enregistré.
window.screenrig.device.onPresence(function () {
window.screenrig.device.display.set({ on: true, brightness: 1 });
});screenrig.device.onKey(handler)#
Appelé avec "volume_up" ou "volume_down" à chaque pression d’une touche de volume matérielle, répétitions comprises. Tant qu’un gestionnaire est enregistré, les touches appartiennent à l’application et le volume de l’appareil reste inchangé.
screenrig.device.onLight(handler)#
Appelé avec la lumière ambiante en lux : la première mesure après l’enregistrement du gestionnaire, puis chaque fois que la lumière varie d’au moins 10 % ou de 1 lux, au plus une fois par seconde. L’appareil doit avoir un capteur de lumière.
window.screenrig.device.onLight(function (lux) {
document.body.classList.toggle("dim-room", lux < 10);
});screenrig.device.onNetwork(handler)#
Appelé avec true ou false chaque fois que l’appareil obtient ou perd une connectivité Internet validée par le système, et immédiatement avec l’état actuel lorsque le premier gestionnaire est enregistré.
window.screenrig.device.onNetwork(function (online) {
offlineBadge.hidden = online;
});screenrig.device.vibrate(ms)#
Jouer un tic haptique. ms est un nombre entier de millisecondes de 1 à 200 et vaut 12 par défaut. La promesse se résout sans valeur une fois que le Player a lancé la vibration, et rejette avec invalid_request, sans rien envoyer, pour tout autre ms.
await window.screenrig.device.vibrate();
await window.screenrig.device.vibrate(40);Joindre les appareils du réseau de l’écran
Une application peut récupérer des données depuis des adresses http:// et ws:// en plus de https://, et peut donc dialoguer avec un appareil ou un serveur du réseau propre à l’écran, comme un contrôleur à l’adresse http://192.168.1.20. Les Players Android, Linux et Raspberry Pi, Windows et macOS l’autorisent. Sur un navigateur de kiosque exécutant l’application web du Player, le propriétaire du navigateur l’autorise au moyen d’une politique d’entreprise : voir Applications sur le réseau local. Le serveur que vous appelez répond aux requêtes CORS pour l’origine de l’application ; sur macOS, les requêtes d’une application portent Origin: null, de sorte que le CORS du serveur y autorise cette origine.
Un moteur de navigateur bloque <img src="http://…"> sur une page sécurisée ; chargez donc les images d’une adresse http:// avec fetch() et URL.createObjectURL().
const response = await fetch("http://192.168.1.20/snapshot.jpg");
image.src = URL.createObjectURL(await response.blob());