OmniMix (anteriormente vMix Controller) é um ecossistema integrado e modular de controle de estúdios e transmissões ao vivo. Ele unifica em uma única interface web de Canvas Livre o controle de software (vMix), mesas de corte físicas (Blackmagic ATEM Switchers), câmeras robóticas (PTZ Sony VISCA over IP), múltiplos fluxos de vídeo em tempo real (NDI, RTSP, WebSocket H.264 e Snapshots) e grafos de Automação por Timeline.
- Visão Geral do Sistema
- Recursos Principais
- Arquitetura do Sistema & Stack Tecnológica
- Mapeamento da Estrutura de Pastas e Arquivos
- Instalação e Configuração
- Manual Completo de Operação
- Catálogo de Comandos Suportados
- Guia de Diagnóstico e Solução de Problemas
- Diretrizes para Desenvolvedores e Agentes de IA
- Licença
Em ambientes de produção e transmissão ao vivo (como estúdios de podcast, auditórios corporativos, igrejas e emissoras de TV), a operação frequentemente requer operar simultaneamente softwares como o vMix, hardwares dedicados como mesas Blackmagic ATEM e câmeras motorizadas PTZ.
O OmniMix elimina a fragmentação de controles ao fornecer um painel único, acessível via navegador web de qualquer estação na rede local, permitindo:
- Criar mesas de corte personalizadas em minutos.
- Disparar cortes sincronizados (Hybrid Cuts) que comutam o vMix e a mesa ATEM física no mesmo milissegundo.
- Operar câmeras robóticas com joystick virtual 360° e enquadramento inteligente automático por clique e arraste com proporção de aspecto 16:9 estrita.
- Visualizar retornos ao vivo sem necessidade de hardware de captura adicional no navegador.
- 📐 Canvas Livre Totalmente Customizável: Posicione, redimensione, empilhe e personalize botões, títulos, grupos e monitores de vídeo livremente usando
react-rnd. - 🔴 Tally Dinâmico em Tempo Real (Program & Preview): Monitoramento do estado do vMix e do ATEM com indicação luminosa imediata (Vermelho = Program, Verde = Preview).
- 🎚️ Controle de Overlays 1 a 4: Faixa de botões compactos em cada widget de input para ligar/desligar camadas de GC/Title em Program (clique esquerdo) ou Preview (clique direito).
- ⚡ Cortes Híbridos Simultâneos (Hybrid Cut): Rota dedicada no backend que dispara a comutação de câmera no vMix e no ATEM em paralelo via chamadas assíncronas concorrentes.
- 🎥 Controle PTZ Avançado (Sony VISCA over IP):
- Manche virtual analógico 360° com freio cinemático progressivo configurável.
-
Atalhos no Teclado Numérico (Numpad): Manche com diagonais (
8/2/4/6/7/9/1/3), centralização Home (5), Zoom (+/-), chamada de posições (Ctrl+1..9) e gravação (Shift+1..9ouCtrl+Shift+1..9). - Gravação e chamada de Presets de posição com velocidade ajustável e feedback no HUD.
- Controle CCU completo: Foco (Auto/Manual/One-Push), Exposição (Auto/Manual/Shutter/Iris), Ganho e Balanço de Branco (Auto/Indoor/Outdoor/One-Push/Trigger).
- 🎯 Enquadramento Inteligente por Região de Interesse (ROI 16:9):
- Ativação instantânea segurando a tecla
CTRLsobre o preview de vídeo. - Trava geométrica estrita na proporção
$16:9$ sem distorção anamórfica. - Conversão de magnificação via tabela óptica oficial da Sony VISCA (
0x0000a0x4000). - Sincronização cinemática com atraso calculado de zoom (
zoomDelayMs), garantindo que Pan e Tilt finalizem o movimento juntos com o Zoom óptico. - Botão dedicado
1x WIDEpara retorno imediato ao plano aberto.
- Ativação instantânea segurando a tecla
- 📺 Múltiplos Motores de Vídeo e Preview:
- Live Preview H.264 direto da câmera via WebSocket (
wfs.js). - Streaming RTSP decodificado como
MJPEGde baixíssima latência via processo filho do FFmpeg. - NDI Discovery e receptor nativo em Python CTypes (
ndi_server.py). - Snapshots com cacheamento duplo (Double Buffering) dos inputs do vMix.
- Live Preview H.264 direto da câmera via WebSocket (
- 🤖 Auto-Tracking Inteligente com IA (YOLOv8 + ByteTrack / MediaPipe) — Recurso Premium:
- Transforme qualquer câmera PTZ padrão em uma câmera de auto-tracking: Rastreia apresentadores, palestrantes e pastores em tempo real sem necessidade de câmeras caras com rastreamento nativo de fábrica ou licenças proprietárias adicionais.
-
Ingestão RTSP de Latência Zero (
ZeroLatencyRTSPReader): Thread dedicada que drena o fluxo RTSP e elimina$100%$ do acúmulo de buffer, processando o vídeo a$20\text{--}60\text{ FPS}$ com latência$< 10\text{ms}$ . - Cinemática Suave com Histerese (Schmitt Trigger) & Cooldown Anti-Hunting: Deadzone dupla inteligente com cooldown de frenagem pós-parada que elimina o efeito pêndulo e micro-oscilações quando o apresentador está parado falando.
-
Modos de Operação:
-
Pan-Only (Solo / Palco): Rastreia o apresentador horizontalmente com$0%$ de risco de desviar para o chão ou teto. -
Pan + Tilt Suave: Rastreamento bidirecional completo com micro-ajustes verticais lentos.
-
-
Safety Override Automático: Ao tocar no manche virtual, usar atalhos do teclado numérico ou chamar um preset, a IA pausa instantaneamente por
$3.5\text{s}$ para dar prioridade total ao operador humano.
- ⏱️ Grafo de Automação por Timeline: Conecte widgets visualmente com setas curvas (
react-xarrows), defina passos ordenados e tempos de espera (delays) para execução sequencial de rotinas. - 🖥️ Modo Popout (Multi-Monitores): Destaque qualquer widget individual (ex: a câmera PTZ) em uma janela separada e limpa do navegador via parâmetro
?popout=<id>. - 💾 Persistência Local e Exportação JSON: Salvamento contínuo em
localStoragee suporte a download e upload de layouts em arquivos.json.
O OmniMix adota uma arquitetura de microsserviços distribuídos, garantindo isolamento de processos, tolerância a falhas e alta performance em tempo real.
flowchart TD
subgraph Browser ["Navegador Web (Operador)"]
ReactApp["Frontend React 18 + Vite + TypeScript\n(Canvas Livre, ROI PTZ com CTRL, Timelines)"]
end
subgraph NodeMiddleware ["Middleware Node.js (Porta 3001)"]
ServerMjs["server.mjs (Express 5)"]
RouteVmix["routes/vmix.mjs (XML Cache & Snapshots)"]
RoutePtz["routes/ptz.mjs (REST Controller)"]
RouteHybrid["routes/hybrid.mjs (Parallel Trigger)"]
RouteAtem["routes/atem.mjs (Reverse Proxy)"]
RouteRtsp["routes/rtsp.mjs (FFmpeg MJPEG Stream)"]
RouteLogs["routes/logs.mjs (Audit Logger)"]
ViscaCore["backend/visca_controller.mjs (UDP Socket & ROI Math)"]
end
subgraph PythonBackend ["Backend Python (Porta 8000 / 8001 / 5055)"]
AtemServer["backend/atem_server.py\n(FastAPI/Starlette + PyATEMMax)"]
NdiServer["backend/ndi_server.py\n(Starlette + CTypes NDI Runtime)"]
TrackerServer["backend/auto_tracker.py (Porta 5055)\n(YOLOv8 + Zero-Latency RTSP Grabber)"]
end
subgraph Hardware ["Estúdio & Equipamentos Físicos"]
VmixHost["vMix Host Software\n(Porta HTTP 8088)"]
AtemSwitcher["Blackmagic ATEM Switcher\n(Porta UDP 9910)"]
PtzCamera["Câmera Robótica PTZ\n(Porta UDP VISCA 52381 / RTSP 554 / WS 8088)"]
end
ReactApp -->|HTTP / Media| ServerMjs
ReactApp -->|WebSocket H.264| PtzCamera
ReactApp -->|Direct Status/Start| TrackerServer
ServerMjs --> RouteVmix
ServerMjs --> RoutePtz
ServerMjs --> RouteHybrid
ServerMjs --> RouteAtem
ServerMjs --> RouteRtsp
ServerMjs --> RouteLogs
RoutePtz --> ViscaCore
RoutePtz -->|Proxy Control| TrackerServer
ViscaCore -->|UDP Datagrams| PtzCamera
TrackerServer -->|Direct UDP VISCA Packets| PtzCamera
PtzCamera -->|RTSP H.264 Feed| TrackerServer
RouteVmix -->|HTTP GET / XML Polling| VmixHost
RouteHybrid -->|HTTP GET Cut| VmixHost
RouteHybrid -->|HTTP POST Cut| AtemServer
RouteAtem -->|HTTP REST| AtemServer
AtemServer -->|UDP Control Packets| AtemSwitcher
RouteRtsp -->|RTSP Stream| PtzCamera
NdiServer -->|NDI Discovery| VmixHost
- Framework & Build: React 18 com compilação ultra-rápida via Vite.
- Manipulação de Canvas:
react-rnd(Drag, Drop, Resize com contenção de grid e limites de tela). - Conectores de Automação:
react-xarrowspara renderização vetorial de nós e setas entre widgets. - Ícones:
lucide-reactpara controles broadcast de alto contraste. - Resiliência:
ErrorBoundaryglobal em React com mecanismo de recuperação e botão de emergência para limpar cache corrompido.
Localizado em server.mjs e modularizado na pasta routes/:
routes/vmix.mjs: Mantém cache síncrono do XML de status do vMix a cada 2 segundos e orquestra a geração de snapshots em JPEG em buffer de disco temporário (vmix-snapshots/).routes/ptz.mjs: Expõe rotas REST para movimentação absoluta, relativa, controle de foco, íris, balanço de branco e o orquestrador de enquadramentoPOST /roi-frame.routes/atem.mjs: Proxy reverso que repassa requisições para o microsserviço Python ATEM.routes/hybrid.mjs: Executa comandos concorrentes viaPromise.allpara disparar transições simultâneas no vMix e no ATEM.routes/rtsp.mjs: Instancia processos filhos do FFmpeg sob demanda para converter fluxos RTSP H.264 brutos em pacotes MJPEG consumíveis por tags<img>HTML5 nativas.routes/logs.mjs: Registra eventos e auditoria de sessão no arquivosession_events.log.
Localizado em backend/atem_server.py:
- Utiliza Starlette / Uvicorn com suporte a ciclo de vida assíncrono (
lifespan). - Mantém um loop de reconexão persistente em segundo plano com a biblioteca
PyATEMMax. - Gerencia comandos UDP de baixa latência diretamente com a mesa Blackmagic (Corte Direto, Auto Transition Fade, Preview e leitura de Tally).
Localizado em backend/visca_controller.mjs e src/utils/ptzMath.ts:
- Gerenciador de sockets UDP nativos com empacotamento Sony VISCA over IP (cabeçalho de 8 bytes, sequência incremental e payload hexadecimal).
- Inquéritos assíncronos (
InquiryPanTiltPos,InquiryZoomPos) com Promises e resolução por timeouts protegidos. -
Tabela de Calibração Óptica Sony VISCA: Mapeamento não-linear de valores de zoom (
$1.0\times$ a$20.0\times$ mapeados de0x0000a0x4000). -
Sincronização Cinemática: Cálculo da razão de velocidade Pan/Tilt e injeção do atraso
zoomDelayMspara assegurar chegada simultânea de todos os eixos.
- WebSocket H.264 Live Preview: Conexão direta do navegador com a câmera na URL
ws://${cameraIp}:8088/live/av0utilizando a bibliotecawfs.js. - RTSP MJPEG Proxy: Conversão de baixo custo computacional através do FFmpeg para navegadores em redes isoladas.
- Double-Buffering Snapshots: Sistema de camada dupla (
layerAelayerB) noPreviewWidgetpara transição sem cintilação (flicker-free) de imagens capturadas do vMix. - NDI Runtime Streamer: Servidor NDI em Python (
ndi_server.py) que consome o runtime oficial da NewTek via CTypes.
vmix-controller/
├── backend/ # Microsserviços e bibliotecas de comunicação de baixo nível
│ ├── atem_server.py # Servidor Python FastAPI/Starlette para Blackmagic ATEM
│ ├── visca_controller.mjs # Driver UDP Sony VISCA over IP e orquestrador ROI
│ ├── ndi_server.py # Receptor e discovery de vídeo NDI em Python CTypes
│ ├── atem_client.py # Cliente auxiliar para testes e chamadas ATEM
│ ├── vmix_client.py # Cliente auxiliar para testes vMix
│ ├── omnimix.py # CLI unificada de controle
│ ├── requirements.txt # Dependências Python (PyATEMMax, uvicorn, starlette, etc.)
│ └── Dockerfile # Receita de container para o backend Python
├── docs/ # Base de conhecimento, sessões de refatoração e manuais
│ ├── session-2026-08-25-ptz-roi-framing.md # Relatório completo do sistema de ROI PTZ 16:9
│ ├── session-2026-05-06-refactor.md # Relatório da modularização de microsserviços
│ ├── README-troubleshooting-network.md # Guia de diagnóstico de sub-redes e IPs
│ ├── README_STARTUP.txt # Guia de inicialização rápida
│ └── RESUME_INSTRUCTIONS.md # Histórico de desenvolvimento
├── routes/ # Roteadores modulares Express do Node.js Middleware
│ ├── atem.mjs # Proxy REST para o backend ATEM
│ ├── hybrid.mjs # Rota de cortes sincronizados vMix + ATEM
│ ├── logs.mjs # Registro em session_events.log
│ ├── ptz.mjs # Endpoints de controle PTZ e ROI
│ ├── rtsp.mjs # Proxy e transcodificador FFmpeg RTSP -> MJPEG
│ └── vmix.mjs # Cache XML, snapshots e proxy reverso da API vMix
├── scripts/ # Utilitários de inicialização, rede e diagnóstico
│ ├── diagnostics/ # Scripts isolados de teste e laboratório médico
│ │ ├── diagnose.mjs # Diagnóstico de integridade geral
│ │ ├── diagnose_vmix.mjs # Teste de API do vMix
│ │ ├── probe_atem.py # Scanner de rede para switchers ATEM
│ │ ├── test_ptz_roi.mjs # Teste de enquadramento óptico PTZ
│ │ └── test_sony_zoom.mjs # Validação da curva não-linear VISCA
│ ├── network/ # Ajustes de rede e firewall no Windows
│ │ ├── add_camera_ip.bat # Adiciona rotas de IP para a câmera PTZ
│ │ ├── configure_network.bat # Configuração de sub-rede
│ │ └── dual_network.ps1 # Configuração de placas de rede duplas
│ └── startup/ # Inicializadores sem Docker
│ └── start_omnimix.bat # Inicializa Python, Node e Vite em janelas paralelas
├── src/ # Aplicação Frontend (React 18 + TypeScript)
│ ├── components/ # Componentes visuais dos widgets
│ │ ├── ButtonWidget.tsx # Botões de disparo, Tally e faixas de Overlay
│ │ ├── GroupWidget.tsx # Área de agrupamento de widgets
│ │ ├── LabelWidget.tsx # Rótulos de texto e títulos estilizados
│ │ ├── PreviewWidget.tsx # Monitor de vídeo (NDI / RTSP / Snapshots)
│ │ ├── PTZWidget.tsx # Widget completo de PTZ (Manche, CCU, ROI, Presets)
│ │ ├── PTZCalibrationModal.tsx # Modal de calibração fina de FOV da lente
│ │ ├── Sidebar.tsx # Barras laterais retráteis (Widgets, Timeline, Debug)
│ │ ├── TimelineWidget.tsx # Sequenciador de automação por passos
│ │ └── TitleListWidget.tsx # Seletor de linhas para títulos e Data Sources
│ ├── lib/ # Clientes e catálogo de comandos
│ │ ├── vmix.ts # Parser de XML e cliente HTTP do vMix
│ │ └── vmixCommands.ts # Catálogo completo de funções do vMix
│ ├── utils/ # Motores matemáticos e utilitários
│ │ ├── calibrationCapture.ts # Utilitários de captura para calibração
│ │ ├── ptzMath.ts # Algoritmos de ROI 16:9, curvas Sony e cálculo cinemático
│ │ └── styles.ts # Helpers de posicionamento CSS
│ ├── App.tsx # Canvas mestre, gerenciador de layout, atalhos e modais
│ ├── main.tsx # Ponto de entrada React
│ └── types.ts # Definições de tipos TypeScript
├── docker-compose.yml # Orquestrador dos contêineres Docker
├── Dockerfile # Receita de container para o Node/Frontend
├── package.json # Dependências do ecossistema Node.js
├── server.mjs # Servidor Express mestre (Node.js Middleware)
├── tsconfig.json # Configurações do compilador TypeScript
└── vite.config.ts # Configurações do Vite e proxies
- Docker Desktop instalado (Recomendado para ambientes de produção estáveis).
- OU Instalação Nativa:
- Node.js: Versão
20.xou superior. - Python: Versão
3.11.xou superior (compip). - FFmpeg: Instalado e adicionado ao
PATHdo sistema.
- Node.js: Versão
- Acesso à rede local onde o vMix, o ATEM e as câmeras PTZ estão conectados.
Crie ou edite o arquivo .env na raiz do projeto (vmix-controller/.env). Este arquivo é o ponto único de controle de endereços de rede do sistema:
# Endereço IP físico do Switcher Blackmagic ATEM na rede local
ATEM_IP=10.90.1.210
# Endereço do host vMix (porta padrão 8088)
# Se estiver no Docker Desktop para Windows, use host.docker.internal:8088
VMIX_IP=host.docker.internal:8088
# Endereço IP padrão da câmera robótica PTZ (Sony VISCA over IP)
CAMERA_IP=192.168.5.163
# Porta UDP padrão para o protocolo Sony VISCA over IP (padrão: 52381)
CAMERA_PORT=52381Important
Atenção com Sub-redes! Verifique se o computador host e o switcher ATEM estão na mesma sub-rede (ex: 10.90.1.x com máscara 255.255.255.0). Dispositivos Blackmagic utilizam pacotes UDP e não responderão se houver divergência de sub-rede.
- Clone o repositório e navegue até a pasta raiz:
git clone https://github.com/seu-usuario/vmix-controller.git cd vmix-controller - Inicie os contêineres:
docker compose up --build -d
- Acompanhe a inicialização dos logs:
docker compose logs -f
- Acesse a interface web no navegador:
- Painel OmniMix: http://localhost:5175
- Middleware API: http://localhost:3001/api
- Backend ATEM: http://localhost:8001/state
- Instale as dependências do Node.js:
npm install
- Instale as dependências do Python Backend:
cd backend pip install -r requirements.txt cd ..
- Dê dois cliques no script de inicialização automatizada:
O script abrirá 3 terminais paralelos (Backend ATEM na porta
scripts/startup/start_omnimix.bat8000, Middleware Node na porta3001e Frontend Vite na porta5174). - Abra o navegador em:
http://localhost:5174
A interface do OmniMix opera em dois modos distintos:
- Modo Operação (Padrão -
Done):- Cliques executam comandos imediatos no vMix, ATEM e câmeras PTZ.
- O movimento e redimensionamento dos widgets ficam bloqueados contra cliques acidentais.
- O cursor exibe ponteiro interativo e o Tally responde em tempo real.
- Modo Edição (
Edit):- Ativado ao clicar no botão
Editno topo esquerdo. - Permite arrastar os widgets para qualquer posição do Canvas.
- Permite redimensionar as bordas dos widgets livremente.
- Habilita a barra de ferramentas superior para alinhamento, distribuição, histórico e criação de widgets.
- Ativado ao clicar no botão
Ao selecionar múltiplos widgets (segurando a tecla Shift ou arrastando uma caixa de seleção):
|←(Align Left): Alinha todos os widgets selecionados pela borda esquerda do primeiro.↑(Align Top): Alinha todos os widgets pelo topo mais alto da seleção.↔(Same Width): Iguala a largura de todos os widgets selecionados à maior largura encontrada.↕(Same Height): Iguala a altura de todos os widgets selecionados à maior altura encontrada.|=|(Distribute Horizontally): Distribui o espaçamento horizontal de forma equidistante entre 3 ou mais widgets selecionados.|=|(Distribute Vertically): Distribui o espaçamento vertical de forma equidistante.🔍+/🔍−(Escalar): Aumenta (+10%) ou diminui (-10%) o tamanho dos widgets selecionados (atalhos de teclado:+ou]para aumentar,-ou[para diminuir).
| Widget | Ícone | Função Principal |
|---|---|---|
| Button | 🕹️ | Botão multifuncional para comandos de corte, transição, áudio, overlays e disparos de mídia. Suporta imagens de fundo, ícones e Tally em tempo real. |
| Preview | 📺 | Monitor de vídeo ao vivo compatível com NDI, RTSP e snapshots de buffer duplo do vMix. |
| PTZ Camera | 🎥 | Painel completo de controle de câmera robótica com Manche 360°, CCU, Presets e Enquadramento Inteligente por ROI. |
| Title List | 📋 | Grid de botões com rolagem rápida para seleção de índices em tabelas de Data Source ou títulos com múltiplas linhas do vMix. |
| Timeline | ⏱️ | Sequenciador visual de automação que dispara uma sequência encadeada de passos com botão NEXT ou PLAY. |
| Group Area | 🗂️ | Caixa delimitadora visual para organizar conjuntos de botões e widgets correlatos no Canvas. |
| Label | 📝 | Caixa de texto para identificação de blocos de corte, operadores e câmeras. |
Cada botão (ButtonWidget) possui inteligência integrada para ler o estado do vMix e do ATEM:
- Tally Visual:
- Fundo / Borda Vermelha (Program): O input vinculado está no ar ao vivo.
- Fundo / Borda Verde (Preview): O input vinculado está em espera na pré-visualização.
- Comportamento do Clique do Mouse:
- Clique com Botão Esquerdo (Left Click): Executa a ação principal (ex:
Cut,AtemCut,HybridCutou ativação de Overlay em Program). - Clique com Botão Direito (Right Click): Envia o input vinculado imediatamente para o Preview (em vMix e ATEM).
- Clique com Botão Esquerdo (Left Click): Executa a ação principal (ex:
- Faixa de Overlays Inferior (1, 2, 3, 4):
- Cada número representa uma camada de título/GC sobreposta.
- Clique Esquerdo no número: Alterna o Overlay diretamente no Program.
- Clique Direito no número: Alterna o Overlay no canal de Preview.
- Indicador Vermelho: Camada ativa no ar.
- Indicador Verde: Camada armada em Preview.
- Botão
PREVIntegrado:- Botão lateral opcional para forçar o envio direto do input para o Preview sem usar o botão direito do mouse.
O widget de câmera PTZ (PTZWidget) é uma das ferramentas mais avançadas do OmniMix:
+-------------------------------------------------------------------------+
| [PTZ] [IMG] [CFG] 🎥 CÂMERA 1 [192.168.5.163] [1x WIDE] |
+-------------------------------------------------------------------------+
| |
| ÁREA DE VÍDEO / LIVE PREVIEW H.264 |
| |
| (Segure CTRL e arraste o mouse para desenhar a caixa 16:9) |
| |
+-------------------------------------------------------------------------+
| [Manche 360°] | [Presets 1-8] | [Zoom +/-] | [Foco / Iris / Shutter / WB] |
+-------------------------------------------------------------------------+
-
Aba PTZ (Movimentação):
- Manche Analógico Virtual 360°: Clique e arraste o manche central para mover a câmera suavemente em qualquer ângulo.
-
Rampa de Freio Mecânico (
Brake): Permite ajustar a inércia e desaceleração progressiva do manche para paradas suaves sem solavancos. - D-Pad Digital: Botões direcionais (Cima, Baixo, Esquerda, Direita e Diagonais).
-
Banco de Presets (1 a 8): Clique simples para chamar uma posição salva; marque o botão
SAVEpara gravar a posição e o zoom atual no slot desejado.
-
Aba IMG (Controle de Câmera / CCU):
-
Foco: Alternância entre Auto Focus, Manual Focus, One-Push AF e ajustes de Foco Perto (
Near) e Longe (Far). -
Exposição & Íris: Modos Auto, Manual, Prioridade de Shutter e controle fino de abertura de Íris e Ganho (
Gain). -
Balanço de Branco (WB): Modos Auto, Indoor (3200K), Outdoor (5600K), One-Push WB e gatilho de calibração (
Trigger).
-
Foco: Alternância entre Auto Focus, Manual Focus, One-Push AF e ajustes de Foco Perto (
-
Aba CFG (Ajustes de Lente & Calibração):
- Ajuste do campo de visão horizontal em plano aberto (
HFOV Wide, padrão:$60.0^\circ$ ). - Definição do zoom óptico máximo da câmera (ex:
$20.0\times$ ). - Ajuste de ticks por grau (
Ticks/Deg, padrão:$14.4$ ). - Trims de ajuste fino percentual de Pan, Tilt e Zoom.
- Ajuste do campo de visão horizontal em plano aberto (
- Segure a tecla
CTRLno teclado. O cursor sobre o vídeo se transformará em uma mira (crosshair). - Clique e arraste sobre a região que deseja enquadrar (ex: o rosto de um apresentador ou um produto na mesa).
- A caixa será desenhada com proporção travada em 16:9.
- Solte o botão do mouse: A câmera calculará os ângulos de deslocamento em Pan e Tilt, consultará a curva de aproximação óptica da Sony VISCA e executará o movimento sincronizado na hora.
- Para voltar ao plano aberto geral, clique no botão azul
1x WIDEna barra superior.
O PTZWidget transforma o teclado numérico em uma mesa de manche ergonômica:
| Tecla / Atalho | Ação | Descrição |
|---|---|---|
8 / 2 / 4 / 6 |
Manche Ortogonal | Cima, Baixo, Esquerda, Direita com aceleração progressiva e desaceleração suave (brake). |
7 / 9 / 1 / 3 |
Manche Diagonal | Diagonais diretas (Up-Left, Up-Right, Down-Left, Down-Right) ou combinações (8+6, 8+4, 2+6, 2+4). |
Alt (segurado ou no meio do movimento) |
⚡ Super-Velocidade (Turbo) | Acelera o movimento (Pan/Tilt/Zoom) instantaneamente para a velocidade máxima da câmera (Max 24). Ao soltar o Alt, o movimento continua na velocidade marcada sem interrupção. |
5 |
Centralizar (Home) | Centraliza Pan e Tilt via comando nativo VISCA Home (81 01 06 04 FF), zera o manche e ilumina a mira central. |
+ (NumpadAdd) |
Zoom In | Aproximação contínua da imagem com rampa de velocidade (e Super-Velocidade com Alt). |
- (NumpadSubtract) |
Zoom Out | Afastamento contínuo da imagem com rampa de velocidade (e Super-Velocidade com Alt). |
Ctrl + [1..9] |
Chamar Posição | Chama a posição salva (Preset 1 a 9) com toast no HUD (📍 Chamando Posição X). |
Shift + [1..9] ou Ctrl + Shift + [1..9] |
Salvar Posição | Grava a posição e o zoom atual no slot 1 a 9 com confirmação no HUD (💾 Posição X Salva!). |
O OmniMix transforma qualquer câmera PTZ VISCA padrão (mesmo sem rastreamento de fábrica) em uma câmera de auto-tracking inteligente:
+-------------------------------------------------------------------------+
| [PTZ] [IMG] [CFG] 🎥 CÂMERA 1 [ONLINE] [ 🎯 TRACK: ON ] [1x WIDE] |
+-------------------------------------------------------------------------+
| |
| +-----------------------+ |
| | 🟢 APRESENTADOR (95%)| |
| | [ 👤 ] | |
| | [ || ] | |
| +-----------------------+ |
| ▲ |
| <--- [ Deadzone Estável 20% ] ---> |
| |
+-------------------------------------------------------------------------+
-
Como Ativar:
- Clique no botão verde
[ 🎯 AUTO-TRACK ]na barra superior do widget. - O OmniMix aciona o motor YOLOv8 no backend, conectando ao fluxo RTSP em tempo real.
- Clique no botão verde
-
Tecnologias Integradas:
- YOLOv8 Object Detection: Identifica a pessoa inteira continuamente, mesmo de costas, de lado, sentando ou caminhando rápido.
-
Leitor RTSP Zero-Latency (
ZeroLatencyRTSPReader): Thread dedicada que drena o buffer da câmera, entregando latência de processamento$< 10\text{ms}$ . -
Histerese (Schmitt Trigger) Anti-Hunting:
- Zona Externa ($20%$): A câmera só começa a se mover quando você dá passos reais para os lados.
-
Zona Interna ($8%$): Quando a câmera te centraliza, ela para suavemente e entra em um cooldown de
$350\text{ms}$ para absorver a inércia física do motor, eliminando 100% de oscilações ou tremedeiras.
-
Modos de Operação (Aba CFG):
-
↔️ Pan Horizontal (Seguro / Solo): Padrão recomendado para transmissões de pastores e palestrantes solos. Segue o apresentador por todo o palco mantendo o tilt travado, sem risco de olhar para o teto ou chão. -
🔄 Pan + Tilt Suave: Rastreamento bidirecional completo com velocidades verticais lentas.
-
-
Safety Override Automático:
- Qualquer intervenção manual (tocar no manche, usar setas, teclado numérico ou chamar um preset) pausa o rastreamento por
$3.5\text{s}$ com aviso sonoro/visual, garantindo prioridade absoluta ao operador humano.
- Qualquer intervenção manual (tocar no manche, usar setas, teclado numérico ou chamar um preset) pausa o rastreamento por
O OmniMix permite criar rotinas operacionais encadeadas (ex: "Entrar Vinheta -> Esperar 3s -> Abrir Microfones -> Cortar para Câmera 1"):
- Adicione um widget de Timeline ao Canvas.
- No Modo Edição, ative o botão
Nodes ONna barra superior. - Pequenos conectores circulares (nós) aparecerão nas laterais dos botões.
- Clique no nó de saída de um widget e arraste até o nó de entrada do próximo widget para criar uma seta de conexão (
react-xarrows). - Abra a Sidebar Esquerda e clique na aba
Timeline / Logic:- Os passos da sequência aparecerão numerados.
- É possível reordenar passos via Drag & Drop ou botões de seta para cima/baixo.
- Configure o tempo de espera (delay em ms) para cada nó.
- Na operação ao vivo:
- Clique no botão
NEXTno widget da Timeline para avançar passo a passo. - Ou clique em
PLAYna Sidebar para rodar a sequência inteira automaticamente com os intervalos programados.
- Clique no botão
Se você utiliza múltiplos monitores na régua técnica de transmissão, qualquer widget do OmniMix pode ser aberto em uma janela dedicada e limpa do navegador:
-
Como usar: Adicione o parâmetro
?popout=<ID_DO_WIDGET>na URL do navegador. -
Exemplo:
http://localhost:5175/?popout=ptz-cam1 - A janela renderizará apenas o widget solicitado ocupando
$100%$ da tela, sem barras de ferramentas ou menus, ideal para monitores auxiliares de retorno de câmera ou mini-painéis de corte.
- Desfazer: Pressione
Ctrl + Zno teclado. - Refazer: Pressione
Ctrl + Shift + ZouCtrl + Y. - Excluir Widget: Selecione o widget e pressione a tecla
Delete. - Seleção Múltipla: Segure
Shifte clique nos widgets ou arraste uma caixa de seleção no fundo do Canvas. - Redimensionar Selecionados: Teclas
+/]para aumentar e-/[para diminuir o tamanho dos widgets em modo edição. - Controle PTZ Numpad:
8/2/4/6(Manche),7/9/1/3(Diagonais),5(Centro),+ / -(Zoom In/Out),Ctrl + 1..9(Chamar Posição),Shift + 1..9ouCtrl + Shift + 1..9(Salvar Posição). - Salvar Backup: No Modo Edição, clique em
Savepara baixar o arquivoomnimix_layout.json. - Restaurar Backup: Clique em
Loade selecione um arquivo.jsonsalvo anteriormente para restaurar a mesa inteira imediatamente.
| Categoria | Comando | Parâmetros | Descrição |
|---|---|---|---|
| Transição | Cut |
- | Corte seco no vMix para o input ativo |
| Transição | Fade |
Duration (ms) |
Transição suave de Fade |
| Transição | Merge |
Duration (ms) |
Transição animada de Merge |
| Transição | Wipe / CubeZoom / Fly |
Duration (ms) |
Efeitos de transição vMix |
| ATEM | AtemCut |
Input (1-8) |
Corte direto no switcher ATEM físico |
| ATEM | AtemPreview |
Input (1-8) |
Envia entrada para o Preview do ATEM |
| ATEM | AtemAuto |
- | Executa transição Auto (Fade) na mesa ATEM |
| ATEM | AtemCutTransition |
- | Inverte PGM e PVW na mesa ATEM |
| Híbrido | HybridCut |
Input (vMix), AtemInput (ATEM) |
Corte simultâneo no vMix e no ATEM em paralelo |
| Overlays | OverlayInput1 a OverlayInput4 |
Input |
Liga/Desliga camada de Overlay no vMix |
| Overlays | OverlayInputAllOff |
- | Remove todas as camadas de overlay ativas |
| Mídia | videoPlay / videoPause / Restart |
Input |
Controle de reprodução de videoclipes |
| Áudio | AudioOn / AudioOff / AudioAuto |
Input |
Mute / Unmute de canais de áudio |
| Áudio | SetVolume |
Input, Value (0-100) |
Ajuste de volume do canal |
| Títulos | SetText |
Input, SelectedName, Value |
Atualiza o texto de um campo de GC |
| Data Source | DataSourceSelectRow / SelectIndex |
Input, Value |
Seleciona linha em tabela do vMix |
| Output | StartStreaming / StopStreaming |
- | Liga/Desliga a transmissão do vMix |
| Output | StartRecording / StopRecording |
- | Liga/Desliga a gravação local no vMix |
- Causa mais comum: Endereço IP do ATEM incorreto ou em sub-rede divergente no arquivo
.env. - Como resolver:
- Descubra a faixa de IP do seu computador executando
ipconfigno terminal. - Verifique se o IP do ATEM configurado no
.env(ex:10.90.1.210) possui os mesmos três primeiros octetos da placa de rede. - Lembre-se: Hardwares Blackmagic ATEM frequentemente não respondem ao comando ping (ICMP), mas respondem na porta UDP 9910.
- Rode o script de teste de rede:
python scripts/diagnostics/probe_atem.py
- Descubra a faixa de IP do seu computador executando
- Como resolver:
- Certifique-se de que o IP da câmera no
.env(CAMERA_IP) está correto. - Confirme se a porta VISCA está configurada como
52381(padrão Sony over IP). - Execute o script de teste de movimentação isolado:
node scripts/diagnostics/test_ptz_roi.mjs
- Certifique-se de que o IP da câmera no
- Se um widget corrompido causar falha de renderização no React, o
ErrorBoundaryexibirá uma tela de alerta com o botão vermelhoRESETAR APP (LIMPAR CACHE), permitindo recuperar o painel sem reinstalações.
- Os roteadores
routes/atem.mjseroutes/vmix.mjspossuem silenciamento inteligente de erros quando os equipamentos estiverem desligados, garantindo que o terminal permaneça legível para comandos e depurações.
Ao contribuir com o código do OmniMix ou desenvolver novos recursos:
- Configuração Unificada de Ambiente:
- NUNCA insira endereços IP fixos no código fonte (
server.mjs,visca_controller.mjs,atem_server.py, etc.). Toda e qualquer configuração deve ser lida do arquivo.envraiz.
- NUNCA insira endereços IP fixos no código fonte (
- Respeito às Fronteiras dos Microsserviços:
- O frontend React deve comunicar-se exclusivamente com a porta
3001(Node.js Middleware) ou rotas relativas/api. - O Node.js atua como roteador/proxy e despacha comandos de hardware para o backend Python (porta
8000) e para a câmera VISCA (porta52381).
- O frontend React deve comunicar-se exclusivamente com a porta
- Módulo PTZ e Matemática de Lentes:
- Todos os algoritmos geométricos, tabelas ópticas Sony e cálculos de interpolação devem residir estritamente em
src/utils/ptzMath.ts. - Mantenha a sincronia cinemática através do parâmetro
zoomDelayMspara preservar o comportamento profissional de enquadramento.
- Todos os algoritmos geométricos, tabelas ópticas Sony e cálculos de interpolação devem residir estritamente em
- Área Segura para Testes:
- Utilize a pasta
experiments/para protótipos escripts/diagnostics/para ferramentas de teste isolado. Não altere a pastalegacy/.
- Utilize a pasta
Este projeto é desenvolvido para uso em produção audiovisual e controle de transmissões ao vivo. Distribuído sob licença proprietária / interna da equipe de desenvolvimento do estúdio.