Apps de TV (LG webOS e Samsung Tizen)

Integre o player em aplicativos empacotados para TVs LG (webOS) e Samsung (Tizen).

O player roda no navegador embutido das Smart TVs LG (webOS) e Samsung (Tizen). Este guia cobre o que muda em relação à web comum — pisos de compatibilidade, controle remoto e empacotamento. Há exemplos completos e comentados no repositório do player: webOS e Tizen.

Testado em dispositivos reais: webOS 4.5 (LG) e Tizen 5.0 (Samsung).

Vale para as duas TVs

deviceClass: 'tv'

Passe essa opção explicitamente no construtor quando você já sabe que está rodando numa TV — não deixe a decisão para a heurística automática de user agent. Detectar TV errado troca a barra para a de desktop e quebra a navegação por controle remoto (não há como usar mouse ali).

new SpallaPlayer('#player', { deviceClass: 'tv' });

isApp

Controla se a skin automática de TV entra sozinha. O player detecta quando roda dentro do app empacotado (a WebAPI de cada plataforma só existe ali), então normalmente você não precisa passar nada. Se o seu app rodar numa WebView sem essa WebAPI, ou se quiser testar num navegador comum antes de empacotar, force explicitamente:

new SpallaPlayer('#player', { deviceClass: 'tv', isApp: true });

Sem essa opção (e sem a WebAPI), o player assume que está no navegador da própria TV e usa a skin padrão em vez da automática de TV — mesmo com deviceClass: 'tv' já forçado. Não há parâmetro de URL equivalente, de propósito: uma página de terceiro não pode forjar "sou um app".

Piso de compatibilidade

O player é compilado com alvo Chromium 63, o piso dos navegadores de TV nas duas plataformas. Compilar sintaxe nova para antiga não cria, porém, APIs que simplesmente não existem no aparelho — e o sintoma de usar uma delas costuma ser silencioso (ex.: o parser de CSS descarta a regra inteira, não só a propriedade desconhecida).

APIChegou na versãoO que fazer
globalThis71já preenchido pelo player; não precisa se preocupar
ResizeObserver64evite depender disso no seu próprio código de integração
AbortController66idem
Array.prototype.flatMap69use reduce/concat no seu código
Element.replaceChildren86use innerHTML = '' + appendChild
min()/clamp() em CSS79use pares width/max-width em vez disso
:focus-visible86use :focus como alternativa
aspect-ratio em CSS88defina altura fixa (@supports not (aspect-ratio: 1))

Se você for escrever HTML/CSS/JS próprio ao redor do player (overlay, painel de diagnóstico, etc.), evite essas APIs ou forneça alternativa.

Chave de API (apiKey)

O navegador embutido de uma TV nem sempre envia o cabeçalho Referer da forma esperada — o que pode fazer a checagem de referrer bloquear conteúdo que deveria estar liberado. Para esses casos, a Spalla pode fornecer uma apiKey, que autoriza a reprodução sem restrições de referer:

new SpallaPlayer('#player', { apiKey: 'seu-jwt-fornecido-pela-spalla' });

O valor viaja apenas na chamada de autorização do conteúdo — a credencial da mídia em si continua sendo emitida pelo backend normalmente. Peça essa chave à Spalla especificamente para o seu aplicativo de TV.

LG webOS

Controle remoto

O navegador de TVs LG não tem API de registro de tecla de mídia — os códigos chegam diretamente no evento keydown do documento. No exemplo, BACK = 461 fecha o player:

document.addEventListener('keydown', (evento) => {
  if (evento.keyCode === 461) {
    /* fechar player / sair da tela */
  }
});

O player já trata as teclas de navegação (setas, OK) quando está montado; o código do seu aplicativo só precisa tratar o que está fora dele (uma lista de conteúdos, um botão de voltar, etc.).

Empacotamento

Requer o webOS TV CLI:

ares-package .
ares-install --device <nome-do-dispositivo> io.spalla.player_1.0.0_all.ipk
ares-launch --device <nome-do-dispositivo> io.spalla.player

O appinfo.json do exemplo já declara os privilégios (requiredACG) usados por ele; ajuste conforme os recursos do seu próprio aplicativo.

Samsung Tizen

Controle remoto

Ao contrário do webOS, o Tizen exige registro explícito para receber teclas de mídia — e exige também o privilégio correto no config.xml:

<tizen:privilege name="http://tizen.org/privilege/tv.inputdevice"/>

Sem esse privilégio, tizen.tvinputdevice.registerKey(...) lança uma exceção e a TV continua dona das teclas: apertar "play" no controle abre o painel do próprio televisor em vez de chegar ao seu aplicativo.

try {
  tizen.tvinputdevice.registerKey('MediaPlayPause');
} catch (erro) {
  // modelos antigos não têm todas as teclas, e sem o privilégio nenhuma passa
}

Use tizen.tvinputdevice.getSupportedKeys() para descobrir, no próprio aparelho, quais teclas de mídia ele reconhece — não há uma lista universal confiável. RETURN = 10009 fecha o player e volta para a lista (diferente do webOS, que usa BACK = 461).

Privilégios necessários

<tizen:privilege name="http://tizen.org/privilege/internet"/>
<!-- Sem isto o aparelho apaga a tela durante a reprodução. -->
<tizen:privilege name="http://tizen.org/privilege/display"/>

$WEBAPIS

$WEBAPIS/webapis/webapis.js é um placeholder resolvido pelo empacotador do Tizen em tempo de build — fora do aparelho (testando num navegador comum) esse script simplesmente não existe, e o aplicativo deve cair de volta para tratamento por teclado normal.

Empacotamento

Requer o Tizen Studio com o pacote de TV instalado:

tizen package -t wgt -s <perfil-de-assinatura> -- .
tizen install -n <arquivo>.wgt -t <id-do-dispositivo>
tizen run -p SpallaPlyr.Player -t <id-do-dispositivo>

Problemas comuns

A TV mostra a interface errada / o controle remoto não navega

O sintoma mais comum é esquecer de passar deviceClass: 'tv' explicitamente, deixando a detecção automática escolher a barra de desktop, que não tem como ser navegada sem mouse. Se a barra ainda assim não for a de TV, confira o isApp acima. Mais casos no guia de solução de problemas.

Nesta página