Manual de instalação e funcionamento — CLKCast
Este manual cobre o ciclo completo: subir o backend/painel, cadastrar conteúdo, e instalar o app numa TV (ou num TV box) — incluindo como simular um TV box na sua própria máquina antes de mexer num dispositivo de verdade.
Ver também docs/arquitetura.md pra uma visão técnica
dos componentes e como eles se conectam.
- 1. Visão geral
- 2. Requisitos
- 3. Subindo o backend
- 4. Primeiro acesso ao painel
- 5. Cadastro de conteúdo, grupos e TVs
- 6. Instalando o app numa TV
- 7. Headwind MDM (opcional)
- 8. Simulando um TV box na sua máquina
- 9. Troubleshooting
1. Visão geral
O CLKCast tem três partes que rodam de forma independente:
- Backend + painel (
docker-compose.yml, na raiz) — API, banco, storage de mídia e a interface web de administração. Roda num servidor (ou na sua máquina, pra testar) e fica de pé o tempo todo. - App Android TV (
android/) — o player que roda em cada TV/TV box, instalado uma vez por dispositivo. - Headwind MDM (
hmdm/) — opcional, facilita instalar/atualizar o app nas TVs remotamente. Sem ele, a instalação é manual (via ADB).
2. Requisitos
- Docker + Docker Compose (pro backend/painel/HMDM)
- Android Studio ou só o
adb/gradlew(pra buildar e instalar o app) - Um TV box/TV com Android (ou o emulador — ver seção 7) com depuração USB habilitada, se for instalar via ADB
3. Subindo o backend
cp .env.example .env # ajuste os valores antes de produção
docker compose up -d --build postgres backend frontend minio
- Painel:
http://localhost:8080 - API:
http://localhost:8000
Importante pra usar com TVs de verdade (não só testando na mesma
máquina): troque MINIO_PUBLIC_URL no .env pro IP real do servidor
na rede (ex: http://192.168.1.50:9000) — as TVs precisam alcançar essa
URL pra baixar fotos/vídeos, e localhost só funciona a partir da própria
máquina que roda o Docker.
⚠️ Isso também vale testando no emulador (seção 8), não só em TV
física — já aconteceu neste projeto: com MINIO_PUBLIC_URL=localhost, o
vídeo tocava normal no navegador do painel mas ficava com tela preta
no app (erro unexpected end of stream no ExoPlayer/logcat), porque
localhost de dentro do emulador/dispositivo não aponta pro host. A
correção é usar o IP da rede Wi-Fi/Ethernet real da máquina (ex:
192.168.x.x, veja com ipconfig/ifconfig) em vez de localhost —
funciona tanto do navegador do host quanto do emulador quanto de uma TV
física. Se você já tinha cadastrado conteúdo antes de fazer essa troca,
as URLs antigas continuam salvas erradas no banco — corrija na mão
(UPDATE content SET url = replace(url, 'http://localhost:9000', 'http://SEU-IP:9000'); direto no Postgres) ou edite cada item pelo
painel.
3.1. Alternativa: instalar sem clonar o repositório
O comando acima builda backend/frontend a partir do código-fonte —
ótimo pra desenvolvimento, mas exige clonar o repositório e ter o
código na máquina. Pra instalar num servidor novo só com Docker, sem
precisar do código-fonte, use as imagens já publicadas no Docker Hub
(cloutrik/clkcast-backend, cloutrik/clkcast-frontend — ver
docs/arquitetura.md):
mkdir clkcast && cd clkcast
curl -O https://raw.githubusercontent.com/Cloutrik/CLKCast/main/docker-compose.prod.yml
curl -O https://raw.githubusercontent.com/Cloutrik/CLKCast/main/.env.example
cp .env.example .env # ajuste os valores antes de produção
docker compose -f docker-compose.prod.yml up -d postgres backend frontend minio
Funciona igual ao fluxo de build local (mesmas portas, mesmas variáveis
de ambiente no .env) — a diferença é só de onde vêm as imagens de
backend/frontend. Pra atualizar depois de uma nova versão publicada:
docker compose -f docker-compose.prod.yml pull backend frontend
docker compose -f docker-compose.prod.yml up -d backend frontend
4. Primeiro acesso ao painel
- Acesse
http://localhost:8080(ou o IP do servidor) — vai cair na tela de login. - Entre com
ADMIN_USERNAME/ADMIN_PASSWORDdo.env(defaultadmin/clkcast).
5. Cadastro de conteúdo, grupos e TVs
- Conteúdo — cadastre fotos, vídeos ou URLs (upload de arquivo ou colar uma URL já hospedada).
- Grupos (opcional) — agrupe TVs que devem exibir o mesmo conteúdo.
- TVs — cada TV aparece sozinha na lista (com status "Aguardando pareamento") depois que o app abre nela pela primeira vez (ver seção 6). Pra vincular, o jeito mais simples é clicar no botão "Vincular" na própria linha e salvar um nome — não precisa digitar nenhum código quando é só uma TV pendente por vez. Se tiver várias TVs pendentes ao mesmo tempo e precisar garantir qual é qual, use o botão "Vincular por código" (o código de 6 dígitos aparece na tela da TV específica).
- Atribua conteúdo à TV específica e/ou ao grupo dela — a playlist final é a mescla dos dois, ordenada.
6. Instalando o app numa TV
6.1. Build do APK
cd android
./gradlew assembleDebug
Gera android/app/build/outputs/apk/debug/app-debug.apk. O endereço do
backend não precisa ser configurado antes de buildar — na primeira
execução do app, ele mostra uma tela pra digitar o endereço do servidor
(valida com GET /health antes de salvar). CLKCAST_API_BASE_URL em
android/gradle.properties só pré-preenche essa tela (conveniência pro
emulador, default http://10.0.2.2:8000/); numa TV real, digite o IP do
servidor direto na tela quando o app abrir pela primeira vez.
O build
assembleDebugserve pra testes/simulação interna. Antes de distribuir de verdade (ex: via Headwind MDM em produção), gere um build assinado (assembleRelease+ keystore) — isso ainda não está configurado neste projeto.
6.2. Opção A — instalação manual via ADB (mais simples, poucas TVs)
Com a TV/TV box na mesma rede e depuração USB/rede habilitada:
adb connect <ip-da-tv>:5555 # se for ADB via rede
adb install app-debug.apk
Abra o app na TV — na primeira execução ele pede o endereço do servidor
(digite http://<ip-do-backend>:8000/ e confirme). Validado o servidor,
a TV aparece sozinha na lista do painel como "Aguardando pareamento".
Clique em "Vincular" na linha dela, dê um nome, salve. Pronto — a TV já
começa a puxar a playlist.
Essa é a via recomendada pro TV box sem câmera (a maioria) — não dá pra usar o QR code de enrollment do Headwind MDM sem câmera (ver seção 7.4).
6.3. Opção B — via Headwind MDM (escala, várias TVs)
Ver seção 7 — o HMDM permite empurrar o APK remotamente pra várias TVs de uma vez e manter modo kiosk, mas o enrollment inicial de um dispositivo sem câmera também precisa de um passo manual (instalar o agente do HMDM como APK comum, não por QR).
6.4. Opção C — Play Store (planejado, ainda não publicado)
O app foi desenhado pra isso: o endereço do servidor é configurado na
tela inicial do app (seção 6.1), não fixado no APK — então, uma vez
publicado, instalar via Play Store seria só buscar "CLKCast", instalar,
abrir e digitar o endereço do servidor, sem precisar de ADB nem HMDM.
Isso ainda não foi feito (falta build assinado — assembleRelease +
keystore, ver nota da seção 6.1 — e a ficha/publicação em si na Play
Console). Ver docs/arquitetura.md.
7. Headwind MDM (opcional)
7.1. Subindo
docker compose up -d hmdm-postgres hmdm-server
Primeira subida demora ~4-5min (baixa o .war). Depois de confirmar que
subiu certo, edite docker-compose.yml: FORCE_RECONFIGURE de "true"
pra "false" e reinicie (docker compose up -d hmdm-server) — sem isso,
todo restart volta a demorar os mesmos 4-5min à toa.
7.2. Configuração pra rede real
No .env, ajuste antes de usar com TVs de verdade:
HMDM_BASE_DOMAIN=<ip-do-servidor> # não localhost
HMDM_LOCAL_IP=<ip-do-servidor-se-atras-de-nat>
7.3. Acesso e primeiro login
http://<ip-do-servidor>/ (porta 80). Login admin/admin — força
troca de senha no primeiro acesso.
7.4. Enrollment de um dispositivo — dois métodos
O HMDM suporta dois métodos de enrollment (confirmado na documentação oficial, h-mdm.com/quick-start):
- QR code (padrão): em Configurações, clique no ícone de QR da configuração desejada, e na TV toque 6x na tela de boas-vindas inicial pra abrir o modo de provisionamento — precisa de câmera.
- APK comum (alternativa oficial pra dispositivos sem câmera): baixe o agente do HMDM como um APK normal e instale via ADB, igual à seção 6.2. Isso NÃO dá Device Owner completo ao HMDM (algumas garantias de bloqueio/kiosk ficam mais fracas que via QR), mas ainda permite gerenciar o dispositivo.
A maioria dos TV boxes não tem câmera — planeje usar o método via APK comum, não o QR code.
7.5. Ainda falta fazer (não testado)
- Subir o APK do CLKCast em "Aplicativos" no HMDM e vincular a uma Configuration, pra ele empurrar automaticamente pras TVs.
- Configurar modo kiosk restringindo a TV só ao app do CLKCast.
- Testar o enrollment via APK comum (seção 7.4) numa TV/emulador real.
- HTTPS real (hoje só
PROTOCOL=http, ok pra rede local).
8. Simulando um TV box na sua máquina
Dá sim pra simular sem precisar de hardware — e do jeito mais realista possível, já que emuladores Android também não têm câmera de verdade por padrão, então o teste reproduz exatamente a limitação real (seção 7.4: precisa instalar via APK comum, não QR).
8.1. Emulador Android TV (recomendado)
O Android Studio/SDK já usado neste projeto suporta criar um dispositivo virtual (AVD) com uma imagem de sistema Android TV (interface Leanback, controle por D-pad em vez de touch) — mais fiel a um TV box real que um emulador de celular comum.
Passos (via Android Studio, mais simples que linha de comando):
- Abra o Device Manager no Android Studio.
- "Create Device" → categoria TV → escolha um perfil (ex: "Android TV (1080p)").
- Escolha uma imagem de sistema Android TV (baixa automaticamente se não tiver — o download é grande, ~1GB).
- Inicie o emulador.
- Instale o app:
adb install app-debug.apk(o emulador já aparece como device noadb devices). - Na tela de configuração de servidor que abre no primeiro uso, digite
http://10.0.2.2:8000/(já vem pré-preenchido, default deCLKCAST_API_BASE_URL) — é como o emulador acessa olocalhostda sua máquina.
✅ Validado neste projeto com um AVD Android TV real (android-36; android-tv;x86_64, 1920x1080, sem câmera, D-pad): o app renderizou em
tela cheia no formato correto de TV (não o layout vertical de celular),
o fluxo completo funcionou — registro (POST /devices/register), exibição
do código de pareamento, polling de status, e a transição pra tela de
player assim que o dispositivo foi vinculado pelo painel (heartbeat +
manifest disparados corretamente). Sem problemas encontrados.
8.2. Testando o Headwind MDM com o emulador
Como o emulador não tem câmera de verdade (mesma limitação de um TV box),
o teste do enrollment via HMDM reproduziria fielmente a seção 7.4: você
instalaria o agente do HMDM via adb install (não por QR), o que é
exatamente o método que vai usar no TV box real depois. Isso significa
que validar no emulador primeiro é um bom ensaio pra depois repetir no
hardware real sem surpresas. Ainda não testado — o teste feito neste
projeto validou o app do CLKCast no emulador de TV, mas não o enrollment
via HMDM propriamente (precisa subir o hmdm-server, que fica parado por
padrão, e repetir os passos da seção 7 apontando pro dispositivo do
emulador).
8.3. Sem Android Studio (linha de comando, sem avdmanager)
Se cmdline-tools/avdmanager não estiverem instalados (comum em setups
só com o SDK, sem Android Studio completo), dá pra criar o AVD na unha:
- Baixe a imagem de sistema direto do Google (substitua a versão se
necessário — confira em
sys-img/android-tv/sys-img2-3.xmlno repositório de imagens):curl -LO https://dl.google.com/android/repository/sys-img/android-tv/x86_64-36_r04.zipunzip x86_64-36_r04.zip -d "$ANDROID_HOME/system-images/android-36/android-tv/" - Crie
~/.android/avd/<Nome>.inie~/.android/avd/<Nome>.avd/config.inimanualmente — use um AVD existente como modelo e ajustehw.lcd.width/heightpra1920/1080,hw.dPad=yes,hw.camera.back=none/hw.camera.front=none(TV não tem câmera),tag.id=android-tv, eimage.sysdir.1apontando pra pasta baixada no passo 1. emulator.exe -avd <Nome> -no-snapshotpra iniciar.
Foi assim que o teste desta seção foi feito neste projeto (sem
avdmanager disponível no ambiente).
9. Troubleshooting
- Backend não sobe na primeira vez (
Connection refusedno log): o Postgres ainda não tinha terminado de iniciar. Orestart: unless-stoppeddo compose reinicia o backend automaticamente até conseguir conectar — espere alguns segundos e confiradocker compose ps. - QR code do HMDM não abre / erro de conexão: confira se
HMDM_BASE_DOMAINbate com a porta que o serviço está exposto (a porta 80 é proposital — verhmdm/README.md). - TV não aparece na lista depois de instalar o app: confira se o
endereço digitado na tela de configuração do app (primeira execução)
aponta pro IP certo do backend, e se a TV está na mesma rede/consegue
alcançar essa URL (teste abrindo
http://<ip>:8000/healthnum navegador na própria TV, se possível). Se digitou errado, reinstale o app (ou limpe os dados dele) pra ver a tela de configuração de novo — ainda não existe um jeito de reabri-la sem isso (verPROJECT.md).