
BrightScript é a linguagem usada para criar canais/apps na plataforma Roku (especialmente nos modelos “legados” e em várias bases de código que ainda rodam por aí). Ela foi desenhada com um objetivo bem claro: ser simples de aprender, estável em dispositivos de TV e eficiente para interfaces e playback de vídeo. Na prática, BrightScript é menos “linguagem acadêmica” e mais “linguagem de produção”: você escreve lógica de app, conversa com componentes (telas, nós, player), trata eventos do controle remoto e integra APIs/ads.
A seguir, vou te mostrar como BrightScript funciona de verdade, do ponto de vista de quem precisa construir um app Roku com qualidade.
Gráfico: o fluxo real de um app Roku (dados → UI → player → ads)
Esse é o “caminho do sinal” dentro de um app típico (VOD ou FAST), do jeito que acontece na prática:
┌───────────────┐
│ Main.brs │
│ inicia o app │
└───────┬───────┘
│ cria
▼
┌───────────────┐
│ HomeScene │
│ UI + eventos │
└───────┬───────┘
│ chama
▼
┌───────────────┐
│ ApiService │
│ request + JSON │
└───────┬───────┘
│ retorna itens
▼
┌───────────────┐
│ MarkupGrid │
│ lista catálogo │
└───────┬───────┘
│ usuário seleciona
▼
┌───────────────┐
│ PlayerScene │
│ Video + estados│
└───────┬───────┘
│ (opcional)
▼
┌───────────────┐
│ RAF / Ads │
│ pre/mid-roll │
└───────────────┘
Por que isso é importante?
Porque BrightScript funciona melhor quando você pensa em componentes + eventos + estados (não em “telas soltas”).
Snippet completo (prático): API → Grid → clique → Player
A ideia aqui é te mostrar um recorte realista que aparece em quase todo app Roku:
1) source/main.brs (inicia o app e mostra a cena)
sub Main()
screen = CreateObject("roSGScreen")
port = CreateObject("roMessagePort")
screen.SetMessagePort(port)
scene = screen.CreateScene("HomeScene")
screen.Show()
while true
msg = wait(0, port)
end while
end sub
2) components/scenes/HomeScene.brs (carrega catálogo e reage ao clique)
sub init()
m.grid = m.top.findNode("contentGrid")
m.grid.observeField("itemSelected", "onItemSelected")
loadCatalog()
end sub
sub loadCatalog()
items = ApiService_GetCatalog()
if items = invalid or items.count() = 0 then
print "Catálogo vazio ou falha de rede"
return
end if
m.grid.content = BuildGridContent(items)
end sub
sub onItemSelected()
idx = m.grid.itemSelected
itemNode = m.grid.content.getChild(idx)
' Navega para player com o item escolhido
m.top.signalBeacon("start") ' opcional para métricas
m.top.getScene().callFunc("showPlayer", itemNode)
end sub
3) components/services/ApiService.brs (request e JSON defensivo)
function ApiService_GetCatalog() as Object
url = "https://seusite.com/api/catalog"
xfer = CreateObject("roUrlTransfer")
xfer.SetUrl(url)
rsp = xfer.GetToString()
if rsp = invalid or rsp = "" then return invalid
json = ParseJson(rsp)
if json = invalid or json.items = invalid then return invalid
return json.items ' normalmente array de itens
end function
4) components/utils/BuildContent.brs (converte JSON em ContentNode)
function BuildGridContent(items as Object) as Object
root = CreateObject("roSGNode", "ContentNode")
for each it in items
node = root.createChild("ContentNode")
node.title = it.title
node.hdPosterUrl = it.poster
node.url = it.streamUrl ' guardamos a URL para o player
end for
return root
end function
5) components/scenes/PlayerScene.brs (player, estados, e tratamento de erro)
sub init()
m.video = m.top.findNode("video")
m.video.observeField("state", "onVideoState")
end sub
sub playItem(item as Object)
content = CreateObject("roSGNode", "ContentNode")
content.url = item.url
content.streamFormat = "hls" ' exemplo
m.video.content = content
m.video.control = "play"
end sub
sub onVideoState()
st = m.video.state
print "Player state: "; st
if st = "error" then
print "Erro no playback. Exibir fallback e permitir retry."
' aqui você poderia mostrar um label de erro na UI
end if
end sub
✅ Esse conjunto já demonstra o coração do BrightScript:
- Scene inicializa UI e observa eventos
- Service faz rede e retorna dados
- Utils converte JSON em ContentNode
- Player observa estados e trata falhas
1) O “jeito Roku” de pensar: componentes + eventos
O ponto central para entender BrightScript é: você não programa “apenas funções”; você programa um app orientado a componentes e eventos.
Em Roku, quase tudo gira em torno de:
- Componentes de UI (SceneGraph, nós, telas)
- Eventos (teclas do controle, mudanças de estado, retorno de rede, timers)
- Ciclo de vida do app (inicializa, cria cena, roda loop, reage)
Ou seja: BrightScript é a camada de lógica que conecta UI, player, rede e anúncios.
2) BrightScript é simples, mas “cheio de detalhes que importam”
Tipagem e valores
BrightScript é dinamicamente tipada. Os tipos mais comuns:
- String
- Integer / Float
- Boolean
- Object (map/dicionário)
- Array
- Invalid
Na prática, aprender a tratar invalid é o que separa um app estável de um app que quebra em produção (principalmente em rede e playback).
3) Estruturas básicas: if/for, funções e escopo
BrightScript tem sintaxe bem direta:
- if / else
- for each
- while
- function / sub
Function vs Sub
functionretorna valorsubnão retorna
Isso ajuda a manter o código limpo: funções produzem dados, subs executam ações.
4) Objetos e Arrays: o coração do app
Associative Array (AA) e Arrays são usados o tempo todo.
Em streaming: JSON → AA/Array → UI → clique → playback.
O snippet acima já mostra esse pipeline de ponta a ponta.
5) Eventos e o controle remoto
A lógica é sempre: um evento acontece, você não “manda” na UI, você reage ao que a UI sinaliza — por isso observeField é tão importante.
6) SceneGraph: onde BrightScript vira app moderno
XML = estrutura visual
BrightScript = comportamento, estado, navegação, eventos
7) Rede e APIs: o mundo real
TV tem Wi-Fi ruim, CDN variando e DNS lento. Por isso:
- timeouts sensatos
- retries controlados
- fallback visual
- logs úteis
- tratamento de
invalid
8) Playback: estados e edge cases
Se toca vídeo, você precisa observar state e tratar:
- buffering
- playing
- finished
- error
9) Performance e estabilidade
Evite:
- loops pesados no thread de UI
- JSON gigante sem cuidado
- criar nós demais
- ignorar
invalid
10) Como pensar como dev Roku
Foque em 4 pilares:
- Dados → UI
- Eventos → Navegação
- Player + Ads
- Resiliência (invalid/timeouts/retry/fallback/log)