tv-quarto
by Lanryyy
README.md
# tv-quarto
Transforma uma TV em **terceira tela do PC** (tela estendida, não espelhamento) pela rede, com um botão na área de trabalho e um **servidor MCP** para o Claude controlar tudo por linguagem natural.
> *Turn a TV into an extended (not mirrored) 3rd monitor of a Windows PC over the LAN, with a one-click desktop app and an MCP server so Claude can drive it.*
```
PC Windows Box Android (UniTV) TV (Hisense VIDAA)
┌──────────────────────────────┐ rede ┌────────────────────┐ HDMI ┌──────────────────┐
│ Virtual Display Driver │ (HEVC) │ Moonlight │─────▶│ entrada HDMI │
│ └ monitor virtual (3ª tela) │──────────▶ │ decodifica vídeo │ │ │
│ Sunshine (encoder da GPU) │ └────────▲───────────┘ └────────▲─────────┘
│ app.py / server.py (MCP) ────┼──── ADB (rede) ─────┘ │
│ ─────┼──── MQTT (vidaa-control): liga, entrada, volume ┘
└──────────────────────────────┘
```
- O monitor virtual **só existe durante a transmissão**: o Sunshine o liga quando a sessão começa e o desliga quando ela termina. Fora disso o Windows continua com as telas normais.
- O **áudio fica no PC** (fone/caixas). Ele não é enviado para a TV.
- Resoluções 1080p, 1440p e 4K, que se trocam pelo app.
## Hardware testado
| Peça | Modelo usado | Observação |
|---|---|---|
| PC | Windows 11, GPU AMD RX 6750 XT | Qualquer GPU com encoder suportado pelo Sunshine (NVENC, AMF, QuickSync) |
| Box | UniTV V10 (Allwinner H616, Android 10, 1 GB) | Qualquer Android com Moonlight. As partes de saída HDMI são específicas da Allwinner |
| TV | Hisense com VIDAA | Liga, desliga e troca de entrada via MQTT. Sem Hisense, o resto funciona e você troca a entrada no controle |
## Pré-requisitos
- Windows 10/11 com `winget` e Python 3.10+.
- O PC e o box na mesma rede local. **Cabo no PC é recomendado**; no box, cabo ou Wi-Fi de 5 GHz.
- No box: **Opções do desenvolvedor** ativadas, com **Depuração USB** e **Depuração ADB pela rede**. Em geral: Configurações → Sobre → clique 7× em "Versão".
## Instalação
### 1. Programas no PC
```powershell
winget install LizardByte.Sunshine
winget install VirtualDrivers.Virtual-Display-Driver
winget install Google.PlatformTools
```
Abra `https://localhost:47990` e crie o usuário do Sunshine.
### 2. Projeto
```powershell
git clone https://github.com/<seu-usuario>/tv-quarto.git
cd tv-quarto
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt
copy config.example.json config.json
```
Edite o `config.json`:
| Campo | O que é |
|---|---|
| `unitv_addr` | IP do box + `:5555` (porta do ADB) |
| `hisense_host` | IP da TV |
| `hisense_unitv_source` | Entrada da TV onde o box está ligado (`hdmi1`…`hdmi4`) |
| `hisense_mac` | MAC da TV. Pode deixar `null`: ele é lido da tabela ARP |
| `sunshine_pc_uuid` | ID do PC no Sunshine. Pode deixar `null`: ele é lido de `sunshine_state.json` |
| `adb_path` | Caminho do `adb.exe`. Pode deixar `null`: ele é procurado no PATH e na pasta do winget |
| `stream_profile` | `1080p`, `1440p` ou `4k`. O app atualiza este campo |
### 3. Monitor virtual + Sunshine
Num **PowerShell como administrador**:
```powershell
powershell -ExecutionPolicy Bypass -File scripts\setup-pc.ps1
```
O script instala o driver do monitor virtual e configura o `sunshine.conf`. Ele mantém suas outras configurações e faz backup em `sunshine.conf.bak`. Também desliga o envio de áudio, aponta o Sunshine para o monitor virtual e o liga e desliga junto com a sessão. Pode rodar de novo sem problema.
### 4. Moonlight no box
```powershell
adb connect <ip-do-box>:5555 # aceite "Sempre permitir deste computador" na TV
```
Baixe o APK do [Moonlight Android](https://github.com/moonlight-stream/moonlight-android/releases) e instale com `adb install`. Depois:
1. Abra o Moonlight, clique no PC e digite o PIN mostrado na aba **PIN** do painel do Sunshine.
2. Em **Configurações → Mudar configurações do HEVC**, escolha **Prefira HEVC**.
O Moonlight não confia no decodificador HEVC da Allwinner e cai para H.264, que nesse chip dá tela verde em 4K e borrões em 1080p.
### 5. Parear a TV Hisense
```powershell
.venv\Scripts\python pair_hisense.py
```
A TV mostra um PIN de 4 dígitos, válido por cerca de 1 minuto. Digite-o no terminal. Se o PIN não aparecer, rode de novo: às vezes ele só aparece na segunda tentativa.
### 6. Atalho na área de trabalho
```powershell
powershell -ExecutionPolicy Bypass -File scripts\create-shortcut.ps1
```
## Uso
### App da área de trabalho
O atalho **TV do quarto** abre uma janela com:
- **Ligar na TV / Desligar terceira tela**: liga a TV, troca a entrada, acorda o box, abre a sessão no Moonlight e ajusta a resolução do monitor virtual. Desligar encerra a sessão, e o monitor virtual some.
- **Resolução**: 1080p, 1440p ou 4K. Se estiver transmitindo, ele reinicia a transmissão com a nova resolução (cerca de 30 a 40 s).
A tela da TV fica à direita da principal. Arraste janelas para lá.
### MCP (Claude Code)
Copie `.mcp.example.json` para `.mcp.json`, ajuste os caminhos e abra o Claude Code nesta pasta. Exemplos: *"liga a TV como terceira tela"*, *"coloca em 1440p"*, *"abaixa o volume da TV para 10"*, *"tira um print da TV"*.
| Ferramenta | Função |
|---|---|
| `start_stream` / `stop_stream` | Liga e desliga a terceira tela |
| `set_resolution` | `1080p`, `1440p` ou `4k` |
| `status` | Estado da TV, do box, da transmissão e do monitor virtual |
| `unitv_screenshot` | Print do que o box está mostrando |
| `unitv_keys`, `unitv_type_text`, `unitv_list_apps`, `unitv_launch_app` | Controle do box |
| `hisense_power`, `hisense_keys`, `hisense_volume`, `hisense_sources`, `hisense_set_source`, `hisense_launch_app` | Controle da TV |
| `hisense_pair_start` / `hisense_pair_finish` | Pareamento da TV |
## Resoluções e desempenho
Medido com uma animação de 64 fps no monitor virtual, contando os quadros exibidos pelo box (`dumpsys SurfaceFlinger --latency`):
| Perfil | Monitor virtual | Saída HDMI do box | Quadros na TV |
|---|---|---|---|
| 1080p | 1920×1080 @ 60 | 1080p60 | **60 fps** |
| 1440p | 2560×1440 @ 60 | 2160p60 (o box amplia) | ~50 fps |
| 4K | 3840×2160 @ 60 | 2160p60 | ~43 fps |
Nos perfis acima de 1080p, o limite é o decodificador do H616. Um box mais forte (Chromecast 4K, Fire TV 4K Max, Shield) deve manter 60 fps.
## Detalhes técnicos
- **A resolução do monitor virtual não segue o cliente.** As opções `dd_*` do Sunshine rodam *antes* do `global_prep_cmd` ligar o monitor e falham com `DevicePrepFailed`. Por isso o `server.py` define o modo com `ChangeDisplaySettingsExW` logo depois que a sessão começa.
- **4K60 escondido no box Allwinner.** O menu do UniTV só lista 4K até 30 Hz, mas o modo 34 (2160p60) é suportado. O `server.py` grava o modo direto no serviço `display_output` (`com.softwinner.IDisplayOutputManager`), com os códigos de binder tirados do `DisplayDaemon.jar`:
| Código | Operação |
|---|---|
| 4 | ler o modo atual |
| 5 | gravar um modo |
| 11 | verificar se um modo é suportado |
```
adb shell service call display_output 5 i32 0 i32 34
```
O AUTO do menu e o `setprop persist.disp.*` não servem: o driver volta ao modo gravado no boot.
- **Fechar a sessão é diferente de desconectar.** Sair do stream com "Voltar" deixa a sessão aberta no PC, e o monitor virtual continua lá. O `stop_stream` usa "Sair da Sessão" no Moonlight.
- **Automação do Moonlight.** É feita pela interface, com `uiautomator`. Os textos procurados estão em português (pt-BR) com alternativa em inglês. Em outro idioma, ajuste `server.py`.
- **`vidaa-control` escreve no stdout**, o que corromperia o canal stdio do MCP. Por isso todas as chamadas passam por `quiet()`.
## Segurança e avisos
- **ADB pela rede** dá controle total do box a qualquer um na sua rede local. Use apenas em rede de confiança.
- **`vidaa-control`** é um projeto não oficial: usa o certificado do app VIDAA e um protocolo obtido por engenharia reversa. Uma atualização de firmware da TV pode quebrar o controle.
- Os comandos de binder e os modos HDMI foram testados em um UniTV V10 (Allwinner H616). Em outro aparelho, confirme antes com o código 11 (verificar suporte).
- Use por sua conta e risco.
## Créditos
[Sunshine](https://github.com/LizardByte/Sunshine) · [Moonlight](https://github.com/moonlight-stream/moonlight-android) · [Virtual Display Driver](https://github.com/VirtualDrivers/Virtual-Display-Driver) · [vidaa-control](https://github.com/tombabolewski/vidaa-control) · [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)
## Licença
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues