Alternativa open source (MIT) a Spacedesk: convierte uno o varios dispositivos Android en monitores secundarios inalámbricos (espejo o extendido) de una PC Windows, en la misma red Wi-Fi/LAN.
Estado: estable ✅ — versión v0.2.1, probada en PC (Windows 11) y Android. Descarga el MSI y el APK en Releases.
- 🔒 Emparejamiento por PIN (6 dígitos, rotación tras cada vínculo).
- 📡 Autodetección en la red local vía mDNS/DNS-SD (sin teclear IPs) + conexión manual por IP.
- 🖥️➡️📱 Modo extendido: usa el teléfono como un monitor nuevo (no solo espejo) mediante un driver de pantalla virtual open-source, instalable con un botón desde la app.
- 👥 Multi-dispositivo: cada teléfono puede ver un monitor distinto a la vez (físico o virtual).
- 🖱️ Cursor visible en los monitores virtuales (compuesto en el frame) para arrastrar ventanas.
- ⚡ Baja latencia: reescalado + descarte de cuadros atrasados (decodifica solo el más reciente).
- 🌙 Tema oscuro completo en ambas aplicaciones.
- 📦 Salidas: MSI (Windows) y APK (Android), generadas por CI con versión en el nombre.
- 🔖 Gestión de versiones automática (SemVer) desde una fuente única (
version.json).
Modo extendido: requiere instalar un driver de pantalla virtual (un clic en "+ Monitor virtual" dentro de la app). Guía:
docs/MODO-EXTENDIDO.md. También se incluye el scaffold de un driver IDD propio enserver-windows/driver/como alternativa futura.
SERVIDOR (Windows, .NET 8 / WPF) CLIENTE (Android, Kotlin)
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ ScreenCapturer (GDI → JPEG) │ │ DiscoveryManager (NsdManager) │
│ MdnsResponder (DNS-SD) │ mDNS ◄───┤ descubre _openwdisplay._tcp │
│ PinManager (PIN 6 díg.) │ │ PairingDialog (PIN) │
│ StreamServer (TCP) │ TCP ───►│ VideoClient (handshake + RX) │
│ ├─ handshake PIN │ frames │ DisplayActivity (SurfaceView) │
│ ├─ frames (MJPEG) │ ◄────► │ LowLatencyVideoPlayer (H.264*) │
│ └─ input (SendInput) │ input │ onTouchEvent → coords 0..1 │
└───────────────────────────────┘ └───────────────────────────────┘
* ruta H.264/MediaCodec lista para sustituir a MJPEG (ver guía, Fase 3)
Protocolo binario compartido: [1 byte Type][4 bytes BE Length][Payload]. Definición en
server-windows/src/Protocol/WireProtocol.cs
y su paridad en client-android/.../WireProtocol.kt.
.
├── server-windows/ # Servidor .NET 8 (WPF, tema oscuro) + MSI (WiX) + driver IDD (scaffold C++)
├── client-android/ # Cliente Kotlin (tema oscuro Material 3) + Gradle
├── execution/ # bump_version.py (gestión de versiones determinística)
├── directives/ # Directiva del marco de orquestación (CLAUDE.md)
├── memory/ # Memoria persistente PARA del agente
├── .github/workflows/ # CI/CD: build.yml (MSI+APK), release.yml (GitHub Release)
├── version.json # Fuente única de versión
└── CHANGELOG.md
Requisitos: .NET 8 SDK.
# 1) Sincroniza la versión a los archivos de build
python execution/bump_version.py sync
# 2) Publica self-contained (no requiere runtime instalado en el destino)
cd server-windows
dotnet publish src/OpenWirelessDisplay.Server.csproj -c Release -r win-x64 --self-contained true -o installer/publish
# 3) Construye el MSI (WiX 5)
dotnet tool install --global wix --version 5.0.2
cd installer
wix build Package.wxs -arch x64 -o OpenWirelessDisplay-Server-<version>.msiRequisitos: JDK 17 + Android SDK (platform-34, build-tools 34).
cd client-android
gradle wrapper # genera ./gradlew la primera vez
./gradlew assembleDebug # APK en app/build/outputs/apk/debug/app-debug.apkO simplemente haz push a GitHub: el workflow build.yml
genera el MSI y el APK como artefactos. Un tag vX.Y.Z dispara
release.yml, que publica una Release con ambos binarios.
- Instala el MSI en Windows y abre OpenWirelessDisplay Server.
- (Opcional, para extender) Pulsa "+ Monitor virtual" para instalar el driver, ponlo en "Extender" (Config. de pantalla) y pulsa "↻ Actualizar lista".
- Elige el monitor a compartir y pulsa Iniciar. Verás un PIN y la IP.
- Abre la app OpenWirelessDisplay en Android (misma Wi-Fi). El PC aparece solo (o usa "Conectar por IP manualmente"). Escribe el PIN y empareja.
- Si el servidor ofrece varios monitores, elige cuál ver en el diálogo de la app. Los toques controlan el cursor sobre ese monitor; cada dispositivo puede ver un monitor distinto.
Permite la app a través del Firewall de Windows la primera vez (el MSI ya añade las reglas para TCP 7345 y mDNS UDP 5353).
version.json es la fuente única. execution/bump_version.py propaga a .NET (MSI) y
Android (versionName/versionCode) y actualiza el CHANGELOG.
python execution/bump_version.py patch # 0.1.0 → 0.1.1
python execution/bump_version.py minor # 0.1.0 → 0.2.0
python execution/bump_version.py major # 0.1.0 → 1.0.0
python execution/bump_version.py set 1.2.3Para usar el teléfono como un monitor extendido (arrastrar ventanas) hace falta un driver de pantalla virtual. Guía paso a paso: docs/MODO-EXTENDIDO.md (instalar un driver IDD open-source firmado y seleccionarlo en "Monitor a compartir").
- MVP: PIN + mDNS + espejo (MJPEG) + input + MSI + APK (CI).
- Selector de monitor a compartir + mapeo de input multi-monitor.
- Modo extendido vía driver virtual open-source (botón integrado, ver
docs/MODO-EXTENDIDO.md). - Multi-dispositivo: cada cliente ve un monitor distinto (protocolo v2).
- Cursor visible en monitores virtuales.
- Baja latencia (reescalado + descarte de cuadros).
- Driver IDD nativo propio (
server-windows/driver/, alternativa al externo). - Codificación H.264/H.265 por hardware (NVENC/AMF/QuickSync) + MediaCodec.
- Transporte WebRTC/UDP de baja latencia (hoy TCP).
- Audio inalámbrico.
MIT.