Documentação

Crie um aplicativo que foi feito para uma tela

Use o SDK do navegador injetado para controle de playlist, eventos de aplicação, diagnóstico e estado persistente de chave/valor.

Assista ser construído

Filme / Construir um app de quiosque com o SDK

3:07

Um visitante tocando um quiosque de check-in no saguão sob uma parede de boas-vindas

Claude Code cria um quiosque de check-in no saguão contra window.screenrig: waitUntilActive(), ready(), kv.get() e emitConfirmed(). O toque do visitante alcança o agente, que responde na parede de boas-vindas. Capítulos e transcrição →

O runtime já está no app

app pack e app upload recebem um diretório estático já construído com uma raiz index.html. O empacotador injeta _screenrig/runtime.js e adiciona sua tag de script a esse documento. A aplicação em execução recebe window.screenrig sem etapa de build e sem dependência npm: não há nada para instalar, importar ou configurar.

Cada versão imutável do aplicativo roda em sua própria origem isolada sob apps.screenrig.ai. O id do aplicativo permanece além da versão, então os dados de chave/valor gravados por uma versão ainda estarão disponíveis para a próxima.

A superfície window.screenrig

Três propriedades somente leitura, dez métodos, um namespace kv com mais cinco e um namespace device para a tela, a presença, as teclas físicas, o sensor de luz, o estado da rede e o feedback háptico. Leia readyState primeiro e verifique capabilities antes de chamar um método que uma ativação pode não ter.

Cada método responde a uma pergunta diferente, então comece pelo que você deseja fazer:

Para fazer issoChamada
Aguarde até que o Player ative esta páginascreenrig.waitUntilActive()
Diz que o aplicativo está ativo e na telascreenrig.ready()
Encerrar a vez deste aplicativo em uma página de avanço de aplicativoscreenrig.nextPage()
Avisar o Player de que esta página não tem nada para mostrar agorascreenrig.skip(reason)
Informe ao agente que algo aconteceuscreenrig.emit(code)
Saber que o backend registrou esse eventoscreenrig.emitConfirmed(code)
Deixe um diagnóstico para o Player e tempo de execução coletaremscreenrig.log(...)
Leia estado de aplicativo ao vivoscreenrig.kv.get(), screenrig.kv.list()
Escreva estado de aplicativo ao vivoscreenrig.kv.set(), screenrig.kv.delete()
Atualizar no momento em que o estado da aplicação ao vivo mudarscreenrig.kv.onChange()
Reaja a uma mudança de tamanho ou capacidadescreenrig.onResize(), screenrig.onCapabilities()
Reduzir o brilho, escurecer ou acordar a telascreenrig.device.display.set()
Saber que alguém chegou perto da telascreenrig.device.onPresence()
Assumir as teclas físicas de volumescreenrig.device.onKey()
Saber o nível de luz ambientescreenrig.device.onLight()
Saber que o dispositivo ficou online ou offlinescreenrig.device.onNetwork()
Emitir um pulso hápticoscreenrig.device.vibrate()
Desative os ouvintes quando o aplicativo terminar com o runtimescreenrig.destroy()

screenrig.readyState#

Se o runtime injetado está anexado. Todo documento começa inert e muda para active quando o handshake e o contexto do Player chegam; uma página que ainda não está na tela permanece inert. Aguarde active com screenrig.waitUntilActive(); não trate inert no carregamento como "fora do screenRIG". Em failed, ou quando window.screenrig está ausente, renderize seu próprio conteúdo e pule a superfície abaixo, assim a mesma build também roda fora do screenRIG. Enquanto inert, ready(), log(), emit(), emitConfirmed(), nextPage(), skip() e a leitura e escrita do kv lançam ou rejeitam com código inert; kv.onChange pode ser registrado a qualquer momento.

Tipo
"inert" | "active" | "failed"

screenrig.context#

Onde este documento está sendo executado.

CampoTipoNotas
application_idstringO id app_ de app upload. A loja de chave/valor pertence a ele.
release_idstringA versão imutável que serve esta origem.
primitive_idstringO primitivo que este documento preenche na página atual.
viewport{ width, height }A superfície na qual o Player está renderizando.
primitive{ width, height }O retângulo que este documento ocupa dentro daquela viewport.
capabilitiesobjectOs mesmos booleanos que screenrig.capabilities.
screen_idstring, opcionalPresente quando o runtime sabe qual tela está reproduzindo.

context é descrição, não material de solicitação. Nada nele deve ser assinado, encaminhado ou enviado de volta para screenRIG; os métodos abaixo carregam o que o runtime precisa.

