Skip to content

Commit

Permalink
refactorizado y modularizado de proceso principal y servidor DIAL
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosrg9 committed Mar 30, 2021
1 parent f42e51d commit 29357e5
Show file tree
Hide file tree
Showing 6 changed files with 3,987 additions and 134 deletions.
54 changes: 37 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# YouTube TV

Cliente de YouTube TV sencillo para escritorio basado en electron. Puede conectar un dispositivo compatible, como un teléfono o un equipo con Google Chrome y enviar los vídeos a la aplicación para visualizarlos.
Cliente de YouTube TV sencillo para escritorio basado en [electron](https://www.electronjs.org/). Puede conectar un dispositivo compatible, como un teléfono o un equipo con Google Chrome y enviar los vídeos a la aplicación para visualizarlos.

Implementa un servidor [DIAL](https://en.wikipedia.org/wiki/Discovery_and_Launch) (basado en SSDP) para permitir la conexión con dispositivos que usan este protocolo (limitado a YouTube).
Implementa un servidor [DIAL](https://en.wikipedia.org/wiki/Discovery_and_Launch) (basado en [SSDP](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol)) para permitir la conexión desde dispositivos que usan este mismo protocolo (limitado a YouTube en esta aplicación).

Usa el siguiente userAgent:
Usa el userAgent permitido por YouTube TV:
```
Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Large Screen Safari/534.24 GoogleTV/092754
```
Expand All @@ -18,40 +18,60 @@ El proyecto se puede descargar compilado y listo para su uso. Disponible para Li
[Todas las builds](https://github.com/marcosrg9/YouTubeTV/releases/latest)

## ⌨️ Atajos de teclado
- Pantalla completa (kiosk mode): Ctrl+F.
- Developer Tools: Ctrl+D.
- Pantalla completa (kiosk mode): <kbd>Ctrl</kbd>+<kbd>F</kbd>.
- Developer Tools: <kbd>Ctrl</kbd>+<kbd>D</kbd>.
- 🆕 Alternar visibilidad del cursor: <kbd>Ctrl</kbd>+<kbd>A</kbd>.


## 📺 Kiosk mode
Para alternar entre el modo ventana y kiosko se puede pulsar el atajo de teclado Ctrl+F.
> ⚠️ Activar el modo quiosco impedirá cambiar de ventanas.
El modo quiosco es, en resumidas cuentas, el modo a pantalla completa, pero es un modo "protegido", esto quiere decir que no se puede cambiar a otras ventanas, los gestos del ratón no funcionan, el atajo del tabulador tampoco funciona, se debe desactivar para cambiar entre ventanas.


Para alternar entre el modo ventana y quiosco se puede pulsar el atajo de teclado <kbd>Ctrl</kbd>+<kbd>F</kbd>.

También se puede forzar desde la instancia a BrowserWindow:
```Javascript
let win = new BrowserWindow({
this.window = new BrowserWindow({
width: 1230,
height: 720,
kiosk: true,
kiosk: false,
title: 'YouTube TV',
```
Sin embargo forzar este modo impide cambiar a otras ventanas de forma sencilla.
## 🔨 Ajustes
- (🆕 1.1.1) El servidor DIAL de esta aplicación se ejecuta bajo el puerto 2000 por defecto. Es poco probable, pero en el caso de que este puerto ya se encuentre en uso, es posible cambiarlo por otro que se encuentre disponible, solo hay que cambiar el contenido de la constante `dialPort` del proceso principal (`main.js`) por otro puerto.
- (🆕 1.1.1) El nombre que el servidor DIAL está emitiendo es `YouTube TV en el equipo de` concatenado con el nombre del usuario que está ejecutando YouTube TV. Si prefiere usar otro nombre, puede hacerlo desde la clase Dial (`servers/DIAL.js`), allí hay una constante llamada `username`, modifica el contenido y YouTube TV empezará a emitir el nombre deseado.
## ⛔ Problemas conocidos
- Al minimizar la ventana, la reproducción se detiene. Se puede reanudar si hay un dispositivo enlazado pulsando el botón de reproducir desde YouTube.
- En la primera ejecución de la aplicación, desde la pantalla de inicio de sesión, no se puede lanzar el modo kiosko.
- Parece que las restricciones de DRM impiden visualizar contenido en resolución HD y superior. Eventualmente, la opción HD se habilitará, pero el contenido en FHD y superior seguirá siendo restringido. Este problema no se puede corregir, al menos de momento.
- En la primera ejecución de la aplicación, desde la pantalla de inicio de sesión, no se puede lanzar el modo quiosco, tal vez haya algún eventListener por temas de accesibilidad y esté provocando conflicto.
- Parece que las restricciones de DRM impiden visualizar contenido en resolución HD y superior. Eventualmente, la opción HD se puede habilitar, pero el contenido en FHD y superior seguirá siendo restringido. Este problema no se puede corregir, al menos de momento.
- La ejecución del código fuente (con electron), hace que el cursor se oculte, este es el comportamiento esperado, sin embargo una vez empaquetado, el cursor ya no se oculta.
- Si se genera una cola y después otro usuario se conecta (echa al que ya estaba conectado), la cola se elimina. Este no es el comportamiento esperado, pero es algo inevitable, parece ser el funcionamiento normal de la plataforma YouTube TV.
## ⚙️ Tests
- ✔️ Windows 10 x64 - win32_x64/ia32.
- ✔️ Ubuntu 19.04 x64 (VM) - linux_x64.
- ✔️ macOS 11.1 Big Sur (MacBook Air) - darwin_x64 (comprobado por [Mateo Fortea](https://github.com/mfortea)).
- ✔️ Rasbian 10 Buster (Raspberry Pi4) - linux_armv7l.
- ✅ Windows 10 x64 - win32_x64/ia32.
- ✅ Ubuntu 19.04 x64 (VM) - linux_x64.
- ✅ macOS 11.2.3 Big Sur (MacBook Air) - darwin_x64 (Marcos).
- ✅ macOS 11.1 Big Sur (MacBook Air) - darwin_x64 ([Mateo Fortea](https://github.com/mfortea)).
- ✅ Rasbian 10 Buster (Raspberry Pi4) - linux_armv7l.
No comprobado en Windows, Linux y macOS para plataformas ARM, excepto linux para Raspberry (armv7l).
No comprobado en Windows y macOS para plataformas ARM, excepto linux ARM para Raspberry (armv7l).
<div align="center">
**Licencia Creative Commons**
![CC-BY-NC-SA](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.eu.svg)
![CC-BY-NC-SA](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.eu.svg)
</div>
112 changes: 12 additions & 100 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,104 +1,16 @@
const dial = require('peer-dial');
const http = require('http');
const express = require('express');
const os = require('os');
const { app, BrowserWindow, nativeImage, globalShortcut, Menu } = require('electron');
let appDial = express();
let server = http.createServer(appDial);

Menu.setApplicationMenu(false);

function createWindow() {
// Electron Params
let win = new BrowserWindow({
width: 1230,
height: 720,
title: 'YouTube TV',
kiosk: false,
backgroundColor: '#282828',
icon: nativeImage.createFromPath(`${__dirname}/build/icons/icon.png`),
setMenu: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true
}
})
win.setMenuBarVisibility(false);
win.loadURL('http://www.youtube.com/tv?', {
userAgent: 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Large Screen Safari/534.24 GoogleTV/092754'
});
// Modules
const { Renderer } = require('./renderer/main_renderer');
const { Dial } = require('./servers/DIAL');

globalShortcut.register('ctrl+f', () => {
if (win.kiosk == true) {
win.kiosk = false;
} else {
win.kiosk = true;
}
})
globalShortcut.register('ctrl+d', () => {
win.toggleDevTools();
})
// DIAL Params
let apps = {
"YouTube": {
name: "YouTube",
state: "stopped",
allowStop: true,
pid: null,
launch: function(a) {
win.loadURL(`http://www.youtube.com/tv?${a}`, {
userAgent: 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Large Screen Safari/534.24 GoogleTV/092754'
});
}
}
}
let dialServer = new dial.Server({
expressApp: appDial,
port: 3000,
prefix: '/dial',
corsAllowOrigins: '*',
friendlyName: `YouTube TV en ${os.hostname}`,
delegate: {
getApp: function(appName) {
let app = apps[appName];
return app;
},
launchApp: function(appName, launchData, callback) {
let app = apps[appName];
let pid = null;
if (app) {
app.pid = 'run';
app.state = 'starting';
app.launch(launchData);
app.state = 'running';
}
callback(app.pid);
},
stopApp: function(appName, pid, callback) {
let app = apps[appName];
if (app && app.pid == pid) {
app.pid = null;
app.state = 'stopped';
callback(true);
} else {
callback(false);
}
}
}
})
win.on('ready-to-show', () => {
win.webContents.insertCSS('html {cursor: none;}');
})

server.listen(3000, () => {
dialServer.start();
})
}
// Third party packages
const express = require('express');

app.on('ready', () => {
createWindow();
});
// Declarations
const appDial = express();
const renderer = new Renderer();
const dialPort = 2000;

app.on('window-all-closed', () => {
if (os.platform !== 'darwin') app.quit();
appDial.listen(dialPort, () => {
const dial = new Dial(appDial, renderer, dialPort);
dial.server.start();
})
Loading

0 comments on commit 29357e5

Please sign in to comment.