🎬 Teleprompter Stealth Mode
Aplicação Electron desktop para teleprompter invisível e discreto para uso em reuniões online, gravações de vídeo com OBS Studio e apresentações ao vivo.
📋 Sobre o Projeto
Solução desktop para profissionais que precisam de um teleprompter discreto para apresentações, gravações e reuniões online. O aplicativo exibe conteúdo em formato Markdown de forma transparente e configurável, permitindo leitura discreta sem aparecer visivelmente nas capturas de tela.
Tecnologias utilizadas: Desenvolvido com JavaScript/Node.js 16+ e Electron 28+, utilizando HTML5/CSS3 para a interface, marked para renderização de Markdown e electron-store para persistência de configurações.
Funcionalidades
- ✅ Janela Transparente e Sempre no Topo - Interface discreta que permanece acima de outras janelas
- ✅ Editor de Markdown Integrado - Edite seu conteúdo diretamente no aplicativo
- ✅ Suporte Completo a Markdown - Renderização rica com títulos, listas, código, etc.
- ✅ Auto-scroll Configurável - Rolagem automática com velocidade ajustável (0-100 px/s)
- ✅ Controles Avançados de Aparência - Transparência, cores, tamanhos e alinhamentos personalizáveis
- ✅ Carregamento de Arquivos - Suporte para arquivos
.mdou.txt - ✅ Persistência de Configurações - Todas as preferências são salvas automaticamente
- ✅ Múltiplas Telas - Suporte para configurações multi-monitor
- ✅ Minimização Inteligente - Minimize para bandeja do sistema ou bolinha "T"
- ✅ Proteção de Conteúdo - Tenta proteger o conteúdo contra capturas de tela (Windows/Linux)
- ✅ Atalhos Globais - Controle o aplicativo mesmo quando não está em foco (
Ctrl + T)
Formatos de Arquivo Suportados
| Formato | Descrição | Extensão |
|---|---|---|
| Markdown | Arquivo Markdown padrão | .md |
| Texto | Arquivo de texto simples | .txt |
Nota: O conteúdo Markdown é renderizado em tempo real usando a biblioteca
marked.
🛠️ Tecnologias
Core
- Electron 28.0+ - Framework para aplicações desktop multiplataforma
- Node.js 16+ - Runtime JavaScript
- marked 11.1.1 - Parser e compilador Markdown
- electron-store 8.1.0 - Armazenamento persistente de configurações
Build e Distribuição
- electron-builder 24.9.1 - Empacotamento e distribuição
- Windows Portable - Executável
.exeportável (não requer instalação)
Frontend
| Tecnologia | Versão | Descrição |
|---|---|---|
| HTML5 | - | Estrutura da interface |
| CSS3 | - | Estilos e animações |
| JavaScript ES6+ | - | Lógica da interface |
📐 Arquitetura
O projeto segue uma arquitetura baseada em processos do Electron, separando claramente as responsabilidades entre o processo principal (Main Process) e o processo de renderização (Renderer Process).
🏗️ Arquitetura Geral do Sistema
%%{title: "Arquitetura Geral do Sistema Teleprompter Stealth Mode"}%%
graph TB
subgraph "Main Process (Node.js)"
A[main.js] --> B[BrowserWindow]
A --> C[IPC Handlers]
A --> D[Global Shortcuts]
A --> E[Tray Icon]
A --> F[TBubble Window]
A --> G[electron-store]
end
subgraph "Renderer Process (Browser)"
H[index.html] --> I[renderer.js]
I --> J[DOM Manipulation]
I --> K[Marked Parser]
I --> L[LocalStorage]
I --> M[Auto-scroll Engine]
end
subgraph "Storage"
N[electron-store]
O[LocalStorage]
end
subgraph "UI Components"
P[Teleprompter Container]
Q[Control Panel]
R[Markdown Editor]
S[Stealth Controls]
end
B --> H
C -.IPC.-> I
I -.IPC.-> C
I --> K
K --> P
I --> M
M --> P
I --> L
A --> N
H --> P
H --> Q
H --> R
H --> S
D --> B
E --> B
F --> B
style A fill:#47848F,stroke:#2e5261,color:#fff
style I fill:#47848F,stroke:#2e5261,color:#fff
style K fill:#1e88e5,stroke:#1565c0,color:#fff
style N fill:#4caf50,stroke:#388e3c,color:#fff
style O fill:#4caf50,stroke:#388e3c,color:#fff
🔄 Fluxo de Comunicação
%%{title: "Fluxo de Comunicação de Carregamento e Renderização"}%%
sequenceDiagram
participant U as Usuário
participant R as Renderer Process
participant M as Main Process
participant W as BrowserWindow
participant S as electron-store
participant LS as LocalStorage
participant MD as marked
Note over U,MD: Fluxo de Carregamento e Renderização
U->>R: Carrega arquivo .md/.txt
R->>R: Lê arquivo via fs.readFile()
R->>R: Atualiza textarea
R->>MD: Parse markdown
MD-->>R: HTML renderizado
R->>R: Atualiza teleprompterContent
R->>LS: Salva conteúdo (debounce 500ms)
Note over U,MD: Fluxo de Configurações
U->>R: Ajusta transparência
R->>M: IPC: set-opacity
M->>W: setOpacity()
M->>S: Salva configuração
S-->>M: Confirmado
U->>R: Ajusta sempre no topo
R->>M: IPC: toggle-always-on-top
M->>W: setAlwaysOnTop()
M->>S: Salva configuração
U->>R: Seleciona tela
R->>M: IPC: get-screens
M-->>R: Lista de telas
R->>M: IPC: move-to-screen
M->>W: setPosition()
Note over U,MD: Fluxo de Auto-scroll
U->>R: Define velocidade scroll
R->>R: startAutoScroll()
R->>R: Intervalo 100ms
R->>R: Atualiza scrollTop
R->>LS: Salva velocidade
Arquitetura da Interface
%%{title: "Arquitetura da Interface de Usuário"}%%
graph TD
A[index.html] --> B[Container Principal]
B --> C[Teleprompter Container]
B --> D[Stealth Controls Header]
B --> E[Control Panel Dropdown]
B --> F[Resize Handle]
C --> G[Teleprompter Content]
G --> H[Markdown Renderizado]
D --> I[Config Button]
D --> J[Minimize Button]
D --> K[Close Button]
E --> L[Transparency Slider]
E --> M[Font Size Slider]
E --> N[Scroll Speed Slider]
E --> O[Scroll Position Slider]
E --> P[Text Alignment Select]
E --> Q[Color Pickers]
E --> R[File Input]
E --> S[Markdown Editor]
E --> T[Update Button]
E --> U[Screen Select]
style A fill:#1e293b,stroke:#475569,color:#f8fafc
style C fill:#47848F,stroke:#2e5261,color:#fff
style E fill:#2d3748,stroke:#4a5568,color:#fff
style H fill:#1e88e5,stroke:#1565c0,color:#fff
🚀 Como Executar
Pré-requisitos
- Node.js 16+ (para execução e build)
- npm (incluído com Node.js)
- Windows 10/11, macOS 10.13+ ou Linux (Ubuntu 18.04+ ou equivalente)
💻 Executando Localmente
Instalação
# Clone ou baixe o repositório
git clone <url-do-repositorio>
cd teleprompter_stealth_mode
# Instale as dependências
npm install
Modo Desenvolvimento (com DevTools)
npm run dev
O aplicativo será executado com DevTools aberto para debug.
Modo Produção
npm start
O aplicativo será executado sem DevTools.
🔨 Build para Produção
Windows (Portable - Recomendado)
npm run build:portable
Gera um arquivo .exe portável em dist/ que não requer instalação:
Teleprompter Stealth-1.0.0-portable.exe
Windows (Instalador)
npm run build:win
Build Genérico (Multi-plataforma)
npm run build
Os arquivos compilados estarão no diretório dist/.
Limpar Arquivos de Build
npm run clean
📖 Como Usar
Primeiros Passos
-
Inicie o aplicativo:
npm start -
Abra o painel de configurações:
- Clique no botão ⚙ (engrenagem) no canto superior direito
- Ou pressione
ESCquando o painel estiver aberto para fechar
-
Carregue ou crie conteúdo:
- Opção 1: Clique em "Carregar Arquivo Markdown" e selecione um arquivo
.mdou.txt - Opção 2: Digite ou cole o conteúdo Markdown diretamente no editor
- Opção 1: Clique em "Carregar Arquivo Markdown" e selecione um arquivo
-
Atualize o teleprompter:
- Clique em "Atualizar Teleprompter"
- Ou pressione
Ctrl + Enterquando o editor estiver em foco
Controles Disponíveis
Ajustando a Transparência
- Abra o painel de configurações (botão ⚙)
- Use o slider "Transparência" para ajustar a opacidade:
- 100% = Totalmente opaco (mais visível para você)
- 30-50% = Recomendado para gravações (visível para você, menos visível para câmeras)
- 10% = Muito transparente (use com cuidado)
Configurando Auto-scroll
- No painel de configurações, ajuste o slider "Velocidade de Rolagem"
- O valor pode ser de 0 (manual) a 100 pixels por segundo
- Use a barra de espaço (
ESPAÇO) para pausar/retomar durante a apresentação
Personalizando Aparência
- Tamanho da Fonte: Ajustável de 10px a 72px (padrão: 32px)
- Cor do Texto: Seletor de cores personalizado (padrão: branco)
- Cor de Fundo: Seletor de cores com opacidade ajustável 0-100% (padrão: preto 0%)
- Alinhamento: Esquerda, Centro, Direita ou Justificado (padrão: Centro)
Usando com Múltiplas Telas
- Abra o painel de configurações
- No menu "Tela", selecione a tela desejada
- A janela será movida automaticamente para o centro da tela selecionada
Minimizando e Restaurando
- Minimizar: Clique no botão − (menos) ou use
Ctrl + T - Restaurar: Clique no ícone na bandeja do sistema ou use
Ctrl + Tnovamente - Bolinha "T": Aparece no canto inferior direito quando minimizado (apenas indicador visual)
⌨️ Atalhos de Teclado
Atalhos Globais (funcionam mesmo quando a janela não está em foco)
| Atalho | Ação |
|---|---|
Ctrl + T |
Mostrar/Ocultar janela (minimizar/restaurar) |
Atalhos Locais (quando a janela está em foco)
| Atalho | Ação |
|---|---|
ESC |
Mostrar/Ocultar painel de configurações |
ESPAÇO |
Pausar/Retomar auto-scroll (quando ativo) |
Ctrl + Enter |
Atualizar teleprompter (quando editor está em foco) |
Ctrl + Q |
Fechar aplicativo |
📁 Estrutura de Arquivos
teleprompter_stealth_mode/
├── main.js # Processo principal do Electron
│ # - Gerenciamento de janelas
│ # - IPC handlers
│ # - Atalhos globais
│ # - Bandeja do sistema
│ # - Bolinha "T" quando minimizado
│
├── renderer.js # Lógica da interface (renderer process)
│ # - Event listeners
│ # - Controles de UI
│ # - Processamento Markdown
│ # - Auto-scroll
│ # - Persistência localStorage
│
├── index.html # Estrutura HTML principal
│ # - Layout da interface
│ # - Painel de controles
│ # - Editor Markdown
│
├── styles.css # Estilos CSS
│ # - Interface stealth
│ # - Estilos Markdown
│ # - Painel dropdown
│ # - Botões e controles
│
├── t-bubble.html # HTML da bolinha "T" (indicador quando minimizado)
│
├── package.json # Configurações do projeto
│ # - Dependências
│ # - Scripts npm
│ # - Configuração electron-builder
│
├── scripts/
│ └── generate-icon.js # Script para gerar ícone da aplicação
│
├── build/ # Arquivos de build (não versionado)
│ └── icon.ico # Ícone do aplicativo
│
├── dist/ # Diretório de saída do build (não versionado)
│
├── .gitignore # Arquivos ignorados pelo Git
├── .npmrc # Configurações npm
├── .electron-builder.env # Variáveis de ambiente do electron-builder
│
└── README.md # Este arquivo
Descrição dos Arquivos Principais
main.js
Processo principal do Electron que gerencia:
- Criação e configuração da janela transparente (
BrowserWindow) - Comunicação IPC (Inter-Process Communication) entre main e renderer
- Atalhos globais de teclado (
Ctrl + TviaglobalShortcut) - Sistema de bandeja (tray icon) com menu de contexto
- Bolinha "T" quando minimizado (
tBubbleWindow) - Persistência de configurações usando
electron-store - Salvamento automático de posição e tamanho da janela
renderer.js
Processo renderer que controla a interface:
- Manipulação do DOM e eventos da interface
- Renderização de Markdown usando
marked - Controle de auto-scroll com intervalo configurável (100ms)
- Sincronização de sliders com scroll position
- Persistência no
localStorage(conteúdo, configurações de UI) - Carregamento de arquivos via Node.js
fs
index.html
Estrutura HTML com:
- Container principal do teleprompter
- Painel de controles (inicialmente oculto, dropdown animado)
- Editor de Markdown (textarea)
- Botões stealth no header (Config, Minimizar, Fechar)
- Handle de redimensionamento (canto inferior direito)
styles.css
Estilos CSS que criam:
- Interface transparente e discreta (dark theme)
- Painel dropdown animado (transições suaves)
- Botões stealth arredondados e semi-transparentes
- Estilos para Markdown renderizado (h1-h6, listas, blockquotes, code)
- Scrollbars personalizadas (finas e discretas)
🔧 Configuração e Persistência
Estrutura de Persistência
O aplicativo usa dois sistemas de armazenamento:
electron-store (Main Process)
Armazenado em: %APPDATA%/teleprompter-stealth-mode/config.json (Windows)
| Chave | Tipo | Descrição |
|---|---|---|
windowBounds |
Object | Posição e tamanho da janela {x, y, width, height} |
opacity |
Number | Opacidade da janela (0.1 - 1.0) |
alwaysOnTop |
Boolean | Janela sempre no topo |
selectedScreen |
Number | Índice da tela selecionada |
LocalStorage (Renderer Process)
Armazenado no navegador (processo renderer)
| Chave | Tipo | Descrição |
|---|---|---|
teleprompter_markdown |
String | Conteúdo Markdown do teleprompter |
teleprompter_transparency |
Number | Transparência (0.1 - 1.0) |
teleprompter_fontSize |
Number | Tamanho da fonte (10 - 72) |
teleprompter_textAlign |
String | Alinhamento (left, center, right, justify) |
teleprompter_textColor |
String | Cor do texto (hex) |
teleprompter_backgroundColor |
String | Cor de fundo (hex) |
teleprompter_backgroundOpacity |
Number | Opacidade do fundo (0 - 100) |
teleprompter_scrollSpeed |
Number | Velocidade de scroll (0 - 100 px/s) |
teleprompter_alwaysOnTop |
Boolean | Sempre no topo |
Auto-save
- Conteúdo Markdown: Salvo automaticamente após 500ms de inatividade (debounce)
- Configurações de UI: Salvas imediatamente ao alterar
- Posição/Tamanho da Janela: Salvas automaticamente após 500ms de inatividade (debounce)
- Configurações da Janela: Salvas imediatamente via IPC
⚠️ Sobre a "Invisibilidade"
Importante: A funcionalidade de "stealth" (invisibilidade) tem limitações que dependem do sistema operacional e das ferramentas de captura utilizadas.
O que o Aplicativo Faz para Proteger
- Janela Transparente - A janela é configurada como transparente (
transparent: true) - Sem Sombra -
hasShadow: falsepara reduzir visibilidade - Proteção de Conteúdo -
setContentProtection(true)no Windows/Linux (tenta bloquear capturas) - Não Aparece na Barra de Tarefas -
skipTaskbar: true - Sem Bordas -
frame: falsepara interface limpa
Limitações
- OBS Studio: Pode capturar janelas transparentes dependendo das configurações. Configure o OBS para capturar apenas janelas específicas ou use um segundo monitor.
- Ferramentas de Reunião (Zoom, Teams, etc.): Podem ou não capturar dependendo das configurações de compartilhamento de tela.
- Capturas de Tela do Sistema: Podem capturar o conteúdo independentemente da proteção.
Soluções Recomendadas
- Use um Segundo Monitor - Configure o teleprompter em uma tela separada que não seja compartilhada
- Configure OBS para Captura Seletiva - Selecione apenas as janelas específicas que deseja capturar
- Ajuste a Transparência - Use valores intermediários (30-50%) para reduzir visibilidade sem comprometer sua leitura
- Teste Antes de Gravar - Sempre teste a configuração antes de uma gravação importante
💡 Dicas de Uso
Para Gravações de Vídeo
- Configure Transparência: 30-50% para equilibrar visibilidade e discrição
- Use Auto-scroll: Pratique a velocidade antes de gravar
- Tamanho da Fonte: Ajuste para a distância entre você e a tela
- Posicione a Janela: Coloque em uma posição confortável para leitura
- Teste a Captura: Faça um teste de gravação antes da sessão real
Para Reuniões Online
- Multi-tela: Use uma tela separada se possível
- Transparência Baixa: Use 40-60% para garantir legibilidade
- Prepare o Conteúdo: Edite e revise o conteúdo antes da reunião
- Use Atalhos: Pratique os atalhos para controle rápido durante a reunião
Para Apresentações ao Vivo
- Velocidade de Scroll: Teste diferentes velocidades e encontre a ideal
- Formatação Markdown: Use cabeçalhos (
#,##) para criar pausas visuais - Conteúdo Estruturado: Organize o conteúdo em seções claras
- Prática: Pratique a leitura com o teleprompter antes da apresentação
Dicas de Formatação Markdown
# Título Principal
## Subtítulo
### Seção Menor
Parágrafo de texto normal.
- Item de lista 1
- Item de lista 2
- Subitem
**Texto em negrito** e *texto em itálico*.
> Citação ou nota importante.
🔮 Destaques Técnicos
Arquitetura Electron
Separação Main/Renderer Process
// main.js - Main Process
const { app, BrowserWindow, ipcMain } = require('electron');
function createWindow() {
mainWindow = new BrowserWindow({
transparent: true,
alwaysOnTop: true,
frame: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
}
// IPC Handler
ipcMain.on('set-opacity', (event, opacity) => {
mainWindow.setOpacity(opacity);
store.set('opacity', opacity);
});
// renderer.js - Renderer Process
const { ipcRenderer } = require('electron');
const { marked } = require('marked');
// IPC Communication
transparencySlider.addEventListener('input', (e) => {
const opacity = parseFloat(e.target.value);
ipcRenderer.send('set-opacity', opacity);
saveToLocalStorage('transparency', opacity);
});
Auto-scroll Engine
function startAutoScroll(speed) {
stopAutoScroll();
autoScrollInterval = setInterval(() => {
teleprompterContainer.scrollTop += speed / 10; // Atualiza a cada 100ms
// Sincronizar slider
const scrollPercent = (teleprompterContainer.scrollTop /
(teleprompterContainer.scrollHeight - teleprompterContainer.clientHeight)) * 100;
if (!isNaN(scrollPercent) && isFinite(scrollPercent)) {
scrollPosition.value = scrollPercent;
scrollValue.textContent = scrollPercent.toFixed(1) + '%';
}
// Parar se chegou ao fim
if (teleprompterContainer.scrollTop >=
teleprompterContainer.scrollHeight - teleprompterContainer.clientHeight) {
stopAutoScroll();
}
}, 100);
}
Persistência com Debounce
// Salvar markdown quando digitar no textarea
markdownInput.addEventListener('input', () => {
clearTimeout(markdownInput.saveTimeout);
markdownInput.saveTimeout = setTimeout(() => {
saveToLocalStorage('markdown', markdownInput.value);
}, 500); // Debounce de 500ms
});
📝 Notas Importantes
- A janela não aparece na barra de tarefas por padrão (configurado via
skipTaskbar: true) - A janela permanece sempre no topo por padrão, mas pode ser desabilitado nas configurações
- O painel de controles pode ser minimizado clicando fora dele ou pressionando
ESC - Todas as configurações são salvas automaticamente no
localStorageeelectron-store - O conteúdo do teleprompter é salvo automaticamente enquanto você digita (com debounce de 500ms)
- A posição e tamanho da janela são salvos automaticamente ao mover/redimensionar (debounce de 500ms)
🐛 Resolução de Problemas
A janela não aparece
- Verifique se há uma bolinha "T" no canto da tela (janela está minimizada)
- Pressione
Ctrl + Tpara restaurar - Verifique o ícone na bandeja do sistema
O auto-scroll não funciona
- Certifique-se de que a velocidade está acima de 0
- Pressione
ESPAÇOpara pausar/retomar - Verifique se há conteúdo suficiente para rolar
As configurações não estão sendo salvas
- Verifique as permissões de escrita no sistema
- Limpe o
localStoragese necessário (via DevTools:F12> Application > Local Storage) - Verifique se
electron-storetem acesso ao diretório de dados do usuário
O conteúdo Markdown não renderiza
- Verifique se o formato está correto
- Use o botão "Atualizar Teleprompter" após editar
- Verifique o console para erros (se DevTools estiver aberto)
📄 Licença
MIT License - Veja o arquivo de licença para mais detalhes.
🤝 Contribuições
Contribuições são bem-vindas! Sinta-se à vontade para abrir issues ou pull requests.
📧 Suporte
Para problemas, sugestões ou perguntas, abra uma issue no repositório do projeto.
Desenvolvido com ❤️ usando Electron