Os params de lançamento não fazem parte de context: uma playlist pode dar a um aplicativo params (veja Tokens de tela em endereços de iframe e params de aplicativo), e o Player anexa cada um ao endereço da página como parâmetro de query depois de ticket. Leia-os em location.search, por exemplo new URLSearchParams(location.search).get("kiosk"). São dicas, não credenciais, e qualquer pessoa que consiga abrir a página pode enviar qualquer valor, então trate-os como entrada não confiável; context.screen_id continua sendo a forma de saber qual tela está reproduzindo. Os Players Qt, Android, Apple e Windows carregam um aplicativo do seu pacote local, que não tem endereço de lançamento, e não lhe passam parâmetros.

screenrig.capabilities#

Dez booleanos que indicam quais métodos restritos farão algo para esta ativação. As chaves são pontuadas, então leia-as com notação de colchetes.

SinalizarPortões
page.advancescreenrig.nextPage()
page.skipscreenrig.skip()
kv.readscreenrig.kv.get(), screenrig.kv.list() e screenrig.kv.onChange()
kv.writescreenrig.kv.set() e screenrig.kv.delete()
device.displayscreenrig.device.display.get(), .set() e screenrig.device.onDisplay()
device.presencescreenrig.device.onPresence()
device.keysscreenrig.device.onKey()
device.lightscreenrig.device.onLight()
device.networkscreenrig.device.onNetwork()
device.hapticsscreenrig.device.vibrate()
if (window.screenrig.capabilities["kv.write"]) {
  saveButton.hidden = false;
}

Assine com onCapabilities em vez de ler as flags uma vez na inicialização.

Tipo
objeto de booleanos

screenrig.waitUntilActive(timeoutMs)#

Chame primeiro, antes de qualquer outro método, e renderize sua interface enquanto espera. Resolve quando o Player ativar esta página, ou imediatamente se o tempo de execução já estiver active, e não declara o aplicativo como renderizado. Rejeita com activation_timeout após timeoutMs (padrão 10000, no máximo 300000); uma página aguardando sua vez pode simplesmente esperar novamente. Inicie o som depois que resolver, porque o Player carrega um aplicativo antes de a página dele aparecer: uma tela cujo navegador permite a reprodução automática inicia o som na hora, e em uma cujo navegador a recusa, play() é rejeitado com NotAllowedError; capture o erro e reproduza sem som.

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();

Verifique readyState === "active" antes de uma chamada SDK de um manipulador de eventos, timer ou catch, e enfileire a entrada que chegar antes. Um log() de um manipulador que roda enquanto inert também lança, o que pode terminar a inicialização antes de qualquer evento ser enviado.

Retorna
Promise<void>

screenrig.ready()#

Chame após waitUntilActive() resolver e antes de depender de context, kv ou nextPage, uma vez que o aplicativo tenha o que precisa para estar na tela. Se chamado durante inert, lança erro.

await window.screenrig.waitUntilActive();
await window.screenrig.ready();
Retorna
Promise<void>

screenrig.nextPage()#

Chame apenas em uma página de avanço de aplicativo onde este primitivo é o controlador, quando o aplicativo terminou sua vez. É único: uma ativação gera um avanço.

window.screenrig.nextPage();

O método é para uma página cujo advance.mode é application, onde este primitivo é o controlador:

{
  "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
    }
  ]
}

Exatamente um primitivo nessa página contém controller: true, e deve ser um primitivo de aplicação. max_ms no objeto de avanço da página delimita a vez.

Exige
capabilities["page.advance"]
Retorna
Promise<void>

screenrig.skip(reason)#

Chame-o em vez de ready() quando o aplicativo não tiver nada para mostrar agora. A tela segue de imediato para a próxima com a transição normal da página, e esta exibição não conta nenhuma reprodução. É uma decisão de início: chame-o até dez segundos depois da ativação e antes de 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();
}

O controlador da página, ou o aplicativo que está sozinho na página, tem a capacidade, em uma página sem imagem nem vídeo. O método rejeita com capability_denied sem ela, com skip_after_ready depois que ready() foi chamado e com not_supported em um Player que não o tem. Rejeita com forbidden quando o Player mantém a página: o operador a segura, a tela está apagada, nenhuma outra página pode tocar ou todas as outras páginas também foram puladas. Renderize então seu conteúdo alternativo e chame ready(). Uma playlist de blocos que pulam todos mostra o último durante todo o seu tempo em vez de girar em ciclo. O reason opcional (no máximo 64 caracteres) aparece no log do Player do projeto como player.application_skipped. skip() vem no runtime que app pack e app upload injetam, então reempacote uma versão para dar o método a ela.

Exige
capabilities["page.skip"]
Retorna
Promise<void>

screenrig.emit(code)#

Use quando o agente deve ver que algo aconteceu: uma página terminou uma etapa, um formulário de quiosque foi enviado, a aplicação comprovou que rodou. Este é um evento nomeado da aplicação, que aparece no log de eventos do projeto onde o agente o acompanha com o CLI incluído events list ou events follow. Um código, sem corpo de mensagem.

log não é um substituto. Um diagnóstico não é um evento de aplicativo, e um agente lendo o log de eventos não o verá.

window.screenrig.emit("menu.rendered");

Os métodos emit() e emitConfirmed() do SDK adicionam registros application.event cujo recurso é a tela. Leia-os com --type application.event, adicionando --screen-id opcionalmente. Os campos retornados details.primitive_id e details.code identificam a primitiva emissora e a ação nomeada. --app-id seleciona eventos do recurso de aplicação, de suas versões e de suas entradas K/V, portanto exclui esses eventos de tela.

screenrig events list --type application.event --screen-id scr_SCREEN
ParâmetroTipoNotas
codestringSanitizado para [A-Za-z0-9._-], no máximo 64 caracteres.
Retorna
void

screenrig.emitConfirmed(code)#

Use quando a aplicação deve saber que o evento chegou: um pedido de quiosque foi feito, um formulário enviado, uma visita finalizada. Envia o mesmo evento nomeado da aplicação que emit, e sua promessa é resolvida somente quando o Player confirma que o backend aceitou o evento.

Rejeita com o problema do backend quando o evento é recusado, e com ack_timeout após 10 segundos sem resposta. Não tente novamente automaticamente após um timeout: o backend pode já ter aceitado o evento. Um recibo prova que o evento está no log de eventos do projeto, não que algo já tenha agido sobre ele.

Recibos funcionam em todo Player que executa aplicativos.

await window.screenrig.emitConfirmed("order.placed");
ParâmetroTipoNotas
codestringSanitizado para [A-Za-z0-9._-], no máximo 64 caracteres.
Retorna
Promise<void>

screenrig.log({ level, code, message })#

Use para diagnósticos: o debug, info, warn e error são textos que o Player e o runtime coletam enquanto a aplicação está na tela. O runtime injetado registra por este método. O registro é limitado: 32 linhas por cliente e no máximo 2048 bytes por mensagem. Registre o que você gostaria durante a depuração, não uma linha por quadro.

Não use log quando quiser dizer emit. Agentes não tratam linhas de log como eventos de aplicação, então tudo que o agente precisa agir deve estar em um código emit.

window.screenrig.log({
  level: "warn",
  code: "menu.stale",
  message: "Falling back to the cached menu."
});
CampoTipoNotas
levelstringdebug, info, warn ou error.
codestringSanitizado para [A-Za-z0-9._-], no máximo 64 caracteres.
messagestringNo máximo 2048 bytes.
Retorna
void

screenrig.onResize(handler)#

Assine quando o layout pode mudar sob você em vez de ler context uma vez. O manipulador recebe { viewport, primitive }, os mesmos dois objetos que context carrega, e a chamada retorna a função que encerra a assinatura.

const stopResize = window.screenrig.onResize(function (size) {
  render(size.viewport, size.primitive);
});

stopResize();
Retorna
função unsubscribe

screenrig.onCapabilities(handler)#

Assine quando as capacidades concedidas podem mudar em vez de decidir uma vez na inicialização. Leia screenrig.capabilities dentro do manipulador para os booleanos atuais e habilite ou oculte os controles afetados; a chamada retorna a função que encerra a assinatura.

const stopCapabilities = window.screenrig.onCapabilities(function () {
  saveButton.hidden = !window.screenrig.capabilities["kv.write"];
});
Retorna
função unsubscribe

screenrig.destroy()#

Desmonte os ouvintes quando o aplicativo terminar com o runtime. Um aplicativo que roda por toda sua vez e deixa o Player substituir o documento não precisa chamar isso.

Retorna
void

screenrig.kv#

A loja de chave/valor do aplicativo, para estado vivo do aplicativo que sobrevive a uma ativação. Cinco métodos próprios: get, list, set, delete e onChange. Veja a loja de chave/valor abaixo.

Tipo
namespace

O armazenamento de chave/valor

Use a loja para o estado ao vivo do aplicativo: o menu que o aplicativo renderiza, o texto que um operador alterou esta manhã, um contador deixado pela última ativação. Leia com kv.get e kv.list, escreva com kv.set e kv.delete, e receba notificações de toda alteração com kv.onChange.

A loja pertence ao id do aplicativo em context.application_id, não a um release, então uma entrada sobrevive ao próximo app upload. Valores são bytes, então texto, JSON e pequenos binários fazem round-trip. Leituras precisam de kv.read e escritas precisam de kv.write; verifique a flag antes de chamar.

A loja e seu push de alterações rodam em todo Player que executa aplicativos: o app web Player (PWA), Android, Amazon Signage Stick, macOS, Windows, Linux, Raspberry Pi, LG webOS Signage, BrightSign e Samsung Smart Signage (Tizen). Apple TV, iPhone e iPad não executam aplicativos; veja suporte a primitivas por plataforma.

screenrig.kv.get(key)#

Ler estado ao vivo do aplicativo. Aguarde a promessa.

const entry = await window.screenrig.kv.get("menu");
Exige
capabilities["kv.read"]
Retorna
promessa

screenrig.kv.list()#

Ler estado ao vivo do aplicativo quando você ainda não conhece as chaves: isso lista as chaves que o aplicativo armazenou. Aguarde a promessa.

const keys = await window.screenrig.kv.list();
Exige
capabilities["kv.read"]
Retorna
promessa

screenrig.kv.set(key, value, options)#

Escreva o estado da aplicação ao vivo. value é uma string ou um Uint8Array; options é opcional.

await window.screenrig.kv.set("menu", JSON.stringify(menu), {
  contentType: "application/json"
});

await window.screenrig.kv.set("badge.png", pngBytes, {
  contentType: "image/png"
});
ParâmetroTipoObrigatórioNotas
keystringsimVeja chaves.
valuestring ou Uint8ArraysimOs bytes para armazenar.
options.contentTypestringnãoPadrão para text/plain para uma string e application/octet-stream para um Uint8Array.
options.expectedRevisioninteiro não negativonãoEscreva somente se a entrada ainda estiver nesta revisão.
options.idempotencyKeystringnãoTentar gravar novamente sem aplicar duas vezes.
Exige
capabilities["kv.write"]
Retorna
promessa

screenrig.kv.delete(key, expectedRevision, options)#

Escreva o estado da aplicação ao vivo removendo uma entrada. expectedRevision é opcional: omita para excluir a entrada atual ou forneça para rejeitar alterações concorrentes.

await window.screenrig.kv.delete("menu");
ParâmetroTipoObrigatórioNotas
keystringsimVeja chaves.
expectedRevisioninteiro não negativonãoA revisão em que a entrada estava quando você a leu.
options.idempotencyKeystringnãoTentar excluir novamente sem aplicar duas vezes.
Exige
capabilities["kv.write"]
Retorna
promessa

screenrig.kv.onChange(handler)#

Atualize o estado da aplicação ao vivo no momento da mudança em vez de consultá-lo periodicamente. O manipulador é executado sempre que qualquer chave desta aplicação muda, quem quer que a tenha escrito: o agente com kv set, um sistema externo por meio de um webhook de chave/valor, ou esta aplicação em qualquer tela. Ele recebe qual chave mudou, não o valor, então leia o novo valor com kv.get. A chamada retorna a função que encerra a inscrição.

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();

Assine antes da primeira leitura, para que uma alteração que ocorra enquanto você lê não seja perdida; um manipulador registrado antes da ativação inicia assim que a página estiver ativa. Chame stopChanges() para encerrar a assinatura.

Uma mudança alcança toda tela cuja playlist coloca este aplicativo em segundos. Várias escritas rápidas para uma chave podem chegar como uma mudança carregando a revisão mais nova, então trate uma mudança como "leia esta chave novamente", não como uma contagem de escritas. Uma mudança é um sinal, não um histórico: leia o que precisar quando o aplicativo iniciar, então siga as mudanças.

CampoTipoNotas
keystringA chave que mudou.
revisioninteiro, opcionalA nova revisão da entrada. Ausente quando deleted é true.
deletedbooleantrue quando a chave foi excluída.
Exige
capabilities["kv.read"]; sem ele o manipulador nunca é executado
Retorna
função unsubscribe

Chaves

Uma chave tem de 1 a 256 bytes UTF-8. O limite é em bytes, não caracteres, então uma chave com caracteres multibyte atinge o limite antes do que seu comprimento sugere. Uma chave não deve começar com _screenrig/; esse prefixo pertence ao runtime injetado.

Revisões e idempotência

Cada entrada carrega uma revisão. Opcionalmente, passe expectedRevision para screenrig.kv.set ou screenrig.kv.delete para escrever apenas se a entrada ainda estiver na revisão que você leu. Uma revisão desatualizada significa que outra pessoa escreveu primeiro: leia a entrada novamente, reaplique sua alteração e tente novamente.

idempotencyKey cobre a outra metade. Uma gravação que pode ser tentada novamente após uma resposta perdida pode carregar a mesma chave em cada tentativa, e a loja a aplica uma vez.

A mesma loja do CLI

O agente pode acessar essas entradas fora do navegador com os comandos kv do CLI incluído contra o id app_ de app upload. Essa é a visão do operador da loja. Não substitui os cinco métodos acima: um aplicativo altera seus próprios dados por meio de screenrig.kv no navegador, enquanto está na tela. Uma alteração feita pelo agente alcança o aplicativo em execução por meio de kv.onChange.

Enviar dados de outro sistema

Um webhook chave/valor é uma URL que grava uma chave deste aplicativo. Entregue para qualquer coisa que possa enviar um POST HTTP, como um ponto de venda, um script de planilha, um cron job ou curl, e cada post substitui o valor dessa chave. Cada tela que executa o aplicativo recebe a atualização via kv.onChange em segundos, sem nova versão e sem agente no meio.

O agente cria um para uma chave com o CLI incluído e fornece sua URL e segredo:

screenrig kv webhook create menu --app-id app_01EXAMPLEAPP00000000000 --description "Point of sale menu feed"

A resposta traz o url do webhook e seu secret (srkw_…). O segredo é mostrado apenas na criação do webhook e na rotação do segredo, então insira-o no sistema de envio imediatamente. A URL não é secreta; o segredo é.

O remetente envia o novo valor como corpo bruto da requisição, com o segredo no cabeçalho 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"}'

Um remetente que só usa autenticação HTTP Basic usa o id do webhook como nome de usuário e o segredo como senha:

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"}'
  • O corpo, no máximo 1 MiB, torna-se o valor, e Content-Type seu tipo de conteúdo (application/octet-stream quando o cabeçalho está ausente). O valor alcança o aplicativo do navegador, então nunca poste uma credencial como valor.
  • Cada postagem é uma gravação de chave/valor como kv set: substitui o valor, aumenta a revisão e é contabilizada para armazenamento como qualquer outra gravação.
  • A resposta é os novos metadados da chave (key, revision, bytes, sha256, content_type e updated_at), nunca seu valor.
  • Adicione um cabeçalho Idempotency-Key (8 a 200 caracteres) para tentar um post com segurança: dentro de 24 horas a mesma chave vale uma vez, e a mesma chave com outro corpo ou tipo de conteúdo é recusada com idempotency_mismatch. Sem ele, cada post é uma nova gravação.
  • Um webhook aceita até 120 posts por minuto; além disso a resposta é 429 com Retry-After.
  • Um segredo ausente ou errado, ou um webhook desconhecido, responde 401. Um segredo na URL ou na string de consulta nunca é aceito.
  • Uma aplicação tem até 20 webhooks. kv webhook rotate-secret emite um novo segredo e o antigo para imediatamente; kv webhook delete para a URL imediatamente e mantém o valor da chave no lugar.

Um cartão também aceita webhooks: um envio constrói o documento de dados dele, como está ou por meio de um mapeamento (Webhooks de cartão).

Comandos webhook chave/valor →

O dispositivo

Um aplicativo que controla um painel de parede ou um quiosque pode comandar a tela em que está. As flags device vão para o frame que controla a página (o controlador da página, ou seu único aplicativo), em um Player que consegue fazer o trabalho nesse dispositivo: o Player Android concede device.display, device.keys e device.network, concede device.presence quando o dispositivo tem câmera e a pessoa que configurou o dispositivo permitiu que o Player a use (Configurações do Android, Apps, screenRIG Player, Permissões, Câmera), device.light quando tem um sensor de luz e device.haptics quando tem um vibrador. Os Players que não conseguem controlar um dispositivo deixam toda flag device como false. display.get(), display.set() e vibrate() rejeitam com not_supported em um Player que não os oferece e com capability_denied sem a flag. onDisplay, onPresence, onKey, onLight e onNetwork podem ser registrados a qualquer momento e, como kv.onChange, simplesmente nunca rodam sem a flag.

screenrig.device.display.set(state)#

Reduzir o brilho, escurecer ou acordar a tela. brightness vai de 0 a 1 (0 é o mais baixo que a luz de fundo chega, não desligada); on: false escurece a tela e on: true a acende de novo. Omita um membro para deixá-lo como está. Os toques continuam chegando ao aplicativo enquanto a tela está escura, então um toque pode acordá-la. Uma programação de exibição que mantém a tela escura prevalece sobre o aplicativo, e o Player restaura a tela quando a página deixa de ser exibida.

await window.screenrig.device.display.set({ brightness: 0.3 });
await window.screenrig.device.display.set({ on: false });
Resolve com
{ on, brightness }, a tela depois da chamada (brightness é null quando o Player não consegue lê-lo); set({}) apenas lê, e brightness mantém seu valor enquanto a tela está escura
Exige
capabilities["device.display"]

screenrig.device.display.get()#

O estado atual da tela, como { on, brightness }.

Exige
capabilities["device.display"]

screenrig.device.onDisplay(handler)#

Chamado com { on, brightness } sempre que a tela muda, seja por este aplicativo, por uma programação de exibição ou por um operador.

Retorna
função unsubscribe
Exige
capabilities["device.display"]

screenrig.device.onPresence(handler)#

Chamado quando o dispositivo vê alguém se mover diante da tela, no máximo uma vez por segundo. O Player lê a câmera do dispositivo e não guarda nenhuma imagem: nenhuma imagem é armazenada, registrada em log ou enviada. A câmera só funciona enquanto houver um manipulador registrado.

window.screenrig.device.onPresence(function () {
  window.screenrig.device.display.set({ on: true, brightness: 1 });
});
Retorna
função unsubscribe
Exige
capabilities["device.presence"]

screenrig.device.onKey(handler)#

Chamado com "volume_up" ou "volume_down" a cada pressionamento de uma tecla física de volume, incluindo repetições. Enquanto houver um manipulador registrado, as teclas pertencem ao aplicativo e o volume do dispositivo permanece como está.

Retorna
função unsubscribe
Exige
capabilities["device.keys"]

screenrig.device.onLight(handler)#

Chamado com a luz ambiente em lux: a primeira leitura depois que o manipulador é registrado, depois sempre que a luz muda em pelo menos 10% ou em 1 lux, no máximo uma vez por segundo. O dispositivo precisa de um sensor de luz.

window.screenrig.device.onLight(function (lux) {
  document.body.classList.toggle("dim-room", lux < 10);
});
Retorna
função unsubscribe
Exige
capabilities["device.light"]

screenrig.device.onNetwork(handler)#

Chamado com true ou false sempre que o dispositivo ganha ou perde conectividade com a internet validada pelo sistema, e imediatamente com o estado atual quando o primeiro manipulador é registrado.

window.screenrig.device.onNetwork(function (online) {
  offlineBadge.hidden = online;
});
Retorna
função unsubscribe
Exige
capabilities["device.network"]

screenrig.device.vibrate(ms)#

Emita um pulso háptico. ms é um número inteiro de milissegundos de 1 a 200 e o padrão é 12. A promessa é resolvida sem valor assim que o Player inicia a vibração, e é rejeitada com invalid_request, sem enviar nada, para qualquer outro ms.

await window.screenrig.device.vibrate();
await window.screenrig.device.vibrate(40);
Resolve com
sem valor
Exige
capabilities["device.haptics"]

Alcance dispositivos na rede da tela

Um aplicativo pode buscar dados de endereços http:// e ws://, além de https://, e assim conversar com um dispositivo ou servidor na própria rede da tela, como um controlador em http://192.168.1.20. Os Players Android, Linux e Raspberry Pi, Windows e macOS permitem isso. Em um navegador de quiosque que executa o app web do Player, o proprietário do navegador permite isso com uma política empresarial: veja Aplicativos na rede local. O servidor que você chama responde ao CORS para a origem do aplicativo; no macOS, as requisições de um aplicativo trazem Origin: null, então o CORS do servidor permite essa origem ali.

Um mecanismo de navegador bloqueia <img src="http://…"> em uma página segura, então carregue imagens de um endereço http:// com fetch() e URL.createObjectURL().

const response = await fetch("http://192.168.1.20/snapshot.jpg");
image.src = URL.createObjectURL(await response.blob());

Criar e posicionar o aplicativo